problemreductions/models/graph/
graph_partitioning.rs1use crate::registry::{FieldInfo, ProblemSchemaEntry};
7use crate::topology::{Graph, SimpleGraph};
8use crate::traits::{OptimizationProblem, Problem};
9use crate::types::{Direction, SolutionSize};
10use serde::{Deserialize, Serialize};
11
12inventory::submit! {
13 ProblemSchemaEntry {
14 name: "GraphPartitioning",
15 module_path: module_path!(),
16 description: "Find minimum cut balanced bisection of a graph",
17 fields: &[
18 FieldInfo { name: "graph", type_name: "G", description: "The undirected graph G=(V,E)" },
19 ],
20 }
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct GraphPartitioning<G> {
56 graph: G,
58}
59
60impl<G: Graph> GraphPartitioning<G> {
61 pub fn new(graph: G) -> Self {
66 Self { graph }
67 }
68
69 pub fn graph(&self) -> &G {
71 &self.graph
72 }
73
74 pub fn num_vertices(&self) -> usize {
76 self.graph.num_vertices()
77 }
78
79 pub fn num_edges(&self) -> usize {
81 self.graph.num_edges()
82 }
83}
84
85impl<G> Problem for GraphPartitioning<G>
86where
87 G: Graph + crate::variant::VariantParam,
88{
89 const NAME: &'static str = "GraphPartitioning";
90 type Metric = SolutionSize<i32>;
91
92 fn variant() -> Vec<(&'static str, &'static str)> {
93 crate::variant_params![G]
94 }
95
96 fn dims(&self) -> Vec<usize> {
97 vec![2; self.graph.num_vertices()]
98 }
99
100 fn evaluate(&self, config: &[usize]) -> SolutionSize<i32> {
101 let n = self.graph.num_vertices();
102 if config.len() != n {
103 return SolutionSize::Invalid;
104 }
105 if !n.is_multiple_of(2) {
107 return SolutionSize::Invalid;
108 }
109 let count_ones = config.iter().filter(|&&x| x == 1).count();
111 if count_ones != n / 2 {
112 return SolutionSize::Invalid;
113 }
114 let mut cut = 0i32;
116 for (u, v) in self.graph.edges() {
117 if config[u] != config[v] {
118 cut += 1;
119 }
120 }
121 SolutionSize::Valid(cut)
122 }
123}
124
125impl<G> OptimizationProblem for GraphPartitioning<G>
126where
127 G: Graph + crate::variant::VariantParam,
128{
129 type Value = i32;
130
131 fn direction(&self) -> Direction {
132 Direction::Minimize
133 }
134}
135
136crate::declare_variants! {
137 GraphPartitioning<SimpleGraph> => "2^num_vertices",
138}
139
140#[cfg(test)]
141#[path = "../../unit_tests/models/graph/graph_partitioning.rs"]
142mod tests;