Skip to content

Commit fb9ab66

Browse files
committed
feat: support initial variable values for cbc
1 parent 4ba2ee2 commit fb9ab66

File tree

1 file changed

+40
-9
lines changed

1 file changed

+40
-9
lines changed

src/solvers/coin_cbc.rs

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,20 @@ pub fn coin_cbc(to_solve: UnsolvedProblem) -> CoinCbcProblem {
2323
variables,
2424
} = to_solve;
2525
let mut model = Model::default();
26+
let mut initial_solution = vec![];
2627
let columns: Vec<Col> = variables
27-
.into_iter()
28+
.iter_variables_with_def()
2829
.map(
29-
|VariableDefinition {
30-
min,
31-
max,
32-
is_integer,
33-
..
34-
}| {
30+
|(
31+
var,
32+
&VariableDefinition {
33+
min,
34+
max,
35+
initial,
36+
is_integer,
37+
..
38+
},
39+
)| {
3540
let col = model.add_col();
3641
// Variables are created with a default min of 0
3742
model.set_col_lower(col, min);
@@ -41,6 +46,9 @@ pub fn coin_cbc(to_solve: UnsolvedProblem) -> CoinCbcProblem {
4146
if is_integer {
4247
model.set_integer(col);
4348
}
49+
if let Some(val) = initial {
50+
initial_solution.push((var, val));
51+
};
4452
col
4553
},
4654
)
@@ -52,12 +60,16 @@ pub fn coin_cbc(to_solve: UnsolvedProblem) -> CoinCbcProblem {
5260
ObjectiveDirection::Maximisation => Sense::Maximize,
5361
ObjectiveDirection::Minimisation => Sense::Minimize,
5462
});
55-
CoinCbcProblem {
63+
let mut problem = CoinCbcProblem {
5664
model,
5765
columns,
5866
has_sos: false,
5967
mip_gap: None,
68+
};
69+
if initial_solution.len() > 0 {
70+
problem = problem.with_initial_solution(initial_solution);
6071
}
72+
problem
6173
}
6274

6375
/// A coin-cbc model
@@ -234,7 +246,7 @@ impl WithMipGap for CoinCbcProblem {
234246

235247
#[cfg(test)]
236248
mod tests {
237-
use crate::{variables, Solution, SolverModel, WithInitialSolution};
249+
use crate::{variable, variables, Solution, SolverModel, WithInitialSolution};
238250
use float_eq::assert_float_eq;
239251

240252
#[test]
@@ -261,4 +273,23 @@ mod tests {
261273
let sol = pb.solve().unwrap();
262274
assert_float_eq!(sol.value(v), limit, abs <= 1e-8);
263275
}
276+
277+
#[test]
278+
fn solve_problem_with_initial_variable_values() {
279+
let limit = 3.0;
280+
// Solve problem once
281+
variables! {
282+
vars:
283+
0.0 <= v <= limit;
284+
};
285+
let pb = vars.maximise(v).using(super::coin_cbc);
286+
let sol = pb.solve().unwrap();
287+
assert_float_eq!(sol.value(v), limit, abs <= 1e-8);
288+
// Recreate problem and solve with initial solution
289+
let mut vars = variables!();
290+
let v = vars.add(variable().min(0).max(limit).initial(2));
291+
let pb = vars.maximise(v).using(super::coin_cbc);
292+
let sol = pb.solve().unwrap();
293+
assert_float_eq!(sol.value(v), limit, abs <= 1e-8);
294+
}
264295
}

0 commit comments

Comments
 (0)