problemreductions/rules/
maximumindependentset_triangular.rs1use crate::models::graph::MaximumIndependentSet;
8use crate::reduction;
9use crate::rules::traits::{ReduceTo, ReductionResult};
10use crate::rules::unitdiskmapping::ksg;
11use crate::rules::unitdiskmapping::triangular;
12use crate::topology::{Graph, SimpleGraph, TriangularSubgraph};
13use crate::types::One;
14
15#[derive(Debug, Clone)]
17pub struct ReductionISSimpleToTriangular {
18 target: MaximumIndependentSet<TriangularSubgraph, i64>,
19 mapping_result: ksg::MappingResult<ksg::KsgTapeEntry>,
20}
21
22impl ReductionResult for ReductionISSimpleToTriangular {
23 type Source = MaximumIndependentSet<SimpleGraph, One>;
24 type Target = MaximumIndependentSet<TriangularSubgraph, i64>;
25
26 fn target_problem(&self) -> &Self::Target {
27 &self.target
28 }
29
30 fn extract_solution(
31 &self,
32 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
33 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
34 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
35
36 let encoded = crate::config::bits_to_config(target_solution);
37 let mapped = triangular::map_config_back(&self.mapping_result, &encoded)?;
38 Ok(crate::config::config_to_bits(&mapped))
39 }
40}
41
42#[reduction(
43 transform = upper_bound {
44 num_vertices = "36 * num_vertices^2 + 36 * num_vertices",
45 num_edges = "108 * num_vertices^2 + 108 * num_vertices",
46 }
47)]
48impl ReduceTo<MaximumIndependentSet<TriangularSubgraph, i64>>
49 for MaximumIndependentSet<SimpleGraph, One>
50{
51 type Result = ReductionISSimpleToTriangular;
52
53 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
54 let n = self.graph().num_vertices();
55 let edges = self.graph().edges();
56 let mapping_error = |error: crate::rules::ReductionError| {
57 error.for_reduction::<Self, MaximumIndependentSet<TriangularSubgraph, i64>>()
58 };
59 let result = triangular::map_weighted(n, &edges).map_err(&mapping_error)?;
60 let weights = triangular::map_unit_weights(&result).map_err(mapping_error)?;
61 let grid = result.to_triangular_subgraph();
62 let target = MaximumIndependentSet::new(grid, weights);
63 Ok(ReductionISSimpleToTriangular {
64 target,
65 mapping_result: result,
66 })
67 }
68}
69
70#[cfg(test)]
71#[path = "../unit_tests/rules/maximumindependentset_triangular.rs"]
72mod tests;