problemreductions/rules/
maximumindependentset_maximumsetpacking.rs1use crate::models::graph::MaximumIndependentSet;
7use crate::models::set::MaximumSetPacking;
8use crate::reduction;
9use crate::rules::traits::{ReduceTo, ReductionResult};
10use crate::topology::{Graph, SimpleGraph};
11use crate::types::{One, WeightElement};
12use std::collections::HashSet;
13
14#[derive(Debug, Clone)]
16pub struct ReductionISToSP<W> {
17 target: MaximumSetPacking<W>,
18}
19
20impl<W> ReductionResult for ReductionISToSP<W>
21where
22 W: WeightElement + crate::variant::VariantParam,
23{
24 type Source = MaximumIndependentSet<SimpleGraph, W>;
25 type Target = MaximumSetPacking<W>;
26
27 fn target_problem(&self) -> &Self::Target {
28 &self.target
29 }
30
31 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
33 target_solution.to_vec()
34 }
35}
36
37macro_rules! impl_is_to_sp {
38 ($W:ty) => {
39 #[reduction(overhead = { num_sets = "num_vertices", universe_size = "num_edges" })]
40 impl ReduceTo<MaximumSetPacking<$W>> for MaximumIndependentSet<SimpleGraph, $W> {
41 type Result = ReductionISToSP<$W>;
42
43 fn reduce_to(&self) -> Self::Result {
44 let edges = self.graph().edges();
45 let n = self.graph().num_vertices();
46
47 let mut sets: Vec<Vec<usize>> = vec![Vec::new(); n];
49 for (edge_idx, &(u, v)) in edges.iter().enumerate() {
50 sets[u].push(edge_idx);
51 sets[v].push(edge_idx);
52 }
53
54 let target = MaximumSetPacking::with_weights(sets, self.weights().to_vec());
55
56 ReductionISToSP { target }
57 }
58 }
59 };
60}
61
62impl_is_to_sp!(i32);
63impl_is_to_sp!(One);
64
65#[derive(Debug, Clone)]
67pub struct ReductionSPToIS<W> {
68 target: MaximumIndependentSet<SimpleGraph, W>,
69}
70
71impl<W> ReductionResult for ReductionSPToIS<W>
72where
73 W: WeightElement + crate::variant::VariantParam,
74{
75 type Source = MaximumSetPacking<W>;
76 type Target = MaximumIndependentSet<SimpleGraph, W>;
77
78 fn target_problem(&self) -> &Self::Target {
79 &self.target
80 }
81
82 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
84 target_solution.to_vec()
85 }
86}
87
88macro_rules! impl_sp_to_is {
89 ($W:ty) => {
90 #[reduction(overhead = { num_vertices = "num_sets", num_edges = "num_sets^2" })]
91 impl ReduceTo<MaximumIndependentSet<SimpleGraph, $W>> for MaximumSetPacking<$W> {
92 type Result = ReductionSPToIS<$W>;
93
94 fn reduce_to(&self) -> Self::Result {
95 let sets = self.sets();
96 let n = sets.len();
97
98 let mut edges = Vec::new();
100 for (i, set_i_vec) in sets.iter().enumerate() {
101 let set_i: HashSet<_> = set_i_vec.iter().collect();
102 for (j, set_j) in sets.iter().enumerate().skip(i + 1) {
103 if set_j.iter().any(|elem| set_i.contains(elem)) {
105 edges.push((i, j));
106 }
107 }
108 }
109
110 let target = MaximumIndependentSet::new(
111 SimpleGraph::new(n, edges),
112 self.weights_ref().clone(),
113 );
114
115 ReductionSPToIS { target }
116 }
117 }
118 };
119}
120
121impl_sp_to_is!(i32);
122impl_sp_to_is!(One);
123
124#[cfg(test)]
125#[path = "../unit_tests/rules/maximumindependentset_maximumsetpacking.rs"]
126mod tests;