Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ This directory contains examples of how to use the `russcip` library.
2. [Knapsack solver](knapsack.rs): A simple integer programming model for the knapsack problem.
3. [Cutting stock](cutting_stock.rs): An example price-and-branch algorithm for the cutting stock problem.
4. [Traveling salesman](tsp.rs): An example of how to solve the traveling salesman problem using a branch-and-cut algorithm using a custom constraint handler.
5. [Random rounding](random_rounding.rs): An example demonstrating how to include a primal heuristic that does random rounding to the current LP solution.
5. [Random rounding](random_rounding.rs): An example demonstrating how to include a primal heuristic that does random rounding to the current LP solution.
6. [Most infeasible branching](most_infeasible_branching.rs): An example showing how to implement a custom branching rule that selects variables based on their fractionality.
59 changes: 59 additions & 0 deletions examples/most_infeasible_branching.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use russcip::prelude::*;
use russcip::ParamSetting;
use russcip::Solving;

/// A branching rule that implements the most infeasible branching strategy.
/// It selects the variable with the highest fractionality (closest to 0.5) to branch on.
struct MostInfeasibleBranching;

impl BranchRule for MostInfeasibleBranching {
fn execute(
&mut self,
model: Model<Solving>,
_branchrule: SCIPBranchRule,
candidates: Vec<BranchingCandidate>,
) -> BranchingResult {
// Find the candidate with the highest fractionality
let mut best_candidate = candidates.first().unwrap().clone();
let mut best_fractionality = (best_candidate.frac - 0.5).abs();

for candidate in candidates {
let fractionality = (candidate.frac - 0.5).abs();
if fractionality > best_fractionality {
best_fractionality = fractionality;
best_candidate = candidate;
}
}

let var = model.var_in_prob(best_candidate.var_prob_id).unwrap();
println!(
"-- MostInfeasibleBranching: Branching on variable {} with fractionality {}",
var.name(),
best_candidate.frac
);
BranchingResult::BranchOn(best_candidate)
}
}

fn main() {
// Initialize SCIP
let mut model = Model::new()
.include_default_plugins()
.read_prob("data/test/simple.mps")
.expect("Failed to read problem file")
.set_presolving(ParamSetting::Off)
.set_heuristics(ParamSetting::Off)
.set_separating(ParamSetting::Off);

// Add the custom branching rule
model.add(
branchrule(MostInfeasibleBranching)
.name("MostInfeasible")
.desc("Most infeasible branching rule"),
);

let solved = model.solve();

assert_eq!(solved.status(), Status::Optimal);
assert_eq!(solved.n_nodes(), 2);
}
7 changes: 7 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
pub use crate::branchrule::*;
pub use crate::builder::branchrule::branchrule;
pub use crate::builder::cons::cons;
pub use crate::builder::eventhdlr::eventhdlr;
pub use crate::builder::heur::heur;
pub use crate::builder::pricer::pricer;
pub use crate::builder::sepa::sepa;
pub use crate::builder::var::var;
pub use crate::conshdlr::*;
pub use crate::eventhdlr::*;
pub use crate::heuristic::*;
pub use crate::model::Model;
pub use crate::model::ModelWithProblem;
pub use crate::model::ObjSense;
pub use crate::model::ProblemOrSolving;
pub use crate::model::Solving;
pub use crate::model::WithSolutions;
pub use crate::model::WithSolvingStats;
pub use crate::pricer::*;
pub use crate::retcode::Retcode;
pub use crate::separator::*;
pub use crate::status::Status;
pub use crate::variable::VarType;
Loading