use alloc::vec::Vec;
mod partial_assignment;
use partial_assignment::PartialAssignment;
use crate::traits::SparseMatrix2D;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum HopcroftKarpError {
#[error("The provided distance type is not large enough for this graph.")]
InsufficientDistanceType,
}
pub trait HopcroftKarp: SparseMatrix2D {
#[allow(clippy::type_complexity)]
#[inline]
fn hopcroft_karp(&self) -> Result<Vec<(Self::RowIndex, Self::ColumnIndex)>, HopcroftKarpError> {
let mut partial_assignment: PartialAssignment<'_, Self, u32> =
PartialAssignment::from(self);
while partial_assignment.bfs()? {
for left_node_id in self.row_indices() {
if !partial_assignment.has_successor(left_node_id) {
partial_assignment.dfs(Some(left_node_id));
}
}
}
Ok(partial_assignment.into())
}
}
impl<M> HopcroftKarp for M where M: SparseMatrix2D {}