Min and max in builder
This commit is contained in:
committed by
Guillaume P
parent
04196f41d3
commit
8c5a66a03f
+36
-7
@@ -92,7 +92,7 @@ impl CpModelBuilder {
|
|||||||
self.add_eq_by_ref(&lhs.into(), &rhs.into())
|
self.add_eq_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_eq_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_eq_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([val, val]);
|
cst.domain.extend([val, val]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ impl CpModelBuilder {
|
|||||||
self.add_ge_by_ref(&lhs.into(), &rhs.into())
|
self.add_ge_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_ge_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_ge_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([val, i64::MAX]);
|
cst.domain.extend([val, i64::MAX]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ impl CpModelBuilder {
|
|||||||
self.add_le_by_ref(&lhs.into(), &rhs.into())
|
self.add_le_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_le_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_le_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([i64::MIN, val]);
|
cst.domain.extend([i64::MIN, val]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ impl CpModelBuilder {
|
|||||||
self.add_gt_by_ref(&lhs.into(), &rhs.into())
|
self.add_gt_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_gt_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_gt_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([val + 1, i64::MAX]);
|
cst.domain.extend([val + 1, i64::MAX]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ impl CpModelBuilder {
|
|||||||
self.add_lt_by_ref(&lhs.into(), &rhs.into())
|
self.add_lt_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_lt_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_lt_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([i64::MIN, val - 1]);
|
cst.domain.extend([i64::MIN, val - 1]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
@@ -152,10 +152,30 @@ impl CpModelBuilder {
|
|||||||
self.add_ne_by_ref(&lhs.into(), &rhs.into())
|
self.add_ne_by_ref(&lhs.into(), &rhs.into())
|
||||||
}
|
}
|
||||||
pub fn add_ne_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
pub fn add_ne_by_ref(&mut self, lhs: &LinearExpr, rhs: &LinearExpr) -> Constraint {
|
||||||
let (mut cst, val) = create_linear_proto(lhs, rhs);
|
let (mut cst, val) = create_linear_cst_proto(lhs, rhs);
|
||||||
cst.domain.extend([i64::MIN, val - 1, val + 1, i64::MAX]);
|
cst.domain.extend([i64::MIN, val - 1, val + 1, i64::MAX]);
|
||||||
self.add_cst(CstEnum::Linear(cst))
|
self.add_cst(CstEnum::Linear(cst))
|
||||||
}
|
}
|
||||||
|
pub fn add_min_eq(
|
||||||
|
&mut self,
|
||||||
|
target: impl Into<LinearExpr>,
|
||||||
|
exprs: impl IntoIterator<Item = impl Into<LinearExpr>>,
|
||||||
|
) -> Constraint {
|
||||||
|
self.add_cst(CstEnum::LinMin(proto::LinearArgumentProto {
|
||||||
|
target: Some(target.into().into()),
|
||||||
|
exprs: exprs.into_iter().map(|e| e.into().into()).collect(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
pub fn add_max_eq(
|
||||||
|
&mut self,
|
||||||
|
target: impl Into<LinearExpr>,
|
||||||
|
exprs: impl IntoIterator<Item = impl Into<LinearExpr>>,
|
||||||
|
) -> Constraint {
|
||||||
|
self.add_cst(CstEnum::LinMax(proto::LinearArgumentProto {
|
||||||
|
target: Some(target.into().into()),
|
||||||
|
exprs: exprs.into_iter().map(|e| e.into().into()).collect(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
fn add_cst(&mut self, cst: CstEnum) -> Constraint {
|
fn add_cst(&mut self, cst: CstEnum) -> Constraint {
|
||||||
let index = self.proto.constraints.len();
|
let index = self.proto.constraints.len();
|
||||||
self.proto.constraints.push(proto::ConstraintProto {
|
self.proto.constraints.push(proto::ConstraintProto {
|
||||||
@@ -338,8 +358,17 @@ where
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl From<LinearExpr> for proto::LinearExpressionProto {
|
||||||
|
fn from(expr: LinearExpr) -> Self {
|
||||||
|
proto::LinearExpressionProto {
|
||||||
|
vars: expr.vars,
|
||||||
|
coeffs: expr.coeffs,
|
||||||
|
offset: expr.constant,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_linear_proto(
|
fn create_linear_cst_proto(
|
||||||
left: &LinearExpr,
|
left: &LinearExpr,
|
||||||
right: &LinearExpr,
|
right: &LinearExpr,
|
||||||
) -> (proto::LinearConstraintProto, i64) {
|
) -> (proto::LinearConstraintProto, i64) {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use cp_sat::builder::CpModelBuilder;
|
||||||
|
use cp_sat::proto::CpSolverStatus;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn min() {
|
||||||
|
let mut model = CpModelBuilder::default();
|
||||||
|
let x = model.new_int_var([(0, 10)]);
|
||||||
|
let y = model.new_int_var([(5, 15)]);
|
||||||
|
let m = model.new_int_var([(-100, 100)]);
|
||||||
|
model.add_min_eq(m, [x, y]);
|
||||||
|
model.maximize(m);
|
||||||
|
|
||||||
|
println!("{:#?}", model.proto());
|
||||||
|
let response = model.solve();
|
||||||
|
assert_eq!(response.status(), CpSolverStatus::Optimal);
|
||||||
|
assert_eq!(10., response.objective_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn max() {
|
||||||
|
let mut model = CpModelBuilder::default();
|
||||||
|
let x = model.new_int_var([(0, 10)]);
|
||||||
|
let y = model.new_int_var([(5, 15)]);
|
||||||
|
let m = model.new_int_var([(-100, 100)]);
|
||||||
|
model.add_max_eq(m, [x, y]);
|
||||||
|
model.minimize(m);
|
||||||
|
|
||||||
|
println!("{:#?}", model.proto());
|
||||||
|
let response = model.solve();
|
||||||
|
assert_eq!(response.status(), CpSolverStatus::Optimal);
|
||||||
|
assert_eq!(5., response.objective_value);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user