Fix infinte loop in case Matrix is not solvable.
This commit is contained in:
parent
7e07dd5941
commit
bd8728ce2f
48
src/lib.rs
48
src/lib.rs
@ -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);
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user