problemreductions/rules/
maximumindependentset_maximumclique.rs1use crate::models::graph::{MaximumClique, MaximumIndependentSet};
7use crate::reduction;
8use crate::rules::traits::{ReduceTo, ReductionResult};
9use crate::topology::{Graph, SimpleGraph};
10use crate::types::{One, WeightElement};
11
12#[derive(Debug, Clone)]
14pub struct ReductionISToClique<W> {
15 target: MaximumClique<SimpleGraph, W>,
16}
17
18impl<W> ReductionResult for ReductionISToClique<W>
19where
20 W: WeightElement + crate::variant::VariantParam,
21{
22 type Source = MaximumIndependentSet<SimpleGraph, W>;
23 type Target = MaximumClique<SimpleGraph, W>;
24
25 fn target_problem(&self) -> &Self::Target {
26 &self.target
27 }
28
29 fn extract_solution(
32 &self,
33 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
34 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
35 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
36
37 Ok(target_solution.to_vec())
38 }
39}
40
41fn reduce_is_to_clique<W: WeightElement>(
42 src: &MaximumIndependentSet<SimpleGraph, W>,
43) -> ReductionISToClique<W> {
44 let comp_edges = super::graph_helpers::complement_edges(src.graph());
45 let target = MaximumClique::new(
46 SimpleGraph::new(src.graph().num_vertices(), comp_edges),
47 src.weights().to_vec(),
48 );
49 ReductionISToClique { target }
50}
51
52#[reduction(
53 transform = exact {
54 num_vertices = "num_vertices",
55 num_edges = "num_vertices * (num_vertices - 1) / 2 - num_edges",
56 }
57)]
58impl ReduceTo<MaximumClique<SimpleGraph, i64>> for MaximumIndependentSet<SimpleGraph, i64> {
59 type Result = ReductionISToClique<i64>;
60
61 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
62 Ok(reduce_is_to_clique(self))
63 }
64}
65
66#[reduction(
67 transform = exact {
68 num_vertices = "num_vertices",
69 num_edges = "num_vertices * (num_vertices - 1) / 2 - num_edges",
70 }
71)]
72impl ReduceTo<MaximumClique<SimpleGraph, One>> for MaximumIndependentSet<SimpleGraph, One> {
73 type Result = ReductionISToClique<One>;
74
75 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
76 Ok(reduce_is_to_clique(self))
77 }
78}
79
80#[cfg(feature = "example-db")]
81pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
82 use crate::export::SolutionPair;
83
84 vec![
85 crate::example_db::specs::RuleExampleSpec {
86 id: "weighted_maximumindependentset_to_maximumclique",
87 build: || {
88 let source = MaximumIndependentSet::new(
89 SimpleGraph::new(5, vec![(0, 1), (1, 2), (2, 3), (3, 4)]),
90 vec![1i64; 5],
91 );
92 crate::example_db::specs::rule_example_with_witness::<
93 _,
94 MaximumClique<SimpleGraph, i64>,
95 >(
96 source,
97 SolutionPair {
98 source_config: serde_json::json!(vec![true, false, true, false, true]),
99 target_config: serde_json::json!(vec![true, false, true, false, true]),
100 },
101 )
102 },
103 },
104 crate::example_db::specs::RuleExampleSpec {
105 id: "cardinality_maximumindependentset_to_maximumclique",
106 build: || {
107 let source = MaximumIndependentSet::new(
108 SimpleGraph::new(5, vec![(0, 1), (1, 2), (2, 3), (3, 4)]),
109 vec![One; 5],
110 );
111 crate::example_db::specs::rule_example_with_witness::<
112 _,
113 MaximumClique<SimpleGraph, One>,
114 >(
115 source,
116 SolutionPair {
117 source_config: serde_json::json!(vec![true, false, true, false, true]),
118 target_config: serde_json::json!(vec![true, false, true, false, true]),
119 },
120 )
121 },
122 },
123 ]
124}
125
126#[cfg(test)]
127#[path = "../unit_tests/rules/maximumindependentset_maximumclique.rs"]
128mod tests;