Open youngzhaozju opened 2 months ago
I solved it. Thanks!
@youngzhaozju Great! would you mind sharing how? and/or the code? to help others with the same issue and to help me understand what is needed to be added to the interface.
I found the most important interface for me is SCIPparseExpr. It allows to add complex expression. It helps me a lot to make my codes simple. Using the current version 0.3.4, I have to write a lot of codes to make constraints. Here are the coding for your consideration:
in scrip.rs, add following:
fn add_Expression_by_txt(
&mut self,
content:&str
)->Expr{
let exp_rc = self.scip.crate_Expr_by_parse_string(content).expect(format!("Failed to prase txt in state ProblemCreated:{}", content).as_str());
return exp_rc;
}
pub(crate) fn crate_Expr_by_parse_string(&mut self, content: &str) -> Result<Expr, Retcode> {
let c_content = CString::new(content).expect("Failed to convert string to CString");
let mut scip_Expr = MaybeUninit::uninit();
let mut final_pos = ptr::null();
scip_call! { ffi::SCIPparseExpr(
self.raw,
scip_Expr.as_mut_ptr(),
c_content.as_ptr(),
&mut final_pos,
None,
std::ptr::null_mut(),
) };
let scip_Expr = unsafe { scip_Expr.assume_init() };
Ok(Expr { raw: scip_Expr })
}
Here is another important interface for me. it allows to use the above expression to make constraint directly:
fn add_basic_nonlinear_cons(
&mut self,
express: Expr,
lhs: f64,
rhs: f64,
name: &str,
) -> Rc<Constraint> {
let cons = self
.scip.create_cons_basic_nonlinear(express.raw,lhs,rhs,name).expect("Failed to create basic nonlinear constraint in state ProblemCreated");
let cons = Rc::new(cons);
self.state.conss.borrow_mut().push(cons.clone());
cons
}
fn add_Expression_text_to_eq_zero(
&mut self,
content:&str,
name:&str,
) {
let exp_rc = self.scip.crate_Expr_by_parse_string(content).expect(format!("Failed to prase txt in state ProblemCreated:{}", content).as_str());
self
.scip.create_cons_basic_nonlinear(exp_rc.raw,0.0,0.0,name).expect("Failed to create basic nonlinear constraint in state ProblemCreated");
}
Here is an example:
// Create model
let mut model = Model::new()
.hide_output()
.include_default_plugins()
.create_prob("test")
.set_obj_sense(ObjSense::Minimize);
// Add variables
let x1 = model.add_var(-10., 4.0, 1., "x1", VarType::Continuous);
let x2 = model.add_var(1.0, 5.0, 1.0, "x2", VarType::Continuous);
let mut x1_expr = model.add_expr_var(&x1);
let x2_expr = model.add_Expression_by_txt("<x2>*<x1> + <x1>^2.0 - <x1>*<x2>*<x2>");
model.add_basic_nonlinear_cons(x2_expr, 1.0, 1.0, "name");
let solved_model = model.solve();
let status = solved_model.status();
println!("Solved with status {:?}", status);
let obj_val = solved_model.obj_val();
println!("Objective value: {}", obj_val);
let sol = solved_model.best_sol().unwrap();
let vars = solved_model.vars();
for var in vars {
println!("{} = {}", &var.name(), sol.val(var));
}
let model = solved_model.free_transform();
println!("end");
Very cool! I could happily copy this code and add it to the repo, but maybe you want to open a PR? so that your contribution is counted in the commit history?
Thanks. I do not want to open a PR since I could not make continues contributions to this project. Anyway, thanks so much for your nice work!
Hey, I want to use the function of "SCIPcreateExprPow". It is not available currently.
Therefore, I want to add it by my self.
pub(crate) fn create_pow_expr( &mut self, base: &Variable, exponent: f64, ) -> Result<Expr, Retcode> { let mut expr_ptr = MaybeUninit::uninit(); scip_call! { ffi::SCIPcreateExprPow( self.raw, expr_ptr.as_mutptr(), base.raw as *mut , exponent, None, std::ptr::null_mut(), ) };
pub fn add_pow_expr(&mut self, base: &Variable, exponent: f64) -> Rc {
let exp = self
.scip
.create_pow_expr(base, exponent)
.expect("Failed to create express power in state ProblemCreated");
let exp_rc = Rc::new(exp);
return exp_rc;
}
Here is an example to utilize it,
// Create model let mut model = Model::new() .hide_output() .include_default_plugins() .create_prob("test") .set_obj_sense(ObjSense::Maximize);
I found that I cannot utilize it in model.add_cons . Is any suggestion?
Thank you! Young