Fix infinte loop in case Matrix is not solvable.

This commit is contained in:
Michael Neumann 2019-04-07 16:46:54 +02:00
parent 7e07dd5941
commit bd8728ce2f
2 changed files with 46 additions and 27 deletions

View File

@ -118,7 +118,7 @@ where
}); });
if count >= n { if count >= n {
debug_assert!(count == n); assert!(count == n);
Step::Done Step::Done
} else { } else {
Step::Step4(Some(count)) Step::Step4(Some(count))
@ -228,23 +228,19 @@ where
let n = c.n(); let n = c.n();
assert!(cov.n() == 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; let mut min = None;
cov.iter_uncovered_row_column_order(|pos| { cov.iter_uncovered_row_column_order(|pos| {
let elm = c.element_at(pos); let elm = c.element_at(pos);
if elm.is_valid() {
min = Some(match min { min = Some(match min {
Some(m) => { Some(m) if m < elm => m,
if m < elm { _ => elm,
m
} else {
elm
}
}
None => elm,
}); });
}
}); });
let minval = min.unwrap(); if let Some(minval) = min {
for row in 0..n { for row in 0..n {
if cov.is_row_covered(row) { if cov.is_row_covered(row) {
c.add_row(row, minval); c.add_row(row, minval);
@ -256,7 +252,10 @@ where
} }
} }
return Step::Step4(None); Step::Step4(None)
} else {
Step::Failure(Error::MatrixNotSolvable)
}
} }
pub fn solve_assignment<W>(weights: &mut W) -> Result<Vec<Position>, Error> pub fn solve_assignment<W>(weights: &mut W) -> Result<Vec<Position>, Error>
@ -783,3 +782,28 @@ fn test_unsolvable() {
let res = solve_assignment(&mut weights); let res = solve_assignment(&mut weights);
assert_eq!(Err(Error::MatrixNotSolvable), res); 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<f32> = WeightMatrix::from_row_vec(N, c.clone());
let res = solve_assignment(&mut weights);
assert_eq!(Err(Error::MatrixNotSolvable), res);
}

View File

@ -47,11 +47,6 @@ impl<T: WeightNum> Weights for WeightMatrix<T> {
return false; return false;
} }
} }
for column in self.c.gencolumns() {
if column.iter().all(|c| !c.is_valid()) {
return false;
}
}
true true
} }
} }