///|
/// Group labels index capacities; absent groups and zero capacities are valid.
pub fn Matroid::partition(
groups : Array[Int32],
capacities : Array[Int32],
) -> Matroid raise MatroidError {
check_size(groups.length())
if capacities.length() > 64 {
raise InvalidInput("too many groups")
}
for c in capacities {
if c < 0 || c > 64 {
raise InvalidInput("invalid capacity")
}
}
for g in groups {
if g < 0 || g >= capacities.length() {
raise InvalidInput("unknown group")
}
}
let labels = groups.copy()
let caps = capacities.copy()
{
size: labels.length(),
model: "partition",
evaluate: xs => {
let counts = Array::make(caps.length(), 0)
for e in xs {
counts[labels[e]] = counts[labels[e]] + 1
}
let mut rank = 0
for g = 0; g < caps.length(); g = g + 1 {
rank = rank + counts[g].min(caps[g])
}
rank
},
}
}