Skip to content

Commit 08e0898

Browse files
authored
feat: introduce problem.add_all to add many vars (#101)
* feat: introduce problem.add_all to add many vars * fix: do not hard-code Vecs for add_all * refactor: prefer more idiomatic std::iter::repeat
1 parent b98de56 commit 08e0898

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

src/variable.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use std::collections::Bound;
66
use std::fmt::{Debug, Display, Formatter};
77
use std::hash::Hash;
8+
use std::iter::{repeat, FromIterator};
89
use std::ops::{Div, Mul, Neg, Not, RangeBounds};
910

1011
use fnv::FnvHashMap as HashMap;
@@ -329,6 +330,37 @@ impl ProblemVariables {
329330
Variable::at(index)
330331
}
331332

333+
/// Adds many variables with the given definitions
334+
///
335+
/// ```
336+
/// use good_lp::*;
337+
/// // Solve a problem with 11 variables: x, y0, y1, ..., y9
338+
/// variables!{problem: 2 <= x <= 3;}
339+
/// let vars = vec![variable().min(0); 10];
340+
/// let y: Vec<Variable> = problem.add_all(vars);
341+
/// let objective: Expression = y.iter().sum(); // Minimise sum(y_i for i in [0; 9])
342+
/// let mut model = problem.minimise(objective).using(default_solver);
343+
/// // for all i, we must have y_i >= x
344+
/// for y_i in y.iter() {
345+
/// model = model.with(constraint!(y_i >= x));
346+
/// }
347+
/// let solution = model.solve().unwrap();
348+
/// # use float_eq::assert_float_eq;
349+
/// assert_float_eq!(solution.value(y[3]), 2., abs <= 1e-8);
350+
/// ```
351+
pub fn add_all<T, B: FromIterator<Variable>>(&mut self, var_defs: T) -> B
352+
where
353+
T: IntoIterator<Item = VariableDefinition>,
354+
{
355+
let index = self.variables.len();
356+
self.variables.extend(var_defs);
357+
self.initial_count += self.variables[index..]
358+
.iter()
359+
.filter(|v| v.initial.is_some())
360+
.count();
361+
(index..self.variables.len()).map(Variable::at).collect()
362+
}
363+
332364
/// Adds a list of variables with the given definition
333365
///
334366
/// ```
@@ -347,7 +379,7 @@ impl ProblemVariables {
347379
/// assert_float_eq!(solution.value(y[3]), 2., abs <= 1e-8);
348380
/// ```
349381
pub fn add_vector(&mut self, var_def: VariableDefinition, len: usize) -> Vec<Variable> {
350-
(0..len).map(|_i| self.add(var_def.clone())).collect()
382+
self.add_all(repeat(var_def).take(len))
351383
}
352384

353385
/// Creates an optimization problem with the given objective. Don't solve it immediately.

0 commit comments

Comments
 (0)