Skip to main content

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}