Simplify LinearExpr

This commit is contained in:
Guillaume Pinot
2021-09-13 16:15:06 +02:00
committed by Guillaume P
parent 7d33f1668a
commit de18b07571
2 changed files with 41 additions and 77 deletions
+1
View File
@@ -14,6 +14,7 @@ readme = "README.md"
prost = "0.8" prost = "0.8"
bytes = "1.1.0" bytes = "1.1.0"
libc = "0.2.101" libc = "0.2.101"
smallvec = { version = "1.6.1", default-features = false, features = ["union"]}
[build-dependencies] [build-dependencies]
prost-build = { version = "0.8" } prost-build = { version = "0.8" }
+40 -77
View File
@@ -1,5 +1,6 @@
use crate::{ffi, proto}; use crate::{ffi, proto};
use proto::constraint_proto::Constraint as CstEnum; use proto::constraint_proto::Constraint as CstEnum;
use smallvec::SmallVec;
/// A builder for CP SAT. /// A builder for CP SAT.
/// ///
@@ -355,8 +356,8 @@ impl CpModelBuilder {
let expr = expr.into(); let expr = expr.into();
let constant = expr.constant; let constant = expr.constant;
self.add_cst(CstEnum::Linear(proto::LinearConstraintProto { self.add_cst(CstEnum::Linear(proto::LinearConstraintProto {
vars: expr.vars, vars: expr.vars.into_vec(),
coeffs: expr.coeffs, coeffs: expr.coeffs.into_vec(),
domain: domain domain: domain
.into_iter() .into_iter()
.flat_map(|(begin, end)| { .flat_map(|(begin, end)| {
@@ -641,8 +642,8 @@ impl CpModelBuilder {
pub fn minimize<T: Into<LinearExpr>>(&mut self, expr: T) { pub fn minimize<T: Into<LinearExpr>>(&mut self, expr: T) {
let expr = expr.into(); let expr = expr.into();
self.proto.objective = Some(proto::CpObjectiveProto { self.proto.objective = Some(proto::CpObjectiveProto {
vars: expr.vars, vars: expr.vars.into_vec(),
coeffs: expr.coeffs, coeffs: expr.coeffs.into_vec(),
offset: expr.constant as f64, offset: expr.constant as f64,
scaling_factor: 1., scaling_factor: 1.,
domain: vec![], domain: vec![],
@@ -670,8 +671,8 @@ impl CpModelBuilder {
*coeff *= -1; *coeff *= -1;
} }
self.proto.objective = Some(proto::CpObjectiveProto { self.proto.objective = Some(proto::CpObjectiveProto {
vars: expr.vars, vars: expr.vars.into_vec(),
coeffs: expr.coeffs, coeffs: expr.coeffs.into_vec(),
offset: -expr.constant as f64, offset: -expr.constant as f64,
scaling_factor: -1., scaling_factor: -1.,
domain: vec![], domain: vec![],
@@ -818,12 +819,14 @@ pub struct Constraint(usize);
#[derive(Clone, Default, Debug)] #[derive(Clone, Default, Debug)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct LinearExpr { pub struct LinearExpr {
vars: Vec<i32>, vars: SmallVec<[i32; 2]>,
coeffs: Vec<i64>, coeffs: SmallVec<[i64; 2]>,
constant: i64, constant: i64,
} }
impl std::ops::AddAssign for LinearExpr {
fn add_assign(&mut self, mut rhs: Self) { impl<E: Into<LinearExpr>> std::ops::AddAssign<E> for LinearExpr {
fn add_assign(&mut self, rhs: E) {
let mut rhs = rhs.into();
if self.vars.len() < rhs.vars.len() { if self.vars.len() < rhs.vars.len() {
std::mem::swap(self, &mut rhs); std::mem::swap(self, &mut rhs);
} }
@@ -847,71 +850,34 @@ impl<L: Into<LinearExpr>> std::ops::SubAssign<L> for LinearExpr {
*self += -rhs.into(); *self += -rhs.into();
} }
} }
impl std::ops::AddAssign<i64> for LinearExpr {
fn add_assign(&mut self, rhs: i64) {
self.constant += rhs;
}
}
impl<V: Into<IntVar>> std::ops::AddAssign<(i64, V)> for LinearExpr {
fn add_assign(&mut self, (coeff, var): (i64, V)) {
let var = var.into();
if var.0 < 0 {
self.vars.push(var.not().0);
self.coeffs.push(-coeff);
self.constant += coeff;
} else {
self.vars.push(var.0);
self.coeffs.push(coeff);
}
}
}
impl<V: Into<IntVar>> std::ops::AddAssign<V> for LinearExpr {
fn add_assign(&mut self, var: V) {
*self += (1, var);
}
}
impl<V: Into<IntVar>> std::iter::Extend<(i64, V)> for LinearExpr {
fn extend<I: IntoIterator<Item = (i64, V)>>(&mut self, iter: I) {
for (coeff, var) in iter.into_iter() {
*self += (coeff, var.into());
}
}
}
impl<V: Into<IntVar>> std::iter::FromIterator<(i64, V)> for LinearExpr {
fn from_iter<I: IntoIterator<Item = (i64, V)>>(iter: I) -> Self {
let mut res = Self::default();
res.extend(iter);
res
}
}
impl<V: Into<IntVar>> std::iter::Extend<V> for LinearExpr {
fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
for var in iter.into_iter() {
*self += var.into();
}
}
}
impl<V: Into<IntVar>> std::iter::FromIterator<V> for LinearExpr {
fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
let mut res = Self::default();
res.extend(iter);
res
}
}
impl<V: Into<IntVar>> From<V> for LinearExpr { impl<V: Into<IntVar>> From<V> for LinearExpr {
fn from(var: V) -> Self { fn from(var: V) -> Self {
let mut res = Self::default(); Self::from((1, var))
res += var;
res
} }
} }
impl From<i64> for LinearExpr { impl From<i64> for LinearExpr {
fn from(constant: i64) -> Self { fn from(constant: i64) -> Self {
let mut res = Self::default(); let mut res = Self::default();
res += constant; res.constant += constant;
res res
} }
} }
impl<V: Into<IntVar>> From<(i64, V)> for LinearExpr {
fn from((coeff, var): (i64, V)) -> Self {
let mut res = Self::default();
let var = var.into();
if var.0 < 0 {
res.vars.push(var.not().0);
res.coeffs.push(-coeff);
res.constant += coeff;
} else {
res.vars.push(var.0);
res.coeffs.push(coeff);
}
return res;
}
}
impl<V: Into<IntVar>, const L: usize> From<[(i64, V); L]> for LinearExpr { impl<V: Into<IntVar>, const L: usize> From<[(i64, V); L]> for LinearExpr {
fn from(expr: [(i64, V); L]) -> Self { fn from(expr: [(i64, V); L]) -> Self {
let mut res = Self::default(); let mut res = Self::default();
@@ -921,31 +887,28 @@ impl<V: Into<IntVar>, const L: usize> From<[(i64, V); L]> for LinearExpr {
res res
} }
} }
impl<T> std::ops::Add<T> for LinearExpr
where impl<T: Into<LinearExpr>> std::ops::Add<T> for LinearExpr {
LinearExpr: std::ops::AddAssign<T>,
{
type Output = LinearExpr; type Output = LinearExpr;
fn add(mut self, rhs: T) -> Self::Output { fn add(mut self, rhs: T) -> Self::Output {
self += rhs; self += rhs.into();
self self
} }
} }
impl<T> std::ops::Sub<T> for LinearExpr
where impl<T: Into<LinearExpr>> std::ops::Sub<T> for LinearExpr {
LinearExpr: std::ops::SubAssign<T>,
{
type Output = LinearExpr; type Output = LinearExpr;
fn sub(mut self, rhs: T) -> Self::Output { fn sub(mut self, rhs: T) -> Self::Output {
self -= rhs; self -= rhs.into();
self self
} }
} }
impl From<LinearExpr> for proto::LinearExpressionProto { impl From<LinearExpr> for proto::LinearExpressionProto {
fn from(expr: LinearExpr) -> Self { fn from(expr: LinearExpr) -> Self {
proto::LinearExpressionProto { proto::LinearExpressionProto {
vars: expr.vars, vars: expr.vars.into_vec(),
coeffs: expr.coeffs, coeffs: expr.coeffs.into_vec(),
offset: expr.constant, offset: expr.constant,
} }
} }