Simplify LinearExpr
This commit is contained in:
committed by
Guillaume P
parent
7d33f1668a
commit
de18b07571
@@ -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
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user