problemreductions/rules/
graphpartitioning_qubo.rs1use crate::models::algebraic::QUBO;
8use crate::models::graph::GraphPartitioning;
9use crate::reduction;
10use crate::rules::traits::{ReduceTo, ReductionResult};
11use crate::topology::{Graph, SimpleGraph};
12
13#[derive(Debug, Clone)]
15pub struct ReductionGraphPartitioningToQUBO {
16 target: QUBO<f64>,
17}
18
19impl ReductionResult for ReductionGraphPartitioningToQUBO {
20 type Source = GraphPartitioning<SimpleGraph>;
21 type Target = QUBO<f64>;
22
23 fn target_problem(&self) -> &Self::Target {
24 &self.target
25 }
26
27 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
28 target_solution.to_vec()
29 }
30}
31
32#[reduction(overhead = { num_vars = "num_vertices" })]
33impl ReduceTo<QUBO<f64>> for GraphPartitioning<SimpleGraph> {
34 type Result = ReductionGraphPartitioningToQUBO;
35
36 fn reduce_to(&self) -> Self::Result {
37 let n = self.num_vertices();
38 let penalty = self.num_edges() as f64 + 1.0;
39 let mut matrix = vec![vec![0.0f64; n]; n];
40 let mut degrees = vec![0usize; n];
41 let edges = self.graph().edges();
42
43 for &(u, v) in &edges {
44 degrees[u] += 1;
45 degrees[v] += 1;
46 }
47
48 for (i, row) in matrix.iter_mut().enumerate() {
49 row[i] = degrees[i] as f64 + penalty * (1.0 - n as f64);
50 for value in row.iter_mut().skip(i + 1) {
51 *value = 2.0 * penalty;
52 }
53 }
54
55 for (u, v) in edges {
56 let (lo, hi) = if u < v { (u, v) } else { (v, u) };
57 matrix[lo][hi] -= 2.0;
58 }
59
60 ReductionGraphPartitioningToQUBO {
61 target: QUBO::from_matrix(matrix),
62 }
63 }
64}
65
66#[cfg(feature = "example-db")]
67pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
68 use crate::export::SolutionPair;
69
70 vec![crate::example_db::specs::RuleExampleSpec {
71 id: "graphpartitioning_to_qubo",
72 build: || {
73 crate::example_db::specs::rule_example_with_witness::<_, QUBO<f64>>(
74 GraphPartitioning::new(SimpleGraph::new(
75 6,
76 vec![
77 (0, 1),
78 (0, 2),
79 (1, 2),
80 (1, 3),
81 (2, 3),
82 (2, 4),
83 (3, 4),
84 (3, 5),
85 (4, 5),
86 ],
87 )),
88 SolutionPair {
89 source_config: vec![0, 0, 0, 1, 1, 1],
90 target_config: vec![0, 0, 0, 1, 1, 1],
91 },
92 )
93 },
94 }]
95}
96
97#[cfg(test)]
98#[path = "../unit_tests/rules/graphpartitioning_qubo.rs"]
99mod tests;