problemreductions/rules/
partitionintopathsoflength2_boundedcomponentspanningforest.rs1use crate::models::graph::{BoundedComponentSpanningForest, PartitionIntoPathsOfLength2};
14use crate::reduction;
15use crate::rules::traits::{ReduceTo, ReductionResult};
16use crate::topology::{Graph, SimpleGraph};
17
18#[derive(Debug, Clone)]
20pub struct ReductionPPL2ToBCSF {
21 target: BoundedComponentSpanningForest<SimpleGraph, i64>,
22}
23
24impl ReductionResult for ReductionPPL2ToBCSF {
25 type Source = PartitionIntoPathsOfLength2<SimpleGraph>;
26 type Target = BoundedComponentSpanningForest<SimpleGraph, i64>;
27
28 fn target_problem(&self) -> &Self::Target {
29 &self.target
30 }
31
32 fn extract_solution(
37 &self,
38 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
39 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
40 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
41
42 Ok(target_solution.to_vec())
43 }
44}
45
46#[reduction(
47 transform = exact {
48 num_vertices = "num_vertices",
49 num_edges = "num_edges",
50 max_components = "num_vertices / 3",
51 }
52)]
53impl ReduceTo<BoundedComponentSpanningForest<SimpleGraph, i64>>
54 for PartitionIntoPathsOfLength2<SimpleGraph>
55{
56 type Result = ReductionPPL2ToBCSF;
57
58 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
59 let n = self.num_vertices();
60 let q = n / 3;
61
62 let max_components = if q == 0 { 1 } else { q };
64
65 let target = BoundedComponentSpanningForest::new(
66 SimpleGraph::new(n, self.graph().edges()),
67 vec![1i64; n], max_components, 3, );
71
72 Ok(ReductionPPL2ToBCSF { target })
73 }
74}
75
76#[cfg(feature = "example-db")]
77pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
78 use crate::export::SolutionPair;
79
80 vec![crate::example_db::specs::RuleExampleSpec {
81 id: "partitionintopathsoflength2_to_boundedcomponentspanningforest",
82 build: || {
83 let source = PartitionIntoPathsOfLength2::new(SimpleGraph::new(
85 6,
86 vec![(0, 1), (1, 2), (3, 4), (4, 5)],
87 ));
88 crate::example_db::specs::rule_example_with_witness::<
89 _,
90 BoundedComponentSpanningForest<SimpleGraph, i64>,
91 >(
92 source,
93 SolutionPair {
94 source_config: serde_json::json!(vec![0, 0, 0, 1, 1, 1]),
95 target_config: serde_json::json!(vec![0, 0, 0, 1, 1, 1]),
96 },
97 )
98 },
99 }]
100}
101
102#[cfg(test)]
103#[path = "../unit_tests/rules/partitionintopathsoflength2_boundedcomponentspanningforest.rs"]
104mod tests;