1use super::*;
2use crate::inter_store::InterStore;
3use haversine::haversine_m_fpair_ord;
4use ordered_float::OrderedFloat;
5use rand::prelude::*;
6use rayon::prelude::ParallelIterator;
7use smallvec::SmallVec;
8use sorted_slice_store::SortedSliceMap;
9use std::collections::BTreeMap;
10use std::collections::HashSet;
11use std::fmt::Debug;
12use utils::min_max;
13
14use kiddo::{KdTree, SquaredEuclidean};
15
16use itertools::Itertools;
17use smallvec::smallvec;
18use std::iter;
19
20type SmallVecIntermediates<V> = SmallVec<[V; 1]>;
21
22pub struct UndirectedAdjGraph<V, E> {
23 edges: BTreeMap<V, BTreeMap<V, (E, SmallVecIntermediates<V>)>>,
24}
25
26impl<V, E> Default for UndirectedAdjGraph<V, E>
27where
28 V: std::hash::Hash + Eq + Copy + Ord + Send + std::fmt::Debug + Default,
29 E: Copy
30 + PartialOrd
31 + Clone
32 + std::fmt::Debug
33 + std::ops::Add<Output = E>
34 + std::cmp::PartialEq
35 + Default,
36{
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42impl<V, E> UndirectedAdjGraph<V, E>
43where
44 V: std::hash::Hash + Eq + Copy + Ord + Send + std::fmt::Debug + Default,
45 E: Copy
46 + PartialOrd
47 + Clone
48 + std::fmt::Debug
49 + std::ops::Add<Output = E>
50 + std::cmp::PartialEq
51 + Default,
52{
53 pub fn new() -> Self {
54 Self {
55 edges: Default::default(),
56 }
57 }
58
59 pub fn set(&mut self, i: &V, j: &V, val: E) {
60 self.edges
61 .entry(*i)
62 .or_default()
63 .insert(*j, (val, Default::default()));
64 self.edges
65 .entry(*j)
66 .or_default()
67 .insert(*i, (val, Default::default()));
68 }
69
70 pub fn remove_vertex(&mut self, v: &V) {
71 while let Some((other_v, (_weight, _intermediaters))) =
72 self.edges.get_mut(v).unwrap().pop_last()
73 {
74 self.edges.get_mut(&other_v).unwrap().remove(v);
75 }
76 assert!(self.edges[v].is_empty());
77 self.edges.remove(v);
78 }
79
80 pub fn get(&self, i: &V, j: &V) -> Option<&E> {
81 self.edges
82 .get(i)
83 .and_then(|from_i| from_i.get(j).map(|(e, _intermediates)| e))
84 }
85
86 pub fn get_all(&self, i: &V, j: &V) -> Option<&(E, SmallVecIntermediates<V>)> {
87 self.edges.get(i).and_then(|from_i| from_i.get(j))
88 }
89
90 pub fn get_intermediates(&self, i: &V, j: &V) -> Option<&[V]> {
91 self.get_all(i, j)
92 .map(|(_e, intermediates)| intermediates.as_slice())
93 }
94
95 pub fn get_all_contracted_edges(&self) -> impl Iterator<Item = (&E, impl Iterator<Item = &V>)> {
99 self.edges
100 .iter()
101 .flat_map(|(a, from_a)| {
102 from_a
103 .iter()
104 .filter(move |(b, _)| a < b)
106 .map(move |(b, (edge_weight, inter))| ((a, inter, b), edge_weight))
107 })
108 .map(|((a, inter, b), edge_weight)| {
109 (
110 edge_weight,
111 iter::once(a).chain(inter.iter()).chain(iter::once(b)),
112 )
113 })
114 }
115
116 pub fn iter_vertexes_num_neighbours(&self) -> impl Iterator<Item = (&V, usize)> {
118 self.edges.iter().map(|(vid, edges)| (vid, edges.len()))
119 }
120
121 pub fn contains_vertex(&self, v: &V) -> bool {
122 self.edges.contains_key(v)
123 }
124
125 pub fn neighbors(&self, i: &V) -> impl Iterator<Item = (&V, &E)> + use<'_, V, E> {
127 self.edges[i]
128 .iter()
129 .map(|(j, (edge_weight, _intermediates))| (j, edge_weight))
130 }
131
132 pub fn num_neighbors(&self, i: &V) -> usize {
134 self.edges.get(i).map_or(0, |es| es.len())
135 }
136
137 pub fn len(&self) -> usize {
138 self.edges
139 .values()
140 .map(|from_i| from_i.len())
141 .sum::<usize>()
142 / 2
143 }
144
145 pub fn num_edges(&self) -> usize {
146 self.edges
147 .values()
148 .map(|from_i| from_i.len())
149 .sum::<usize>()
150 / 2
151 }
152
153 pub fn is_empty(&self) -> bool {
154 self.edges.is_empty()
155 }
156 pub fn num_vertexes(&self) -> usize {
157 self.edges.len()
158 }
159
160 pub fn vertexes(&self) -> impl Iterator<Item = &V> {
161 self.edges.keys()
162 }
163
164 pub fn remove_edge(&mut self, i: &V, j: &V) {
165 if let Some(from_i) = self.edges.get_mut(i) {
166 from_i.remove(j);
167 if from_i.is_empty() {
168 self.edges.remove(i);
169 }
170 }
171 if let Some(from_j) = self.edges.get_mut(j) {
172 from_j.remove(i);
173 if from_j.is_empty() {
174 self.edges.remove(j);
175 }
176 }
177 }
178}
179
180pub type SmallNidVec = SmallVec<[i64; 1]>;
181pub type SmallI32Vec = SmallVec<[i32; 1]>;
182
183#[derive(Default, Debug, Clone)]
184pub struct Graph2 {
185 edges: BTreeMap<i64, SmallNidVec>,
187}
188
189impl Graph2 {
190 pub fn new() -> Self {
191 Default::default()
192 }
193
194 pub fn add_edge(&mut self, vertex1: i64, vertex2: i64) -> bool {
195 if vertex1 == vertex2 {
196 return false;
197 }
198 match self.edges.get_mut(&vertex1) {
199 Some(others) => {
200 if others.contains(&vertex2) {
201 true
202 } else {
203 others.push(vertex2);
204 self.edges.entry(vertex2).or_default().push(vertex1);
205 false
206 }
207 }
208 _ => {
209 self.edges.insert(vertex1, smallvec![vertex2]);
210 self.edges.entry(vertex2).or_default().push(vertex1);
211 false
212 }
213 }
214 }
215
216 pub fn vertexes(&self) -> impl ExactSizeIterator<Item = &i64> {
217 self.edges.keys()
218 }
219 pub fn vertexes_par_iter(&self) -> impl ParallelIterator<Item = &i64> {
220 self.edges.par_iter().map(|(k, _v)| k)
221 }
222
223 pub fn vertexes_w_num_neighbours(&self) -> impl Iterator<Item = (&i64, usize)> {
224 self.edges.iter().map(|(nid, neigh)| (nid, neigh.len()))
225 }
226
227 pub fn vertexes_w_num_neighbours_par(&self) -> impl ParallelIterator<Item = (&i64, usize)> {
228 self.edges.par_iter().map(|(nid, neigh)| (nid, neigh.len()))
229 }
230
231 pub fn edges_iter(&self) -> impl Iterator<Item = (&i64, &i64)> {
232 self.edges.iter().flat_map(|(nid, neighs)| {
233 neighs
234 .iter()
235 .filter(|other| *other > nid)
236 .map(move |other| (nid, other))
237 })
238 }
239 pub fn edges_par_iter(&self) -> impl ParallelIterator<Item = (&i64, &i64)> {
240 self.edges.par_iter().flat_map(|(nid, neighs)| {
241 neighs
242 .par_iter()
243 .filter(|other| *other > nid)
244 .map(move |other| (nid, other))
245 })
246 }
247
248 pub fn neighbours(&self, vertex: &i64) -> impl Iterator<Item = &i64> + use<'_> {
249 self.edges.get(vertex).into_iter().flat_map(|ns| ns.iter())
250 }
251
252 pub fn num_neighbors(&self, vertex: &i64) -> Option<usize> {
253 self.edges.get(vertex).map(|others| others.len())
254 }
255
256 pub fn add_edge_chain(&mut self, vertexes: &[i64]) -> bool {
257 if vertexes.len() < 2 {
260 return false;
261 }
262 let mut added = false;
263 for w in vertexes.windows(2) {
264 added |= self.add_edge(w[0], w[1]);
265 }
266 added
267 }
268
269 pub fn num_vertexes(&self) -> usize {
270 self.edges.len()
271 }
272 pub fn num_edges(&self) -> usize {
273 self.edges
274 .values()
275 .map(|from_i| from_i.len())
276 .sum::<usize>()
277 / 2
278 }
279 pub fn is_empty(&self) -> bool {
280 self.edges.is_empty()
281 }
282
283 pub fn first_vertex(&self) -> Option<&i64> {
284 self.edges.first_key_value().map(|(k, _v)| k)
285 }
286 pub fn contains_vertex(&self, vertex: i64) -> bool {
287 self.edges.contains_key(&vertex)
288 }
289 pub fn contains_edge(&self, v1: i64, v2: i64) -> bool {
290 self.edges
291 .get(&v1)
292 .is_some_and(|neighs| neighs.contains(&v2))
293 }
294
295 pub fn remove_vertex(&mut self, vertex: i64) -> Option<SmallNidVec> {
296 let others = self.edges.remove(&vertex);
297 if let Some(ref others) = others {
298 for o in others {
299 let oo = self.edges.get_mut(o).unwrap();
300 oo.retain(|n| *n != vertex);
301 if oo.is_empty() {
302 self.edges.remove(o);
303 }
304 }
305 }
306
307 others
308 }
309 pub fn remove_edge(&mut self, vertex1: i64, vertex2: i64) -> Option<(i64, i64)> {
310 if self
311 .edges
312 .get(&vertex1)
313 .is_some_and(|v1_neighs| v1_neighs.contains(&vertex2))
314 {
315 self.edges
316 .get_mut(&vertex1)
317 .unwrap()
318 .retain(|n| *n != vertex2);
319 self.edges
320 .get_mut(&vertex2)
321 .unwrap()
322 .retain(|n| *n != vertex1);
323 if self.edges.get(&vertex1).unwrap().is_empty() {
324 self.edges.remove(&vertex1);
325 }
326 if self.edges.get(&vertex2).unwrap().is_empty() {
327 self.edges.remove(&vertex2);
328 }
329
330 Some((vertex1, vertex2))
331 } else {
332 None
333 }
334 }
335
336 pub fn into_disconnected_graphs(
337 mut self,
338 progress_bar: impl Into<Option<ProgressBar>>,
339 ) -> impl Iterator<Item = Self> {
340 let mut frontier = Vec::new();
341 let progress_bar: Option<ProgressBar> = progress_bar.into();
342
343 std::iter::from_fn(move || {
344 if self.is_empty() {
345 return None;
346 }
347
348 let mut new_graph = Graph2::new();
349
350 frontier.truncate(0);
351 frontier.push(*self.first_vertex().unwrap());
352
353 while let Some(nid) = frontier.pop() {
354 if let Some(others) = self.remove_vertex(nid) {
356 if let Some(progress_bar) = &progress_bar {
357 progress_bar.inc(1);
358 }
359 for o in others {
360 if !new_graph.contains_vertex(o) {
361 frontier.push(o);
362 }
363 new_graph.add_edge(nid, o);
364 }
365 }
366 }
367
368 Some(new_graph)
369 })
370 }
371
372 pub fn into_lines_random(self) -> impl Iterator<Item = Box<[i64]>> {
373 let mut graph = self;
374
375 std::iter::from_fn(move || {
376 if graph.is_empty() {
377 return None;
378 }
379
380 let mut curr_path: Vec<i64> = Vec::new();
381 curr_path.push(
386 graph
387 .vertexes_w_num_neighbours()
388 .take(100)
389 .filter(|(_nid, nn)| *nn == 1)
390 .map(|(nid, _)| *nid)
391 .next()
392 .unwrap_or_else(|| *graph.first_vertex().unwrap()),
393 );
394 let mut next: Option<i64>;
395 let mut last: &i64;
396
397 loop {
398 last = curr_path.last().unwrap();
399 next = graph
400 .neighbours(last)
401 .find(|v| !curr_path.contains(*v))
402 .copied();
403 match next {
404 None => {
405 break;
406 }
407 Some(next) => {
408 graph.remove_edge(*last, next).unwrap();
409 curr_path.push(next);
410 }
411 }
412 }
413
414 Some(curr_path.into_boxed_slice())
415 })
416 }
417
418 pub fn into_lines_as_crow_flies(
419 self,
420 nodeid_pos: &impl NodeIdPosition,
421 ) -> impl Iterator<Item = Box<[i64]>> + '_ {
422 let mut graphs = vec![self];
423
424 std::iter::from_fn(move || {
425 if graphs.is_empty() {
426 return None;
427 }
428 let mut graph = graphs.pop().unwrap();
429 assert!(!graph.is_empty());
430
431 let target_pair = graph
432 .edges
433 .keys()
434 .par_bridge()
435 .map(|n1| (n1, nodeid_pos.get(n1).unwrap()))
436 .flat_map(|(n1, p1)| {
437 graph
438 .edges
439 .keys()
440 .par_bridge()
441 .filter(|n2| *n2 > n1)
442 .map(move |n2| ((n1, p1), (n2, nodeid_pos.get(n2).unwrap())))
443 })
444 .max_by_key(|((_n1, p1), (_n2, p2))| haversine_m_fpair_ord(*p1, *p2));
445 let target_pair = target_pair.unwrap();
446
447 let src = target_pair.0;
448 let dest = target_pair.1;
449 let dest_nid = dest.0;
450 let dest_p = dest.1;
451
452 let res = dij::path_one_to_one(
453 (*src.0, (OrderedFloat(src.1.0), OrderedFloat(src.1.1))),
454 (*dest_nid, (OrderedFloat(dest_p.0), OrderedFloat(dest_p.1))),
455 nodeid_pos,
456 &graph,
457 None,
458 );
459 let path = res.1;
460
461 for edge in path.iter().tuple_windows::<(_, _)>() {
462 graph.remove_edge(*edge.0, *edge.1).unwrap();
463 }
464
465 if !graph.is_empty() {
466 let _old_num_graphs = graphs.len();
467 graphs.extend(graph.into_disconnected_graphs(None));
468 }
469
470 Some(path.into_boxed_slice())
471 })
472 }
473
474 #[allow(clippy::type_complexity)]
476 pub fn random_sample_vertexes(
477 &self,
478 num: usize,
479 nodeid_pos: &impl NodeIdPosition,
480 ) -> Box<[i64]> {
481 if num >= self.num_vertexes() {
482 let all_nodes = self.vertexes().copied().collect::<Vec<_>>();
483 return all_nodes.into_boxed_slice();
484 }
485
486 let all_nodes = self
487 .vertexes()
488 .copied()
489 .collect::<Vec<i64>>()
490 .into_boxed_slice();
491 assert!(!all_nodes.is_empty());
492
493 let k = 100;
495
496 let mut new_nodes = HashSet::with_capacity(num);
498
499 let mut kdtree: KdTree<f64, 2> = KdTree::with_capacity(num);
500 let mut rng = &mut rand::rng();
501
502 let first = *all_nodes.choose(&mut rng).unwrap();
503 let pos = nodeid_pos.get_arr(&first).unwrap();
504 new_nodes.insert(first);
505 kdtree.add(&pos, first.try_into().unwrap());
506
507 let mut possible_nodes = Vec::with_capacity(k);
509
510 while new_nodes.len() < num {
511 possible_nodes.truncate(0);
514 while possible_nodes.len() < k {
515 possible_nodes.extend(
516 all_nodes
517 .sample(&mut rng, k - possible_nodes.len() + 1)
518 .filter(|nid| !new_nodes.contains(nid))
519 .map(|nid| {
520 let pos = nodeid_pos.get_arr(nid).unwrap();
521 let dist = kdtree.nearest_one::<SquaredEuclidean>(&pos).distance;
522
523 (OrderedFloat(-dist), *nid, pos)
525 }),
526 );
527 }
528
529 possible_nodes.par_sort_by_key(|(dist, _nid, _pos)| *dist);
531 let (_dist, nid, pos) = possible_nodes[0];
532
533 kdtree.add(&pos, nid.try_into().unwrap());
535 new_nodes.insert(nid);
536 }
537
538 let new_nodes = new_nodes.into_iter().collect::<Vec<_>>();
539 new_nodes.into_boxed_slice()
540 }
541
542 pub fn betweenness_centrality(
543 &self,
544 nodes: &[i64],
545 nodeid_pos: &impl NodeIdPosition,
546 inter_store: &inter_store::InterStore,
547 progress_bar: impl Into<Option<ProgressBar>>,
548 ) -> SortedSliceMap<(i64, i64), u64> {
549 let progress_bar: Option<ProgressBar> = progress_bar.into();
550
551 let edge_lengths = SortedSliceMap::from_iter(self.edges_iter().map(|(nid1, nid2)| {
552 let edge_len = inter_store
553 .expand_undirected(*nid1, *nid2)
554 .map(|nid| nodeid_pos.get(&nid).unwrap())
555 .tuple_windows::<(_, _)>()
556 .par_bridge()
557 .map(|(p1, p2)| haversine::haversine_m_fpair(p1, p2))
558 .sum::<f64>();
559
560 let edge_len = (edge_len * 100.).round() as u64;
561
562 ((*nid1, *nid2), edge_len)
563 }));
564
565 let bc_res =
568 SortedSliceMap::from_iter(self.edges_iter().map(|(&nid1, &nid2)| ((nid1, nid2), 0)));
569 let bc_res = Arc::new(Mutex::new(bc_res));
570
571 nodes.par_iter().enumerate().for_each_with(
572 (bc_res.clone(), HashMap::new()),
573 |(bc_res, prev_dist), (i, nid0)| {
574 let target_nodes = &nodes[(i + 1)..];
575
576 dij::dij_single(*nid0, self, &edge_lengths, prev_dist);
578
579 let mut new_segs: Vec<((i64, i64), u64)> = Vec::with_capacity(target_nodes.len());
581
582 let mut buf_segs: Vec<(u64, i64, _)> = Vec::with_capacity(target_nodes.len());
584
585 buf_segs.extend(
586 target_nodes
587 .iter()
588 .copied()
589 .map(|nid_n| (prev_dist[&nid_n].1, nid_n, 1)),
590 );
591 buf_segs.par_sort_by_key(|(dist, nid, _acc)| (*dist, *nid));
592
593 while let Some((_dist, nid_b, acc)) = buf_segs.pop() {
594 if &nid_b == nid0 {
595 continue;
596 }
597 let (nid_a, new_dist) = prev_dist[&nid_b];
598
599 new_segs.push((min_max(nid_a, nid_b), acc));
601
602 let k = buf_segs.partition_point(|(thisdist, nid, _acc)| {
603 (*thisdist, *nid).le(&(new_dist, nid_a))
604 });
605 if k >= buf_segs.len() {
606 buf_segs.push((new_dist, nid_a, acc));
608 } else if buf_segs[k].1 == nid_a {
609 buf_segs[k].2 += acc;
611 } else {
612 buf_segs.insert(k, (new_dist, nid_a, acc));
614 }
615 }
616
617 let mut bc_res = bc_res.lock().unwrap();
618 for ((nid_a, nid_b), val) in new_segs.into_iter() {
619 *bc_res.get_mut(&(nid_a, nid_b)).unwrap() += val;
620 }
621 if let Some(progress_bar) = &progress_bar {
622 progress_bar.inc(target_nodes.len() as u64);
623 }
624 },
625 );
626
627 Arc::try_unwrap(bc_res).unwrap().into_inner().unwrap()
628 }
629
630 pub fn compress_graph(
631 &mut self,
632 inter_store: &mut Arc<Mutex<&mut InterStore>>,
633 remove_old_inters: bool,
634 never_remove_vertexes: impl Fn(i64) -> bool + Sync,
635 ) {
636 let num_orig_vertexes = self.num_vertexes();
637
638 let mut vertexes_already_excluded = HashSet::new();
640
641 let mut vertex_queue: Vec<i64> = Vec::new();
643 let mut tmp_inters = Vec::new();
644
645 loop {
646 vertex_queue.par_extend(self.vertexes_w_num_neighbours_par().filter_map(
647 |(nid, nneigh)| {
648 if nneigh == 2
649 && !vertexes_already_excluded.contains(nid)
650 && !never_remove_vertexes(*nid)
651 {
652 Some(*nid)
653 } else {
654 None
655 }
656 },
657 ));
658 if vertex_queue.is_empty() {
659 break;
660 }
661
662 while let Some(nid) = vertex_queue.pop() {
663 if self.num_neighbors(&nid) != Some(2) || never_remove_vertexes(nid) {
664 continue;
665 }
666 let mut others = self.remove_vertex(nid).unwrap();
667 let nid_b = others.pop().unwrap();
668 let nid_a = others.pop().unwrap();
669
670 if self.contains_edge(nid_a, nid_b) {
671 self.add_edge(nid, nid_a);
674 self.add_edge(nid, nid_b);
675
676 vertexes_already_excluded.insert(nid);
678 continue;
679 }
680
681 let mut inter_store = inter_store.lock().unwrap();
682 tmp_inters.truncate(0);
683 tmp_inters.extend(inter_store.inters_undirected(&nid_a, &nid));
684 tmp_inters.push(nid);
685 tmp_inters.extend(inter_store.inters_undirected(&nid, &nid_b));
686
687 if remove_old_inters {
688 inter_store.remove_undirected(&nid_a, &nid);
689 inter_store.remove_undirected(&nid, &nid_b);
690 }
691 inter_store.insert_undirected((nid_a, nid_b), &tmp_inters);
692
693 self.add_edge(nid_a, nid_b);
694
695 vertex_queue.push(nid_a);
697 vertex_queue.push(nid_b);
698 }
699 }
700
701 debug!(
702 "Removed {} vertexes ({}%)",
703 num_orig_vertexes - self.num_vertexes(),
704 (num_orig_vertexes - self.num_vertexes()) * 100 / num_orig_vertexes,
705 );
706 }
707
708 pub fn remove_spikes(&mut self, never_remove_vertexes: impl Fn(i64) -> bool + Sync) {
709 let num_orig_vertexes = self.num_vertexes();
710
711 let mut vertex_queue: Vec<i64> = Vec::new();
713
714 loop {
715 vertex_queue.par_extend(self.vertexes_w_num_neighbours_par().filter_map(
716 |(nid, nneigh)| {
717 if nneigh == 1 && !never_remove_vertexes(*nid) {
718 Some(*nid)
719 } else {
720 None
721 }
722 },
723 ));
724 if vertex_queue.is_empty() {
725 break;
726 }
727
728 while let Some(nid) = vertex_queue.pop() {
729 if self.num_neighbors(&nid) != Some(1) || never_remove_vertexes(nid) {
730 continue;
731 }
732 let mut others = self.remove_vertex(nid).unwrap();
733 let nid_a = others.pop().unwrap();
734
735 vertex_queue.push(nid_a);
736 }
737 }
738
739 debug!(
740 "Removed {} vertexes ({}%)",
741 num_orig_vertexes - self.num_vertexes(),
742 (num_orig_vertexes - self.num_vertexes()) * 100 / num_orig_vertexes,
743 );
744 }
745}