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