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
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}