From bd8728ce2f26ce94d03a3c09251dfe722cd285f5 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Sun, 7 Apr 2019 16:46:54 +0200 Subject: [PATCH] Fix infinte loop in case Matrix is not solvable. --- src/lib.rs | 68 ++++++++++++++++++++++++++++++-------------- src/weight_matrix.rs | 5 ---- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b6fca92..c5e2eb7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -118,7 +118,7 @@ where }); if count >= n { - debug_assert!(count == n); + assert!(count == n); Step::Done } else { Step::Step4(Some(count)) @@ -228,35 +228,34 @@ where let n = c.n(); assert!(cov.n() == n); - // Find the smallest uncovered value in the matrix + // Find the smallest, valid uncovered value in the matrix let mut min = None; cov.iter_uncovered_row_column_order(|pos| { let elm = c.element_at(pos); - min = Some(match min { - Some(m) => { - if m < elm { - m - } else { - elm - } - } - None => elm, - }); + if elm.is_valid() { + min = Some(match min { + Some(m) if m < elm => m, + _ => elm, + }); + } }); - let minval = min.unwrap(); - for row in 0..n { - if cov.is_row_covered(row) { - c.add_row(row, minval); + if let Some(minval) = min { + for row in 0..n { + if cov.is_row_covered(row) { + c.add_row(row, minval); + } } - } - for column in 0..n { - if !cov.is_column_covered(column) { - c.sub_column(column, minval); + for column in 0..n { + if !cov.is_column_covered(column) { + c.sub_column(column, minval); + } } - } - return Step::Step4(None); + Step::Step4(None) + } else { + Step::Failure(Error::MatrixNotSolvable) + } } pub fn solve_assignment(weights: &mut W) -> Result, Error> @@ -783,3 +782,28 @@ fn test_unsolvable() { let res = solve_assignment(&mut weights); assert_eq!(Err(Error::MatrixNotSolvable), res); } + +#[test] +fn test_unsolvable2() { + use std::f32; + const N: usize = 3; + + let c = vec![ + // row 0 + f32::INFINITY, + 400.0, // (a) + f32::INFINITY, + // row 1 + f32::INFINITY, + 400.0, // (a') collision! + f32::INFINITY, + // row 2 + 400.0, + 250.0, + 0.0, + ]; + + let mut weights: WeightMatrix = WeightMatrix::from_row_vec(N, c.clone()); + let res = solve_assignment(&mut weights); + assert_eq!(Err(Error::MatrixNotSolvable), res); +} diff --git a/src/weight_matrix.rs b/src/weight_matrix.rs index ff58641..de3fe00 100644 --- a/src/weight_matrix.rs +++ b/src/weight_matrix.rs @@ -47,11 +47,6 @@ impl Weights for WeightMatrix { return false; } } - for column in self.c.gencolumns() { - if column.iter().all(|c| !c.is_valid()) { - return false; - } - } true } }