problemreductions/models/graph/
minimum_metric_dimension.rs1use crate::registry::{FieldInfo, ProblemSchemaEntry, VariantDimension};
8use crate::topology::{Graph, SimpleGraph};
9use crate::traits::Problem;
10use crate::types::Min;
11use serde::{Deserialize, Serialize};
12use std::collections::VecDeque;
13
14inventory::submit! {
15 ProblemSchemaEntry {
16 name: "MinimumMetricDimension",
17 display_name: "Minimum Metric Dimension",
18 aliases: &[],
19 dimensions: &[
20 VariantDimension::new("graph", "SimpleGraph", &["SimpleGraph"]),
21 ],
22 module_path: module_path!(),
23 description: "Find minimum resolving set of a graph",
24 fields: &[
25 FieldInfo { name: "graph", type_name: "G", description: "The underlying graph G=(V,E)" },
26 ],
27 }
28}
29
30pub fn bfs_distances<G: Graph>(graph: &G, source: usize) -> Vec<usize> {
35 let n = graph.num_vertices();
36 let mut dist = vec![usize::MAX; n];
37 dist[source] = 0;
38 let mut queue = VecDeque::new();
39 queue.push_back(source);
40 while let Some(u) = queue.pop_front() {
41 for v in graph.neighbors(u) {
42 if dist[v] == usize::MAX {
43 dist[v] = dist[u] + 1;
44 queue.push_back(v);
45 }
46 }
47 }
48 dist
49}
50
51#[derive(Debug, Clone, Serialize)]
78pub struct MinimumMetricDimension<G> {
79 graph: G,
81 #[serde(skip)]
83 dist_matrix: Vec<Vec<usize>>,
84}
85
86impl<'de, G: Graph + Deserialize<'de>> Deserialize<'de> for MinimumMetricDimension<G> {
87 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
88 where
89 D: serde::Deserializer<'de>,
90 {
91 #[derive(Deserialize)]
92 struct Helper<G> {
93 graph: G,
94 }
95 let helper = Helper::<G>::deserialize(deserializer)?;
96 Ok(Self::new(helper.graph))
97 }
98}
99
100impl<G: Graph> MinimumMetricDimension<G> {
101 pub fn new(graph: G) -> Self {
103 let n = graph.num_vertices();
104 let dist_matrix = (0..n).map(|v| bfs_distances(&graph, v)).collect();
105 Self { graph, dist_matrix }
106 }
107
108 pub fn graph(&self) -> &G {
110 &self.graph
111 }
112
113 pub fn num_vertices(&self) -> usize {
115 self.graph.num_vertices()
116 }
117
118 pub fn num_edges(&self) -> usize {
120 self.graph.num_edges()
121 }
122
123 pub fn is_resolving(&self, config: &[usize]) -> bool {
128 let n = self.graph.num_vertices();
129 let selected: Vec<usize> = (0..n).filter(|&i| config[i] == 1).collect();
130 if selected.is_empty() {
131 return false;
132 }
133
134 for u in 0..n {
137 for v in (u + 1)..n {
138 let all_same = selected
139 .iter()
140 .all(|&w| self.dist_matrix[w][u] == self.dist_matrix[w][v]);
141 if all_same {
142 return false;
143 }
144 }
145 }
146
147 true
148 }
149}
150
151impl<G> Problem for MinimumMetricDimension<G>
152where
153 G: Graph + crate::variant::VariantParam,
154{
155 const NAME: &'static str = "MinimumMetricDimension";
156 type Value = Min<usize>;
157
158 fn variant() -> Vec<(&'static str, &'static str)> {
159 crate::variant_params![G]
160 }
161
162 fn dims(&self) -> Vec<usize> {
163 vec![2; self.graph.num_vertices()]
164 }
165
166 fn evaluate(&self, config: &[usize]) -> Min<usize> {
167 if !self.is_resolving(config) {
168 return Min(None);
169 }
170 let count = config.iter().filter(|&&x| x == 1).count();
171 Min(Some(count))
172 }
173}
174
175crate::declare_variants! {
176 default MinimumMetricDimension<SimpleGraph> => "2^num_vertices",
177}
178
179#[cfg(feature = "example-db")]
180pub(crate) fn canonical_model_example_specs() -> Vec<crate::example_db::specs::ModelExampleSpec> {
181 vec![crate::example_db::specs::ModelExampleSpec {
182 id: "minimum_metric_dimension_simplegraph",
183 instance: Box::new(MinimumMetricDimension::new(SimpleGraph::new(
184 5,
185 vec![(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (3, 4)],
186 ))),
187 optimal_config: vec![1, 1, 0, 0, 0],
188 optimal_value: serde_json::json!(2),
189 }]
190}
191
192#[cfg(test)]
193#[path = "../../unit_tests/models/graph/minimum_metric_dimension.rs"]
194mod tests;