mod nalgebra;
mod vecmatrix;
pub use crate::parser::{Edge, Graph, Vertex};
#[cfg(feature = "mpi")]
use mpi::traits::*;
pub trait AdjacencyMatrix {
fn from_dim(dim: usize) -> Self;
fn dim(&self) -> usize;
fn get(&self, row: usize, col: usize) -> f64;
fn set(&mut self, row: usize, col: usize, cost: f64);
fn evaluate_path(&self, path: &Path) -> f64 {
let n = path.len();
if n <= 1 {
return 0.0;
}
let mut acc = 0.0;
for from in 0..(n - 1) {
let to = from + 1;
let cost = self.get(path[from], path[to]);
acc += cost;
}
acc
}
fn evaluate_circle(&self, path: &Path) -> f64 {
if path.len() <= 1 {
return 0.0;
}
let last_edge = self.get(*path.last().unwrap(), *path.first().unwrap());
let path_cost = self.evaluate_path(path);
path_cost + last_edge
}
fn is_metric(&self) -> bool {
let dim = self.dim();
for i in 0..dim {
for j in i..dim {
let direct_cost = self.get(i, j);
for k in 0..dim {
let indirect_cost = self.get(i, k) + self.get(k, j);
if direct_cost > indirect_cost + 1e-10 {
return false;
}
}
}
}
true
}
}
pub type Path = Vec<usize>;
pub type Solution = (f64, Vec<usize>);
pub use crate::datastructures::vecmatrix::VecMatrix;
pub use crate::datastructures::nalgebra::NAMatrix;
#[derive(Default, Clone, Copy, Equivalence)]
#[cfg(feature = "mpi")]
pub struct MPICostRank(pub f64, pub mpi::topology::Rank);
#[derive(Default, Clone, Copy, Equivalence)]
#[cfg(feature = "mpi")]
pub struct MPICostPath(pub f64, pub [usize; 3]);
#[cfg(test)]
mod test {
use super::*;
use ::nalgebra::DMatrix;
#[test]
fn test_triangle_inequality_check_fails() {
let graph = NAMatrix(DMatrix::from_row_slice(
3,
3,
&[0., 3., 1., 3., 0., 1., 1., 1., 0.],
));
assert!(!graph.is_metric());
}
#[test]
fn test_triangle_inequality_check_succedes() {
let graph = NAMatrix(DMatrix::from_row_slice(
3,
3,
&[0., 0.3, 0.1, 0.3, 0., 0.2, 0.1, 0.2, 0.],
));
assert!(graph.is_metric());
}
}