problemreductions/rules/
maximumclique_ilp.rs1use crate::models::algebraic::{LinearConstraint, ObjectiveSense, ILP};
10use crate::models::graph::MaximumClique;
11use crate::reduction;
12use crate::rules::traits::{ReduceTo, ReductionResult};
13use crate::topology::{Graph, SimpleGraph};
14
15#[derive(Debug, Clone)]
22pub struct ReductionCliqueToILP {
23 target: ILP<bool>,
24}
25
26impl ReductionResult for ReductionCliqueToILP {
27 type Source = MaximumClique<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_vertices",
46 num_constraints = "num_vertices^2",
47 }
48)]
49impl ReduceTo<ILP<bool>> for MaximumClique<SimpleGraph, i32> {
50 type Result = ReductionCliqueToILP;
51
52 fn reduce_to(&self) -> Self::Result {
53 let num_vars = self.graph().num_vertices();
54
55 let mut constraints: Vec<LinearConstraint> = Vec::new();
59 for u in 0..num_vars {
60 for v in (u + 1)..num_vars {
61 if !self.graph().has_edge(u, v) {
62 constraints.push(LinearConstraint::le(vec![(u, 1.0), (v, 1.0)], 1.0));
63 }
64 }
65 }
66
67 let objective: Vec<(usize, f64)> = self
69 .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 ReductionCliqueToILP { target }
78 }
79}
80
81#[cfg(test)]
82#[path = "../unit_tests/rules/maximumclique_ilp.rs"]
83mod tests;