use ::approx::AbsDiffEq;
use super::*;
use crate::Sense;
use std::ops::Neg;
impl AbsDiffEq for Instance {
type Epsilon = crate::ATol;
fn default_epsilon() -> Self::Epsilon {
Function::default_epsilon()
}
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
let self_vars = self.used_decision_variables();
let other_vars = other.used_decision_variables();
if self_vars.len() != other_vars.len() {
return false;
}
for ((id, var), (other_id, other_var)) in self_vars.iter().zip(other_vars.iter()) {
if id != other_id || !var.abs_diff_eq(other_var, epsilon) {
return false;
}
}
match (self.sense, other.sense) {
(Sense::Minimize, Sense::Maximize) | (Sense::Maximize, Sense::Minimize) => {
if !self
.objective
.clone()
.neg()
.abs_diff_eq(&other.objective, epsilon)
{
return false;
}
}
_ => {
if !self.objective.abs_diff_eq(&other.objective, epsilon) {
return false;
}
}
}
for (id, c_self) in &self.constraints {
match other.constraints.get(id) {
Some(c_other) => {
if !c_self.abs_diff_eq(c_other, epsilon) {
return false;
}
}
None => return false,
}
}
true
}
}