use alloc::{vec, vec::Vec};
mod inner;
use core::fmt::Debug;
use inner::HungarianInner;
use super::{
LAPError,
lap_error::{
sparse_padded_lap_impl, validate_lap_entry_costs, validate_sparse_lap_entry_costs,
},
};
use crate::{
impls::PaddedMatrix2D,
traits::{DenseValuedMatrix2D, Finite, Number, SparseValuedMatrix2D, TotalOrd, TryFromUsize},
};
pub trait Hungarian: DenseValuedMatrix2D + Sized
where
Self::Value: Number + Finite + TotalOrd,
Self::ColumnIndex: TryFromUsize,
{
#[allow(clippy::type_complexity)]
#[inline]
fn hungarian(
&self,
max_cost: Self::Value,
) -> Result<Vec<(Self::RowIndex, Self::ColumnIndex)>, LAPError>
where
<Self::ColumnIndex as TryFrom<usize>>::Error: Debug,
{
validate_lap_entry_costs(max_cost)?;
let mut inner = HungarianInner::new(self, max_cost)?;
inner.augmentation();
Ok(inner.into_assignments())
}
}
impl<M: DenseValuedMatrix2D> Hungarian for M
where
M::Value: Number + Finite + TotalOrd,
M::ColumnIndex: TryFromUsize,
{
}
pub trait SparseHungarian: SparseValuedMatrix2D + Sized
where
Self::Value: Number,
Self::RowIndex: TryFromUsize,
Self::ColumnIndex: TryFromUsize,
{
#[allow(clippy::type_complexity)]
#[inline]
fn sparse_hungarian(
&self,
padding_cost: Self::Value,
max_cost: Self::Value,
) -> Result<Vec<(Self::RowIndex, Self::ColumnIndex)>, LAPError>
where
Self::Value: Finite + TotalOrd,
<<Self as crate::traits::Matrix2D>::ColumnIndex as TryFrom<usize>>::Error: Debug,
{
sparse_padded_lap_impl!(self, padding_cost, max_cost, hungarian)
}
}
impl<M: SparseValuedMatrix2D> SparseHungarian for M
where
M::Value: Number,
M::RowIndex: TryFromUsize,
M::ColumnIndex: TryFromUsize,
{
}