### Implementing Specialized Constraints Source: https://context7.com/scipopt/russcip/llms.txt Provides examples of adding advanced constraint types such as set partitioning, covering, packing, cardinality, SOS1, indicator, and quadratic constraints. ```rust use russcip::prelude::*; let mut model = Model::default().minimize(); let x1 = model.add(var().bin().obj(3.0)); let x2 = model.add(var().bin().obj(4.0)); let x3 = model.add(var().bin().obj(5.0)); model.add_cons_set_part(vec![&x1, &x2, &x3], "partition"); model.add_cons_set_cover(vec![&x1, &x2], "cover"); model.add_cons_set_pack(vec![&x2, &x3], "pack"); let y1 = model.add(var().cont(0.0..=10.0).obj(1.0)); let y2 = model.add(var().cont(0.0..=10.0).obj(2.0)); let y3 = model.add(var().cont(0.0..=10.0).obj(3.0)); model.add_cons_cardinality(vec![&y1, &y2, &y3], 2, "card"); model.add_cons_sos1(vec![&y1, &y2, &y3], Some(&[1.0, 2.0, 3.0]), "sos1"); let indicator = model.add(var().bin()); model.add_cons_indicator(&indicator, vec![&y1, &y2], &mut [1.0, -1.0], 0.0, "ind"); model.add_cons_quadratic(vec![], &mut [], vec![&y1, &y2], vec![&y1, &y2], &mut [1.0, 1.0], 0.0, 1.0, "circle"); ``` -------------------------------- ### Implement Custom Primal Heuristic in Rust Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to implement the Heuristic trait to create custom primal heuristics. This example performs simple rounding of LP solution values and attempts to add the resulting solution to the SCIP model. ```rust use russcip::prelude::*;\nuse russcip::{Heuristic, HeurResult, HeurTiming, Solving, ProblemOrSolving};\n\nstruct RoundingHeuristic;\n\nimpl Heuristic for RoundingHeuristic {\n fn execute(\n &mut self,\n model: Model,\n _timing: HeurTiming,\n _node_inf: bool,\n ) -> HeurResult {\n let sol = model.create_sol();\n\n for var in model.vars() {\n let lp_val = var.sol_val();\n let rounded = lp_val.round();\n sol.set_val(&var, rounded);\n }\n\n match model.add_sol(sol) {\n Ok(_) => {\n println!("Heuristic found a solution!");\n HeurResult::FoundSol\n }\n Err(_) => HeurResult::NoSolFound\n }\n }\n}\n\nfn main() {\n let mut model = Model::new()\n .hide_output()\n .include_default_plugins()\n .read_prob("problem.lp")\n .unwrap();\n\n model.add(\n heur(RoundingHeuristic)\n .name("rounding")\n .desc("Simple rounding heuristic")\n .dispchar('R')\n .timing(HeurTiming::AFTER_LP_NODE | HeurTiming::AFTER_LP_PLUNGE)\n .priority(1000)\n .freq(1)\n );\n\n model.solve();\n} ``` -------------------------------- ### Install russcip via Cargo Source: https://github.com/scipopt/russcip/blob/main/README.md The standard way to add the russcip dependency to a Rust project using the bundled feature for easier installation. ```bash cargo add russcip --features bundled ``` -------------------------------- ### Model Creation and Solving Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to initialize a model, define variables and constraints, and execute the solver. ```APIDOC ## POST /model/solve ### Description Initializes a new optimization model, adds variables and constraints, and triggers the SCIP solver to find an optimal solution. ### Method POST ### Endpoint /model/solve ### Parameters #### Request Body - **objective** (string) - Required - Optimization direction (maximize/minimize) - **variables** (array) - Required - List of variables with types and objective coefficients - **constraints** (array) - Required - List of linear constraints ### Request Example { "objective": "maximize", "variables": [{"name": "x1", "type": "int", "obj": 3.0}, {"name": "x2", "type": "int", "obj": 2.0}], "constraints": [{"name": "c1", "coefs": {"x1": 2.0, "x2": 1.0}, "rhs": 100.0, "sense": "le"}] } ### Response #### Success Response (200) - **status** (string) - Solver status (e.g., Optimal) - **obj_val** (float) - The objective value found - **solution** (object) - Map of variable names to values ``` -------------------------------- ### Setting Solver Parameters Source: https://context7.com/scipopt/russcip/llms.txt Illustrates how to configure the SCIP solver's behavior using various parameters, including time limits, memory limits, verbosity, and algorithm tuning. ```APIDOC ## Setting Solver Parameters ### Description Configure SCIP's behavior through various parameter settings for time limits, memory limits, verbosity, and algorithm tuning. ### Method `Model::hide_output`, `Model::set_time_limit`, `Model::set_memory_limit`, `Model::set_presolving`, `Model::set_heuristics`, `Model::set_separating`, `Model::set_int_param`, `Model::set_real_param`, `Model::set_longint_param`, `Model::set_bool_param`, `Model::param` ### Endpoint N/A (Internal model configuration) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; let model = Model::new() // Control output verbosity (0 = silent, 4 = default) .hide_output() // or .show_output() or .set_display_verbosity(2) // Resource limits .set_time_limit(60) // 60 second time limit .set_memory_limit(4096) // 4GB memory limit // Algorithm settings .set_presolving(ParamSetting::Aggressive) .set_heuristics(ParamSetting::Fast) .set_separating(ParamSetting::Off) // Direct parameter access .set_int_param("limits/solutions", 10).unwrap() .set_real_param("limits/gap", 0.01).unwrap() .set_longint_param("limits/nodes", 1000).unwrap() .set_bool_param("display/allviols", true).unwrap() .include_default_plugins() .create_prob("problem"); // Read parameters back let time_limit: f64 = model.param("limits/time"); let verbosity: i32 = model.param("display/verblevel"); ``` ### Response #### Success Response (200) N/A (Configuration, success indicated by lack of panic) #### Response Example N/A ``` -------------------------------- ### Configuring Solver Parameters Source: https://context7.com/scipopt/russcip/llms.txt Shows how to adjust solver behavior including resource limits, verbosity, and algorithm-specific settings. It also demonstrates how to read parameter values back from the model. ```rust use russcip::prelude::*; let model = Model::new() .hide_output() .set_time_limit(60) .set_memory_limit(4096) .set_presolving(ParamSetting::Aggressive) .set_heuristics(ParamSetting::Fast) .set_separating(ParamSetting::Off) .set_int_param("limits/solutions", 10).unwrap() .set_real_param("limits/gap", 0.01).unwrap() .set_longint_param("limits/nodes", 1000).unwrap() .set_bool_param("display/allviols", true).unwrap() .include_default_plugins() .create_prob("problem"); let time_limit: f64 = model.param("limits/time"); let verbosity: i32 = model.param("display/verblevel"); ``` -------------------------------- ### Create and Solve Basic MIP Model in Rust Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates creating a maximization model, adding integer variables with objective coefficients, defining constraints, solving the model, and retrieving the solution status and objective value. It uses the builder API for variables and constraints. ```rust use russcip::prelude::*; fn main() { // Create a maximization model let mut model = Model::default().maximize(); // Add integer variables with objective coefficients let x1 = model.add(var().int(0..).obj(3.).name("x1")); let x2 = model.add(var().int(0..).obj(2.).name("x2")); // Add constraints: 2*x1 + x2 <= 100 and x1 + 2*x2 <= 80 model.add(cons().name("c1").coef(&x1, 2.).coef(&x2, 1.).le(100.)); model.add(cons().name("c2").coef(&x1, 1.).coef(&x2, 2.).le(80.)); // Solve the model let solved_model = model.solve(); // Check status and get solution println!("Status: {:?}", solved_model.status()); println!("Objective value: {}", solved_model.obj_val()); let sol = solved_model.best_sol().unwrap(); for var in solved_model.vars() { println!("{} = {}", var.name(), sol.val(&var)); } } ``` -------------------------------- ### Problem File Loading Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to load an existing optimization problem from standard file formats like LP or MPS. ```APIDOC ## POST /model/read ### Description Loads an optimization problem definition from a file path (LP or MPS format) into the solver instance. ### Method POST ### Endpoint /model/read ### Parameters #### Query Parameters - **file_path** (string) - Required - Path to the .lp or .mps file ### Request Example { "file_path": "problem.lp" } ### Response #### Success Response (200) - **status** (string) - Solver status after execution - **obj_val** (float) - Objective value - **solving_time** (float) - Time taken to solve in seconds ``` -------------------------------- ### Managing Solutions Source: https://context7.com/scipopt/russcip/llms.txt Explains how to create custom solutions, add them to the model, and retrieve results after solving. It includes methods for accessing variable values via maps. ```rust use russcip::prelude::*; let mut model = Model::default().maximize(); let x = model.add(var().bin().obj(3.0).name("x")); let y = model.add(var().bin().obj(4.0).name("y")); model.add(cons().coef(&x, 1.0).coef(&y, 1.0).le(1.0)); let sol = model.create_orig_sol(); sol.set_val(&x, 1.0); sol.set_val(&y, 0.0); model.add_sol(sol).ok(); let solved = model.solve(); if let Some(best_sol) = solved.best_sol() { println!("Best objective: {}", best_sol.obj_val()); let name_map = best_sol.as_name_map(); for (name, value) in &name_map { println!("{}: {}", name, value); } } ``` -------------------------------- ### Exporting Optimization Problems to Files Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to save an optimization model to standard formats like LP or MPS. This is useful for debugging model structure or sharing problems with other solvers. ```rust use russcip::prelude::*; let mut model = Model::default().minimize(); let x = model.add(var().int(0..=100).obj(1.0).name("x")); let y = model.add(var().int(0..=100).obj(2.0).name("y")); model.add(cons().coef(&x, 1.0).coef(&y, 1.0).ge(10.0)); // Write to LP format with symbolic names model.write("output", "lp", true).expect("Failed to write"); // Write to MPS format with indices model.write("output", "mps", false).expect("Failed to write"); ``` -------------------------------- ### Read Optimization Problems from Files in Rust Source: https://context7.com/scipopt/russcip/llms.txt Shows how to load optimization problems from LP or MPS files using `read_prob()`. It also demonstrates solving the loaded model and retrieving various statistics such as status, objective value, nodes explored, solving time, and LP iterations. ```rust use russcip::prelude::*; // Read problem from LP file let model = Model::new() .hide_output() .include_default_plugins() .read_prob("problem.lp") .expect("Failed to read problem file") .solve(); println!("Status: {:?}", model.status()); println!("Objective: {}", model.obj_val()); println!("Nodes explored: {}", model.n_nodes()); println!("Solving time: {:.2}s", model.solving_time()); println!("LP iterations: {}", model.n_lp_iterations()); // Get all solutions if let Some(solutions) = model.get_sols() { for (i, sol) in solutions.iter().enumerate() { println!("Solution {}: obj = {}", i, sol.obj_val()); } } ``` -------------------------------- ### Writing Problems to Files Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to save optimization problems to files in various formats like LP and MPS, useful for debugging and external tool integration. ```APIDOC ## Writing Problems to Files ### Description Save optimization problems to files for debugging, sharing, or solving with other tools. ### Method `Model::write` ### Endpoint N/A (Local file operation) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; let mut model = Model::default().minimize(); let x = model.add(var().int(0..=100).obj(1.0).name("x")); let y = model.add(var().int(0..=100).obj(2.0).name("y")); model.add(cons().coef(&x, 1.0).coef(&y, 1.0).ge(10.0)); // Write to LP format with symbolic names model.write("output", "lp", true).expect("Failed to write"); // Write to MPS format with indices model.write("output", "mps", false).expect("Failed to write"); ``` ### Response #### Success Response (200) N/A (File operation, success indicated by lack of panic) #### Response Example N/A ``` -------------------------------- ### Solution Handling Source: https://context7.com/scipopt/russcip/llms.txt Covers accessing and manipulating solutions, including creating custom solutions, retrieving solution values, and converting solutions to different map formats. ```APIDOC ## Solution Handling ### Description Access and manipulate solutions, including creating custom solutions and retrieving solution values. ### Method `Model::create_orig_sol`, `Solution::set_val`, `Solution::obj_val`, `Model::add_sol`, `Model::solve`, `SolvedModel::best_sol`, `Solution::val`, `Solution::as_name_map`, `Solution::as_id_map`, `SolvedModel::n_sols` ### Endpoint N/A (Internal model solving and solution access) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; let mut model = Model::default().maximize(); let x = model.add(var().bin().obj(3.0).name("x")); let y = model.add(var().bin().obj(4.0).name("y")); model.add(cons().coef(&x, 1.0).coef(&y, 1.0).le(1.0)); // Create and add a custom solution before solving let sol = model.create_orig_sol(); sol.set_val(&x, 1.0); sol.set_val(&y, 0.0); println!("Custom solution obj: {}", sol.obj_val()); if model.add_sol(sol).is_ok() { println!("Solution added successfully"); } let solved = model.solve(); // Access best solution if let Some(best_sol) = solved.best_sol() { println!("Best objective: {}", best_sol.obj_val()); println!("x = {}, y = {}", best_sol.val(&x), best_sol.val(&y)); // Get solution as maps let name_map = best_sol.as_name_map(); // HashMap let id_map = best_sol.as_id_map(); // HashMap for (name, value) in &name_map { println!("{}: {}", name, value); } } println!("Total solutions found: {}", solved.n_sols()); ``` ### Response #### Success Response (200) N/A (Solution data is accessed via methods) #### Response Example N/A ``` -------------------------------- ### Define Constraints with Builder API in Rust Source: https://context7.com/scipopt/russcip/llms.txt Shows how to define constraints using the `cons()` builder, specifying coefficients for variables and using `le()`, `ge()`, or `eq()` methods to set the constraint type and bound. It also demonstrates using `expr()` for multiple coefficients. ```rust use russcip::prelude::*; let mut model = Model::default().maximize(); let x = model.add(var().cont(0.0..=10.0).obj(1.0).name("x")); let y = model.add(var().cont(0.0..=10.0).obj(2.0).name("y")); let z = model.add(var().cont(0.0..=10.0).obj(3.0).name("z")); // Less-than-or-equal constraint: x + 2y <= 15 model.add(cons().name("c1").coef(&x, 1.0).coef(&y, 2.0).le(15.0)); // Greater-than-or-equal constraint: y + z >= 5 model.add(cons().name("c2").coef(&y, 1.0).coef(&z, 1.0).ge(5.0)); // Equality constraint: x + y + z = 10 model.add(cons().name("c3").coef(&x, 1.0).coef(&y, 1.0).coef(&z, 1.0).eq(10.0)); // Using expr() for multiple coefficients at once let vars = vec![&x, &y, &z]; model.add( cons() .name("c4") .expr(vars.iter().map(|v| (*v, 1.0))) .le(20.0) ); let solved = model.solve(); println!("Optimal value: {}", solved.obj_val()); ``` -------------------------------- ### Attach and Manage Custom Data in SCIP Model Source: https://github.com/scipopt/russcip/blob/main/README.md Demonstrates how to attach user-defined structs to a SCIP Model instance using anymap. This allows for persistent storage and retrieval of custom data during the optimization process. ```rust let mut model = Model::new(); // Some user-defined data struct MyData { title: String, } let data = MyData { title: "My Data".to_string(), }; // Attach the data to the model model.set_data(data); // Retrieve the data let data_ref = model.get_data::().unwrap(); assert_eq!(data_ref.title, "My Data"); // Mutate the data let data_mut = model.get_data_mut::().unwrap(); data_mut.title = "New Title".to_string(); assert_eq!(data_mut.title, "New Title"); ``` -------------------------------- ### Custom Primal Heuristics Source: https://context7.com/scipopt/russcip/llms.txt Illustrates how to create custom primal heuristics by implementing the `Heuristic` trait and integrating them into the SCIP solving process. ```APIDOC ## Custom Primal Heuristics Implement primal heuristics to find feasible solutions during the solving process. ### Description This section demonstrates creating a primal heuristic that rounds the LP solution values to find a feasible integer solution. ### Method `Model::add` with `heur` ### Endpoint N/A (In-process customization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; use russcip::{Heuristic, HeurResult, HeurTiming, Solving, ProblemOrSolving}; struct RoundingHeuristic; impl Heuristic for RoundingHeuristic { fn execute( &mut self, model: Model, _timing: HeurTiming, _node_inf: bool, ) -> HeurResult { // Create a new solution let sol = model.create_sol(); // Round LP solution values for var in model.vars() { let lp_val = var.sol_val(); let rounded = lp_val.round(); sol.set_val(&var, rounded); } // Try to add the solution match model.add_sol(sol) { Ok(_) => { println!("Heuristic found a solution!"); HeurResult::FoundSol } Err(_) => HeurResult::NoSolFound } } } fn main() { let mut model = Model::new() .hide_output() .include_default_plugins() .read_prob("problem.lp") .unwrap(); // Add heuristic with timing configuration model.add( heur(RoundingHeuristic) .name("rounding") .desc("Simple rounding heuristic") .dispchar('R') .timing(HeurTiming::AFTER_LP_NODE | HeurTiming::AFTER_LP_PLUNGE) .priority(1000) .freq(1) // call at every node ); model.solve(); } ``` ### Response #### Success Response (200) N/A (In-process execution) #### Response Example N/A ``` -------------------------------- ### Define Variables with Builder API in Rust Source: https://context7.com/scipopt/russcip/llms.txt Illustrates using the `var()` builder to define different types of variables (binary, integer, continuous) with specific bounds, objective coefficients, and names. It also shows how to access variable properties after creation. ```rust use russcip::prelude::*; let mut model = Model::default().minimize(); // Binary variable (0 or 1) let binary_var = model.add(var().bin().obj(1.0).name("y")); // Integer variable with bounds [0, 100] let int_var = model.add(var().int(0..=100).obj(2.0).name("x")); // Continuous variable with lower bound only let cont_var = model.add(var().cont(0.0..).obj(0.5).name("z")); // Implicit integer variable let impl_int = model.add(var().impl_int(0..=50).name("w")); // Access variable properties println!("Name: {}, Type: {:?}, Obj: {}", binary_var.name(), binary_var.var_type(), binary_var.obj()); println!("Bounds: [{}, {}]", int_var.lb(), int_var.ub()); ``` -------------------------------- ### Perform Iterative Solving with Free Transform Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to transition a solved model back to a modifiable state using free_transform. This is useful for sequential optimization tasks where the model structure changes based on previous results. ```rust use russcip::prelude::*;\n\nfn main() {\n let mut model = Model::default().maximize();\n let x = model.add(var().int(0..=100).obj(3.0).name("x"));\n let y = model.add(var().int(0..=100).obj(2.0).name("y"));\n model.add(cons().coef(&x, 2.0).coef(&y, 1.0).le(100.0));\n\n let solved = model.solve();\n let mut model = solved.free_transform();\n\n let z = model.add(var().int(0..=50).obj(4.0).name("z"));\n model.add(cons().coef(&z, 1.0).le(25.0));\n\n let solved = model.solve();\n println!("Second solve: obj = {}", solved.obj_val());\n} ``` -------------------------------- ### Accessing Raw C-API Source: https://github.com/scipopt/russcip/blob/main/README.md How to access the underlying SCIP raw pointers for advanced usage not covered by the safe wrapper. ```APIDOC ## Accessing Raw C-API ### Description The `ffi` module provides access to the raw C-API. Users can access the raw pointer of a Model or its components (Variables, Constraints) using the `inner` or `scip_ptr` methods. ### Methods - `Model::scip_ptr()`: Returns `*mut ffi::SCIP` - `Variable::inner()`: Returns `*mut ffi::SCIP_VAR` - `Constraint::inner()`: Returns `*mut ffi::SCIP_CONS` ### Usage Note These methods are marked as `unsafe` and should be used with caution when functionality is not yet exposed by the safe Rust interface. ``` -------------------------------- ### Attach and Manage Custom Data in Models Source: https://context7.com/scipopt/russcip/llms.txt Shows how to store and retrieve custom structs within a SCIP model. This allows for persistent state management across different solving phases or plugins. ```rust use russcip::prelude::*;\n\n#[derive(Debug)]\nstruct ProblemData {\n name: String,\n node_count: usize,\n best_solution_time: Option,\n}\n\nfn main() {\n let mut model = Model::default().minimize();\n let data = ProblemData {\n name: "My Problem".to_string(),\n node_count: 0,\n best_solution_time: None,\n };\n model.set_data(data);\n\n let data_ref = model.get_data::().unwrap();\n println!("Problem: {}", data_ref.name);\n\n let data_mut = model.get_data_mut::().unwrap();\n data_mut.node_count = 100;\n data_mut.best_solution_time = Some(1.5);\n} ``` -------------------------------- ### Create Minimal Model in Rust Source: https://context7.com/scipopt/russcip/llms.txt Creates a stripped-down optimization model using `minimal_model()` in Russcip. This model is configured without presolving, heuristics, or separation, ensuring predictable behavior for testing. It demonstrates adding binary variables, an objective function, and a constraint, then solving and asserting the optimal status and objective value. ```rust use russcip::{minimal_model, prelude::*}; fn main() { let mut model = minimal_model() .hide_output() .maximize(); let x = model.add(var().bin().obj(1.0)); let y = model.add(var().bin().obj(2.0)); model.add(cons().coef(&x, 1.0).coef(&y, 1.0).le(1.0)); let solved = model.solve(); assert_eq!(solved.status(), Status::Optimal); assert_eq!(solved.obj_val(), 2.0); } ``` -------------------------------- ### Custom Branching Rules Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to implement custom branching rules by defining a struct that implements the `BranchRule` trait and adding it to the SCIP model. ```APIDOC ## Custom Branching Rules Implement custom branching strategies by implementing the `BranchRule` trait. ### Description This section shows how to create a custom branching rule that selects the variable with the fractional part closest to 0.5 for branching. ### Method `Model::add` with `branchrule` ### Endpoint N/A (In-process customization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; use russcip::{BranchRule, BranchingCandidate, BranchingResult, SCIPBranchRule, Solving}; struct MostInfeasibleBranching; impl BranchRule for MostInfeasibleBranching { fn execute( &mut self, model: Model, _branchrule: SCIPBranchRule, candidates: Vec, ) -> BranchingResult { // Find variable with fractional part closest to 0.5 let mut best = candidates.first().unwrap().clone(); let mut best_score = (best.frac - 0.5).abs(); for candidate in &candidates { let score = (candidate.frac - 0.5).abs(); if score < best_score { best_score = score; best = candidate.clone(); } } let var = model.var_in_prob(best.var_prob_id).unwrap(); println!("Branching on {} (frac={})", var.name(), best.frac); BranchingResult::BranchOn(best) } } fn main() { let mut model = Model::new() .hide_output() .include_default_plugins() .read_prob("problem.mps") .unwrap() .set_presolving(ParamSetting::Off); // Add custom branching rule with high priority model.add( branchrule(MostInfeasibleBranching) .name("MostInfeasible") .desc("Branch on most fractional variable") .priority(100000) .maxdepth(-1) // no depth limit ); let solved = model.solve(); println!("Status: {:?}, Nodes: {}", solved.status(), solved.n_nodes()); } ``` ### Response #### Success Response (200) N/A (In-process execution) #### Response Example N/A ``` -------------------------------- ### Implement Custom Variable Pricer for Column Generation Source: https://context7.com/scipopt/russcip/llms.txt Demonstrates how to implement the Pricer trait to solve pricing subproblems and dynamically add variables to a model. This is essential for large-scale optimization problems where not all variables can be explicitly defined. ```rust use russcip::prelude::*;\nuse russcip::{Pricer, PricerResult, PricerResultState, SCIPPricer, Solving};\n\nstruct KnapsackPricer {\n capacity: f64,\n weights: Vec,\n}\n\nimpl Pricer for KnapsackPricer {\n fn generate_columns(\n &mut self,\n mut model: Model,\n _pricer: SCIPPricer,\n farkas: bool,\n ) -> PricerResult {\n if farkas {\n return PricerResult {\n state: PricerResultState::NoColumns,\n lower_bound: None,\n };\n }\n\n let mut dual_values = Vec::new();\n for i in 0..self.weights.len() {\n if let Some(cons) = model.find_cons(&format!("demand_{}", i)) {\n if let Some(dual) = cons.dual_sol() {\n dual_values.push(dual);\n }\n }\n }\n\n let mut pricing = Model::default().hide_output().maximize();\n let vars: Vec<_> = self.weights.iter().enumerate().map(|(i, &w)| {\n pricing.add(var().int(0..).obj(dual_values.get(i).copied().unwrap_or(0.0)))\n }).collect();\n\n pricing.add(\n cons().expr(vars.iter().zip(self.weights.iter()).map(|(v, &w)| (v, w)))\n .le(self.capacity)\n );\n\n let solved_pricing = pricing.solve();\n\n if let Some(sol) = solved_pricing.best_sol() {\n let reduced_cost = 1.0 - sol.obj_val();\n\n if reduced_cost < -1e-6 {\n let new_var = model.add_priced_var(0.0, f64::INFINITY, 1.0, "pattern", VarType::Integer);\n\n for (i, v) in vars.iter().enumerate() {\n let coef = sol.val(v);\n if let Some(cons) = model.find_cons(&format!("demand_{}", i)) {\n model.add_cons_coef(&cons, &new_var, coef);\n }\n }\n\n return PricerResult {\n state: PricerResultState::FoundColumns,\n lower_bound: None,\n };\n }\n }\n\n PricerResult {\n state: PricerResultState::NoColumns,\n lower_bound: None,\n }\n }\n} ``` -------------------------------- ### Special Constraint Types Source: https://context7.com/scipopt/russcip/llms.txt Details on how to implement various specialized constraint types supported by Russcip, including set partitioning, covering, packing, cardinality, SOS1, indicator, and quadratic constraints. ```APIDOC ## Special Constraint Types ### Description Russcip supports specialized constraint types for common optimization patterns. ### Method `Model::add_cons_set_part`, `Model::add_cons_set_cover`, `Model::add_cons_set_pack`, `Model::add_cons_cardinality`, `Model::add_cons_sos1`, `Model::add_cons_indicator`, `Model::add_cons_quadratic` ### Endpoint N/A (Internal model constraint addition) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use russcip::prelude::*; let mut model = Model::default().minimize(); let x1 = model.add(var().bin().obj(3.0)); let x2 = model.add(var().bin().obj(4.0)); let x3 = model.add(var().bin().obj(5.0)); // Set partitioning: exactly one variable equals 1 model.add_cons_set_part(vec![&x1, &x2, &x3], "partition"); // Set covering: at least one variable equals 1 model.add_cons_set_cover(vec![&x1, &x2], "cover"); // Set packing: at most one variable equals 1 model.add_cons_set_pack(vec![&x2, &x3], "pack"); // Cardinality: at most k variables can be non-zero let y1 = model.add(var().cont(0.0..=10.0).obj(1.0)); let y2 = model.add(var().cont(0.0..=10.0).obj(2.0)); let y3 = model.add(var().cont(0.0..=10.0).obj(3.0)); model.add_cons_cardinality(vec![&y1, &y2, &y3], 2, "card"); // at most 2 non-zero // SOS1 constraint: at most one variable can be non-zero let weights = [1.0, 2.0, 3.0]; // branching priorities model.add_cons_sos1(vec![&y1, &y2, &y3], Some(&weights), "sos1"); // Indicator constraint: if bin_var=1, then linear constraint holds let indicator = model.add(var().bin()); model.add_cons_indicator(&indicator, vec![&y1, &y2], &mut [1.0, -1.0], 0.0, "ind"); // Quadratic constraint: x1^2 + x2^2 <= 1 let z1 = model.add(var().cont(0.0..=1.0)); let z2 = model.add(var().cont(0.0..=1.0)); model.add_cons_quadratic( vec![], // linear variables &mut [], // linear coefficients vec![&z1, &z2], // quad var 1 vec![&z1, &z2], // quad var 2 &mut [1.0, 1.0], // quad coefficients 0.0, // lhs 1.0, // rhs "circle" ); ``` ### Response #### Success Response (200) N/A (Constraint addition, success indicated by lack of panic) #### Response Example N/A ``` -------------------------------- ### Implement Custom Branching Rule in Rust Source: https://context7.com/scipopt/russcip/llms.txt Defines a custom branching strategy by implementing the BranchRule trait. The implementation selects the variable with a fractional part closest to 0.5 and registers it with the SCIP model. ```rust use russcip::prelude::*;\nuse russcip::{BranchRule, BranchingCandidate, BranchingResult, SCIPBranchRule, Solving};\n\nstruct MostInfeasibleBranching;\n\nimpl BranchRule for MostInfeasibleBranching {\n fn execute(\n &mut self,\n model: Model,\n _branchrule: SCIPBranchRule,\n candidates: Vec,\n ) -> BranchingResult {\n let mut best = candidates.first().unwrap().clone();\n let mut best_score = (best.frac - 0.5).abs();\n\n for candidate in &candidates {\n let score = (candidate.frac - 0.5).abs();\n if score < best_score {\n best_score = score;\n best = candidate.clone();\n }\n }\n\n let var = model.var_in_prob(best.var_prob_id).unwrap();\n println!("Branching on {} (frac={})", var.name(), best.frac);\n\n BranchingResult::BranchOn(best)\n }\n}\n\nfn main() {\n let mut model = Model::new()\n .hide_output()\n .include_default_plugins()\n .read_prob("problem.mps")\n .unwrap()\n .set_presolving(ParamSetting::Off);\n\n model.add(\n branchrule(MostInfeasibleBranching)\n .name("MostInfeasible")\n .desc("Branch on most fractional variable")\n .priority(100000)\n .maxdepth(-1)\n );\n\n let solved = model.solve();\n println!("Status: {:?}, Nodes: {}", solved.status(), solved.n_nodes());\n} ``` -------------------------------- ### Model Data Management Source: https://github.com/scipopt/russcip/blob/main/README.md Methods for attaching, retrieving, and mutating custom user-defined data within a SCIP Model instance. ```APIDOC ## Model Data Management ### Description Allows users to attach arbitrary data structures to a SCIP model instance for state management or communication between plugins. ### Methods - `set_data(data: T)`: Attaches data to the model. - `get_data() -> Option<&T>`: Retrieves a reference to the attached data. - `get_data_mut() -> Option<&mut T>`: Retrieves a mutable reference to the attached data. ### Request Example ```rust let mut model = Model::new(); struct MyData { title: String } let data = MyData { title: "My Data".to_string() }; model.set_data(data); ``` ### Response - **Success**: Returns the requested data type or a mutable reference to it. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.