graph_simulation/algorithm/bounded.rs
1use graph_base::interfaces::graph::{Adjacency, AdjacencyInv, Degree, Directed, Graph};
2use graph_base::interfaces::labeled::Labeled;
3
4use std::collections::{HashSet, HashMap};
5
6pub trait BoundedSimulation<'a> {
7 type Node: 'a;
8
9 fn get_bounded_simulation(&'a self, other: &'a Self) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>>;
10}
11
12pub trait Bounded<'a>: Graph<'a> {
13 fn get_bound(&'a self, u: &'a Self::Node, v: &'a Self::Node) -> usize;
14}
15
16impl<'a, 'b, T> BoundedSimulation<'a> for T
17where
18 T: Graph<'a> + Bounded<'a> + Degree<'a> + Labeled<'a> + Adjacency<'a> + Degree<'a> + AdjacencyInv<'a> + Directed + 'b,
19 T::Node: 'a, T::Edge: 'a,
20{
21 type Node = T::Node;
22
23 fn get_bounded_simulation(&'a self, other: &'a Self) -> HashMap<&'a Self::Node, HashSet<&'a Self::Node>> {
24
25 let adj_self = self.get_adj();
26 let adj_other = other.get_adj();
27 let adj_self_inv = self.get_adj_inv();
28 // let adj_other_inv = other.get_adj_inv();
29
30
31
32 // anc(get_bound(u_prime, u), u_prime, v) that returns v_prime in anc if:
33 // 1. label_same(u_prime, v_prime)
34 // 2. len(v_prime/.../v) <= get_bound(u_prime, u)
35 // dec(get_bound(u, u_prime), u_prime, v) that returns v_prime in dec if:
36 // 1. label_same(u_prime, v_prime)
37 // 2. len(v/.../v_prime) <= get_bound(u, u_prime)
38 // they are HashMap<(usize, &Node, &Node), HashSet<&Node>>
39
40 // We firstly compute the distance matrix M of (V_other, E_other)
41 let mut distance: HashMap<(&T::Node, &T::Node), usize> = HashMap::new();
42 for u in other.nodes() {
43 let mut queue: Vec<(&T::Node, usize)> = vec![(u, 0)];
44 let mut visited: HashSet<&T::Node> = HashSet::new();
45 visited.insert(u);
46 while !queue.is_empty() {
47 let (current, dist) = queue.remove(0);
48 distance.insert((u, current), dist);
49 for neighbor in other.get_post(&adj_other, current) {
50 if !visited.contains(neighbor) {
51 visited.insert(neighbor);
52 queue.push((neighbor, dist + 1));
53 }
54 }
55 }
56 }
57
58 let mut anc: HashMap<(usize, &T::Node, &T::Node), HashSet<&T::Node>> = HashMap::new();
59 let mut dec: HashMap<(usize, &T::Node, &T::Node), HashSet<&T::Node>> = HashMap::new();
60
61
62 // Then we compute anc and dec based on distance matrix
63
64 // compute anc
65 // anc(bound, u_prime, v) := {v_prime | label_same(u_prime, v_prime) and distance(v_prime, v) <= bound}
66 // where u_prime is node from self, v_prime and v are nodes from other
67 for u_prime in self.nodes() {
68 for u in self.get_post(&adj_self, u_prime) {
69 let bound = self.get_bound(u_prime, u);
70 for v in other.nodes() {
71 let mut anc_set: HashSet<&T::Node> = HashSet::new();
72 for v_prime in other.nodes() {
73 if self.label_same(u_prime, v_prime) {
74 if let Some(&dist) = distance.get(&(v_prime, v)) {
75 if dist <= bound {
76 anc_set.insert(v_prime);
77 }
78 }
79 }
80 }
81 anc.insert((bound, u_prime, v), anc_set);
82 }
83 }
84 }
85
86 // compute dec
87 // dec(bound, u_prime, v) := {v_prime | label_same(u_prime, v_prime) and distance(v, v_prime) <= bound}
88 // where u_prime is node from self, v_prime and v are nodes from other
89 // We need to compute dec for all possible (u', u) pairs to get all required bounds
90 for u in self.nodes() {
91 for u_prime in self.get_post(&adj_self, u) {
92 let bound = self.get_bound(u, u_prime);
93 for v in other.nodes() {
94 let mut dec_set: HashSet<&T::Node> = HashSet::new();
95 for v_prime in other.nodes() {
96 if self.label_same(u_prime, v_prime) {
97 if let Some(&dist) = distance.get(&(v, v_prime)) {
98 if dist <= bound {
99 dec_set.insert(v_prime);
100 }
101 }
102 }
103 }
104 dec.insert((bound, u_prime, v), dec_set);
105 }
106 }
107 }
108
109 let self_out_degree = self.get_out_degree();
110 let other_out_degree = other.get_out_degree();
111
112 // sim(u) := {v | v in V_other and label_same(u, v) and out_degree(v) != 0 if out_degree(u) != 0}
113 let mut sim = HashMap::new();
114 for u in self.nodes() {
115 let mut candidates: HashSet<&'a T::Node> = HashSet::new();
116 for v in other.nodes() {
117 if self.label_same(&u, v) {
118 if self.out_degree(&self_out_degree,&u) != 0 {
119 if other.out_degree(&other_out_degree,&v) != 0 {
120 candidates.insert(v);
121 }
122 } else {
123 candidates.insert(v);
124 }
125 }
126 }
127 sim.insert(u, candidates);
128 }
129
130 // presim(u) := {v | v in V_other and there NOT exists (u_prime, u) in E_self
131 // s.t. ((1) v_prime in sim(u), (2) label_same(u_prime, v), and (3) len(v/.../v_prime) <= get_bound(u_prime, u))}
132 let mut presim = HashMap::new();
133 for u in self.nodes() {
134 let mut candidates: HashSet<&'a T::Node> = HashSet::new();
135 'v_loop: for v in sim.get(&u).unwrap() {
136 if other.out_degree(&other_out_degree, v) == 0 {
137 continue;
138 }
139 // v 在 presim(u) 中,当且仅当:对所有 u' 都不存在这样的 v'
140 // 这里 u' 满足 (u_prime, u) in E_self,即 u' 是 u 的前驱
141 for u_prime in self.get_pre(&adj_self_inv, u) {
142 // 首先检查条件 (2):label_same(u_prime, v)
143 // 如果 v 的标签不等于 u_prime 的标签,则条件 (2) 不满足,v 不可能被排除
144 if !self.label_same(u_prime, v) {
145 continue; // 这个 u_prime 无法排除 v,检查下一个 u_prime
146 }
147
148 let bound = self.get_bound(&u_prime, &u);
149 // 检查:是否存在 v' 满足条件
150 // (1) v' in sim(u)
151 // (2) label_same(u_prime, v) - 已经满足(见上面的检查)
152 // (3) len(v/.../v') <= bound (对应 dec)
153 if let Some(dec_set) = dec.get(&(bound, &u_prime, v)) {
154 // dec_set 包含所有标签为 u_prime 且距离 v 在 bound 内的节点
155 // 检查这些节点是否在 sim(u) 中
156 let has_match = dec_set.iter().any(|v_prime| {
157 sim.get(&u).unwrap().contains(v_prime)
158 });
159 // 如果存在这样的 v',则 v 不在 presim(u) 中
160 if has_match {
161 continue 'v_loop;
162 }
163 }
164 // 如果 dec_set 不存在或为空,则不存在满足条件的 v',继续检查下一个 u'
165 }
166 // 所有 u' 都不存在满足条件的 v',v 在 presim(u) 中
167 candidates.insert(v);
168 }
169 presim.insert(u, candidates);
170 }
171
172 // while (there exists a node u ∈ V_self with premv(u) != ∅) do
173 // for (each (u′, u) ∈ E_self and each z ∈ premv(u) ∩ sim(u′)) do
174 // sim(u′) := sim(u′) \ {z};
175 // if (sim(u′) = ∅) then return ∅;
176 // for each u′′ with (u′′, u′) ∈ E_self do
177 // for (z′ ∈ anc(get_bound(u′′, u′), u′′, z) ∧ z′ /∈ premv(u′)) do
178 // if (dec(get_bound(u′′, u′), u′, z′) ∩ sim(u′) = ∅)
179 // then premv(u′) := premv(u′) ∪ {z′};
180 // premv(u) := ∅;
181
182 loop {
183 // 1. 找到一个 presim 非空的节点 u,如果没有则退出
184 let Some(u) = self.nodes().find(|node| !presim.get(node).unwrap().is_empty()) else {
185 break;
186 };
187
188 // 2. 提前复制 premv_u,避免后续借用冲突
189 let premv_u = presim.get(&u).unwrap().clone();
190
191 // 3. 收集所有 u 的前驱节点 u_prime,即边 (u_prime, u)
192 let u_primes: Vec<_> = self.get_pre(&adj_self_inv, &u).collect();
193
194 for u_prime in u_primes {
195 // 4. 提前收集 sim(u_prime) 和 premv_u 的交集
196 let sim_u_prime = sim.get(&u_prime).unwrap();
197 let to_remove: Vec<_> = premv_u.intersection(sim_u_prime).cloned().collect();
198
199 for z in to_remove {
200 // 5. 现在可以安全地修改 sim
201 sim.get_mut(&u_prime).unwrap().remove(&z);
202
203 if sim.get(&u_prime).unwrap().is_empty() {
204 return HashMap::new();
205 }
206
207 // 6. 收集 u_prime 的前驱节点 u_double_prime,即边 (u_double_prime, u_prime)
208 let u_double_primes: Vec<_> = self.get_pre(&adj_self_inv, &u_prime).collect();
209
210 // 7. 收集所有需要更新的 (u_double_prime, z_prime) 对
211 let mut updates: Vec<(&T::Node, &T::Node)> = Vec::new();
212
213 // 收集当前 presim(u_prime) 的值,用于检查 z' /∈ presim(u′)
214 let presim_u_prime = presim.get(&u_prime).unwrap().clone();
215
216 for u_double_prime in u_double_primes {
217 let bound = self.get_bound(&u_double_prime, &u_prime);
218
219 if let Some(anc_set) = anc.get(&(bound, &u_double_prime, &z)) {
220 // 收集 anc_set 到临时变量
221 let anc_vec: Vec<_> = anc_set.iter().cloned().collect();
222
223 // 过滤出满足条件的 z_prime: z' ∈ anc(...) ∧ z' /∈ presim(u′)
224 for z_prime in anc_vec.iter() {
225 if !presim_u_prime.contains(z_prime) {
226 // 检查 dec(...) ∩ sim(u') 是否为空
227 if let Some(dec_set) = dec.get(&(bound, &u_prime, z_prime)) {
228 let sim_u_prime_set = sim.get(&u_prime).unwrap();
229 let has_intersection = dec_set.iter().any(|v| sim_u_prime_set.contains(v));
230
231 if !has_intersection {
232 updates.push((u_double_prime, *z_prime));
233 }
234 }
235 }
236 }
237 }
238 }
239
240 // 8. 批量更新 presim(u_double_prime)
241 for (u_double_prime, z_prime) in updates {
242 presim.get_mut(&u_double_prime).unwrap().insert(z_prime);
243 }
244 }
245 }
246
247 // 9. 清空 presim(u)
248 presim.get_mut(&u).unwrap().clear();
249 }
250
251 sim
252 }
253}