problemreductions/rules/
maximummatching_ilp.rs1use crate::models::algebraic::{LinearConstraint, ObjectiveSense, ILP};
10use crate::models::graph::MaximumMatching;
11use crate::reduction;
12use crate::rules::traits::{ReduceTo, ReductionResult};
13use crate::topology::{Graph, SimpleGraph};
14
15#[derive(Debug, Clone)]
22pub struct ReductionMatchingToILP {
23 target: ILP<bool>,
24}
25
26impl ReductionResult for ReductionMatchingToILP {
27 type Source = MaximumMatching<SimpleGraph, i32>;
28 type Target = ILP<bool>;
29
30 fn target_problem(&self) -> &ILP<bool> {
31 &self.target
32 }
33
34 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
39 target_solution.to_vec()
40 }
41}
42
43#[reduction(
44 overhead = {
45 num_vars = "num_edges",
46 num_constraints = "num_vertices",
47 }
48)]
49impl ReduceTo<ILP<bool>> for MaximumMatching<SimpleGraph, i32> {
50 type Result = ReductionMatchingToILP;
51
52 fn reduce_to(&self) -> Self::Result {
53 let num_vars = self.graph().num_edges(); let v2e = self.vertex_to_edges();
58 let constraints: Vec<LinearConstraint> = v2e
59 .into_iter()
60 .filter(|(_, edges)| !edges.is_empty())
61 .map(|(_, edges)| {
62 let terms: Vec<(usize, f64)> = edges.into_iter().map(|e| (e, 1.0)).collect();
63 LinearConstraint::le(terms, 1.0)
64 })
65 .collect();
66
67 let weights = self.weights();
69 let objective: Vec<(usize, f64)> = weights
70 .iter()
71 .enumerate()
72 .map(|(i, &w)| (i, w as f64))
73 .collect();
74
75 let target = ILP::new(num_vars, constraints, objective, ObjectiveSense::Maximize);
76
77 ReductionMatchingToILP { target }
78 }
79}
80
81#[cfg(test)]
82#[path = "../unit_tests/rules/maximummatching_ilp.rs"]
83mod tests;