net_ensembles/generic_graph.rs
1//! # Generic implementation for Topology
2//! * contains multiple measurable quantities
3//! * used by `Graph<T>` and `SwGraph<T>`
4use crate::{traits::*, iter::*, GraphErrors};
5
6use std::{convert::*, collections::*, marker::*, io::Write};
7
8#[cfg(feature = "serde_support")]
9use serde::{Serialize, Deserialize};
10/// # Generic graph implementation
11/// * contains multiple measurable quantities
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
14pub struct GenericGraph<T, A>
15{
16 pub(crate) next_id: usize,
17 pub(crate) edge_count: usize,
18 pub(crate) vertices: Vec<A>,
19 pub(crate) phantom: PhantomData<T>,
20}
21
22impl<T, A> GenericGraph<T, A>
23where T: Node,
24 A: AdjContainer<T> {
25 /// Create new graph with `size` nodes
26 /// and no edges
27 pub fn new(size: usize) -> Self {
28 let mut vertices = Vec::with_capacity(size);
29 vertices.extend(
30 (0..size)
31 .map(|i| A::new(i, T::new_from_index(i)))
32 );
33 Self{
34 vertices,
35 next_id: size,
36 edge_count: 0,
37 phantom: PhantomData,
38 }
39 }
40}
41
42impl<T, A> GenericGraph<T, A>
43where A: AdjContainer<T>
44{
45
46 /// # removes all edges from the graph
47 /// * inexpensive O(1), if there are no edges to begin with
48 /// * O(vertices) otherwise
49 pub fn clear_edges(&mut self) {
50 if self.edge_count() != 0 {
51 self.edge_count = 0;
52 for container in self.vertices.iter_mut() {
53 unsafe { container.clear_edges(); }
54 }
55 }
56 }
57
58 /// # initialize Ring
59 /// * every node is connected with its neighbors, which are
60 /// not more than distance away
61 pub(crate) fn init_ring(&mut self, distance: usize) -> Result<(), GraphErrors>
62 {
63 self.clear_edges();
64 let n = self.vertex_count();
65
66 for i in 0..n
67 {
68 for add in 1..=distance{
69 let sum = i + add;
70 let index2 = if sum >= n {
71 sum - n
72 } else {
73 sum
74 };
75 self.add_edge(i, index2)?
76 }
77 }
78 Ok(())
79 }
80
81 /// # Sort adjecency lists
82 /// If you depend on the order of the adjecency lists, you can sort them
83 /// # Performance
84 /// * internally uses [pattern-defeating quicksort](https://github.com/orlp/pdqsort)
85 /// as long as that is the standard
86 /// * sorts an adjecency list with length `d` in worst-case: `O(d log(d))`
87 /// * is called for each adjecency list, i.e., `self.vertex_count()` times
88 pub fn sort_adj(&mut self) {
89 for container in self.vertices.iter_mut() {
90 container.sort_adj();
91 }
92 }
93
94
95 /// # get `AdjContainer` of vertex `index`
96 /// * **panics** if index out of bounds
97 pub fn container(&self, index: usize) -> &A {
98 &self.vertices[index]
99 }
100
101 /// # get `AdjContainer` of vertex `index`
102 /// * `None` if index is out of bounds
103 /// * `Some(&A)` else
104 pub fn container_checked(&self, index: usize) -> Option<&A>
105 {
106 self.vertices.get(index)
107 }
108
109 /// * get iterator over AdjContainer in order of the indices
110 /// * iterator returns `AdjContainer<Node>`
111 pub fn container_iter(&self) -> std::slice::Iter::<A> {
112 self.vertices.iter()
113 }
114
115 /// * iterate over `AdjContainer` of neighbors of vertex `index`
116 /// * iterator returns `AdjContainer<Node>`
117 /// * `sort_adj` will affect the order
118 ///
119 /// If `let mut iter = self.contained_iter_neighbors()` is called directly after
120 /// `self.sort_adj()`, the following will be true (as long as `iter` does not return `None` of cause):
121 /// `iter.next().unwrap().id() < iter.next().unwrap.id() < ...` Note, that `...id()` returns the
122 /// index of the corresponding vertex
123 /// * **panics** if index out of bounds
124 pub fn container_iter_neighbors(&self, index: usize) -> NContainerIter<T, A> {
125 NContainerIter::new(
126 self.vertices.as_slice(),
127 self.vertices[index].neighbors()
128 )
129 }
130
131 /// * get iterator over additional information stored at each vertex in order of the indices
132 /// * iterator returns a `Node` (for example `EmptyNode` or whatever you used)
133 /// * similar to `self.container_iter().map(|container| container.contained())`
134 pub fn contained_iter(&self) -> ContainedIter<T, A> {
135 ContainedIter::new(self.vertices.as_slice())
136 }
137
138 /// * same as `contained_iter`, but mutable
139 pub fn contained_iter_mut(&mut self) -> ContainedIterMut<T, A> {
140 ContainedIterMut::new (
141 self.vertices.iter_mut()
142 )
143
144 }
145
146 /// * iterate over additional information of neighbors of vertex `index`
147 /// * iterator returns `&T`
148 /// * `sort_adj` will affect the order
149 /// * **panics** if index out of bounds
150 pub fn contained_iter_neighbors(&self, index: usize) -> NContainedIter<T, A> {
151 NContainedIter::new(
152 self.vertices.as_slice(),
153 self.vertices[index].neighbors()
154 )
155 }
156
157 /// * iterate over additional information of neighbors of vertex `index`
158 /// * iterator returns (`index_neighbor`,`&T`)
159 /// * `sort_adj` will affect the order
160 /// * **panics** if index out of bounds
161 pub fn contained_iter_neighbors_with_index(&self, index: usize) -> NIContainedIter<T, A> {
162 NIContainedIter::new(
163 self.vertices.as_slice(),
164 self.vertices[index].neighbors()
165 )
166 }
167
168 /// * iterate over mutable additional information of neighbors of vertex `index`
169 /// * iterator returns `&mut T`
170 /// * `sort_adj` will affect the order
171 /// * **panics** if index out of bounds
172 /// * See also: [`GraphIteratorsMut`](../traits/trait.GraphIteratorsMut.html)
173 pub fn contained_iter_neighbors_mut(&mut self, index: usize) -> NContainedIterMut<T, A> {
174 assert!(
175 index < self.vertices.len(),
176 "contained_iter_neighbors_mut - index out of bounds"
177 );
178
179 let ptr = self.vertices.as_mut_ptr();
180 let iter_helper: &mut A = unsafe { &mut *ptr.add(index) };
181 let iter = iter_helper.neighbors();
182
183 NContainedIterMut::new(
184 self.vertices.as_mut_slice(),
185 iter
186 )
187 }
188
189 /// * iterate over mutable additional information of neighbors of vertex `index`
190 /// * iterator returns `(index_neighbor: usize, neighbor: &mut T)`
191 /// * `sort_adj` will affect the order
192 /// * **panics** if index out of bounds
193 /// * See also: [`GraphIteratorsMut`](../traits/trait.GraphIteratorsMut.html)
194 pub fn contained_iter_neighbors_mut_with_index(&mut self, index: usize) -> INContainedIterMut<T, A> {
195 assert!(
196 index < self.vertices.len(),
197 "contained_iter_neighbors_mut_with_index - index out of bounds"
198 );
199
200 let ptr = self.vertices.as_mut_ptr();
201 let iter_helper: &mut A = unsafe { &mut *ptr.add(index) };
202 let iter = iter_helper.neighbors();
203
204 INContainedIterMut::new(
205 self.vertices.as_mut_slice(),
206 iter
207 )
208 }
209
210 pub(crate) fn container_mut(&mut self, index: usize) -> &mut A {
211 &mut self.vertices[index]
212 }
213
214 /// # For your calculations etc.
215 /// * **read access** to **your struct** T, stored at **each vertex**, that implements `Node` trait
216 /// ## Note
217 /// * **panics** if index out of bounds
218 pub fn at(&self, index: usize) -> &T {
219 self.container(index).contained()
220 }
221
222 /// # For your calculations etc.
223 /// * **read access** to **your struct** T, stored at **each vertex**, that implements `Node` trait
224 /// * `None` if index is out of bounds
225 pub fn at_checked(&self, index: usize) -> Option<&T>
226 {
227 self.container_checked(index)
228 .map(|container| container.contained())
229 }
230
231 /// # For your calculations etc.
232 /// * **write access** to **your struct** T, stored at **each vertex**, that implements `Node` trait
233 /// # Note
234 /// * **panics** if index out of bounds
235 pub fn at_mut(&mut self, index: usize) -> &mut T {
236 self.container_mut(index).contained_mut()
237 }
238
239 /// returns number of vertices present in graph
240 pub fn vertex_count(&self) -> usize {
241 self.next_id
242 }
243
244 /// calculates the average degree of the graph
245 /// * `(2 * edge_count) / vertex_count`
246 pub fn average_degree(&self) -> f32 {
247 (2 * self.edge_count()) as f32 / self.vertex_count() as f32
248 }
249
250 /// # Get mutable vertex
251 /// * panics if index out of range
252 pub(crate) fn get_mut_unchecked(&mut self, index: usize) -> &mut A {
253 &mut self.vertices[index]
254 }
255
256 /// Returns two mutable references in a tuple
257 /// ## panics if:
258 /// * index out of bounds
259 /// * in debug: if indices are not unique
260 pub(crate) fn get_2_mut(&mut self, index0: usize, index1: usize) -> (&mut A, &mut A)
261 {
262 debug_assert!(
263 index0 < self.next_id &&
264 index1 < self.next_id,
265 "net_ensembles - panic - index out of bounds! \
266 vertex_count: {}, index_0: {}, index1: {} - \
267 error probably results from trying to add or remove edges",
268 self.vertex_count(),
269 index0,
270 index1
271
272 );
273
274 debug_assert!(
275 index0 != index1,
276 "net_ensembles - panic - indices have to be unique! \
277 error probably results from trying to add or remove self-loops"
278 );
279
280 let r1: &mut A;
281 let r2: &mut A;
282
283 let ptr = self.vertices.as_mut_ptr();
284
285 unsafe {
286 r1 = &mut *ptr.offset(index0 as isize);
287 r2 = &mut *ptr.offset(index1 as isize);
288 }
289
290 (r1, r2)
291 }
292
293 /// Returns three mutable references in a tuple
294 /// ## panics:
295 /// * index out of bounds
296 /// * in debug: if indices are not unique
297 pub(crate) fn get_3_mut(&mut self, index0: usize, index1: usize, index2: usize) ->
298 (&mut A, &mut A, &mut A)
299 {
300 debug_assert!(
301 index0 < self.next_id &&
302 index1 < self.next_id &&
303 index2 < self.next_id
304 );
305
306 debug_assert!(
307 index0 != index1 &&
308 index1 != index2 &&
309 index2 != index0
310 );
311
312 let r1: &mut A;
313 let r2: &mut A;
314 let r3: &mut A;
315
316 let ptr = self.vertices.as_mut_ptr();
317
318 unsafe {
319 r1 = &mut *ptr.offset(index0 as isize);
320 r2 = &mut *ptr.offset(index1 as isize);
321 r3 = &mut *ptr.offset(index2 as isize);
322 }
323
324 (r1, r2, r3)
325 }
326
327 /// Returns a reference to the element stored in the specified node or `None` if out of Bounds
328 pub fn get_contained(&self, index: usize) -> Option<&T>
329 {
330 self.vertices
331 .get(index)
332 .and_then(|v| Some(v.contained()))
333 }
334
335 /// Returns a mutable reference to the element stored in the specified node or `None` if out of Bounds
336 pub fn get_contained_mut(&mut self, index: usize) -> Option<&mut T>
337 {
338 self.vertices
339 .get_mut(index)
340 .and_then(|v| Some(v.contained_mut()))
341 }
342
343 /// Returns a reference to the element stored in the specified node
344 ///
345 /// For a save alternative see [get_contained](`Self::get_contained`)
346 /// # Safety
347 /// Calling this method with an out-of-bounds index is [undefined behavior](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) even if the resulting reference is not used.
348 pub unsafe fn get_contained_unchecked(&self, index: usize) -> &T
349 {
350 self.vertices
351 .get_unchecked(index)
352 .contained()
353 }
354
355 /// Returns a mutable reference to the element stored in the specified node
356 ///
357 /// For a save alternative see [get_contained_mut](`Self::get_contained_mut`)
358 /// # Safety
359 /// Calling this method with an out-of-bounds index is [undefined behavior](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) even if the resulting reference is not used.
360 pub unsafe fn get_contained_unchecked_mut(&mut self, index: usize) -> &mut T
361 {
362 self.vertices
363 .get_unchecked_mut(index)
364 .contained_mut()
365 }
366
367 /// Adds edge between nodes `index1` and `index2`
368 /// ## ErrorCases:
369 /// | Error | Reason |
370 /// | ---- | ---- |
371 /// | `GraphErrors::IndexOutOfRange` | `index1` or `index2` larger than `self.vertex_count()` |
372 /// | `GraphErrors::EdgeExists` | requested edge already exists! |
373 /// ## panics
374 /// * if indices out of bounds
375 /// * in debug: If `index0 == index1`
376 pub fn add_edge(&mut self, index1: usize, index2: usize) -> Result<(),GraphErrors> {
377 let (r1, r2) = self.get_2_mut(index1, index2);
378 unsafe{ r1.push(r2)?; }
379 self.edge_count += 1;
380 Ok(())
381 }
382
383 /// Removes edge between nodes *index1* and *index2*
384 /// ## ErrorCases:
385 /// | Error | Reason |
386 /// | ---- | ---- |
387 /// | `GraphErrors::IndexOutOfRange` | `index1` or `index2` larger than `self.vertex_count()` |
388 /// | `GraphErrors::EdgeDoesNotExist` | requested edge does not exists |
389 /// # panics
390 /// * if index out of bounds
391 /// * in debug: If `index0 == index1`
392 pub fn remove_edge(&mut self, index1: usize, index2: usize) -> Result<(),GraphErrors> {
393 let (r1, r2) = self.get_2_mut(index1, index2);
394 unsafe{ r1.remove(r2)?; }
395 self.edge_count -= 1;
396 Ok(())
397 }
398
399 /// returns total number of edges in graph
400 pub fn edge_count(&self) -> usize {
401 self.edge_count
402 }
403
404 /// * returns number of vertices adjacent to vertex `index`
405 /// * `None` if index out of bounds
406 pub fn degree(&self, index: usize) -> Option<usize> {
407 Some(
408 self
409 .vertices
410 .get(index)?
411 .degree()
412 )
413 }
414
415 /// # get degree vector
416 /// * returns vector of length `self.vertex_count()`
417 /// where each entry corresponds to the degree of the vertex with the respective index
418 pub fn degree_vec(&self) -> Vec<usize>
419 {
420 let mut degree_vec = Vec::with_capacity(self.vertex_count());
421 degree_vec.extend(
422 self
423 .vertices
424 .iter()
425 .map(|c| c.degree())
426 );
427 degree_vec
428 }
429
430
431
432 /// # returns `Iterator`
433 ///
434 /// * the iterator will iterate over the vertices in depth first search order,
435 /// beginning with vertex `index`.
436 /// * iterator returns `node`
437 /// * iterator always returns None if index out of bounds
438 ///
439 /// Order
440 ///------------------------
441 /// Order is guaranteed to be in DFS order, however
442 /// if this order is not unambigouse
443 /// adding edges and especially removing edges will shuffle the order.
444 ///
445 /// Note:
446 /// ----------------------
447 /// Will only iterate over vertices within the connected component that contains vertex `index`
448 pub fn dfs(&self, index: usize) -> Dfs<T, A> {
449 Dfs::new(&self, index)
450 }
451
452 /// # returns `Iterator`
453 ///
454 /// * the iterator will iterate over the vertices in depth first search order,
455 /// beginning with vertex `index`.
456 /// * Iterator returns tuple `(index, node)`
457 /// * iterator always returns None if index out of bounds
458 ///
459 /// Order
460 ///------------------------
461 /// Order is guaranteed to be in DFS order, however
462 /// if this order is not unambigouse
463 /// adding edges and especially removing edges will shuffle the order.
464 ///
465 /// Note:
466 /// ----------------------
467 /// Will only iterate over vertices within the connected component that contains vertex `index`
468 pub fn dfs_with_index(&self, index: usize) -> DfsWithIndex<T, A> {
469 DfsWithIndex::new(&self, index)
470 }
471
472 /// # returns `Iterator`
473 ///
474 /// * the iterator will iterate over the vertices in breadth first search order,
475 /// beginning with vertex `index`.
476 /// * Iterator returns tuple `(index, node, depth)`
477 ///
478 /// ### depth
479 /// * starts at 0 (i.e. the first element in the iterator will have `depth = 0`)
480 /// * `depth` equals number of edges in the *shortest path* from the *current* vertex to the
481 /// *first* vertex (i.e. to the vertex with index `index`)
482 ///
483 /// Order
484 ///------------------------
485 /// Order is guaranteed to be in BFS order, however
486 /// if this order is not unambigouse
487 /// adding edges and especially removing edges will shuffle the order.
488 ///
489 /// Note:
490 /// ----------------------
491 /// Will only iterate over vertices within the connected component that contains vertex `index`
492 pub fn bfs_index_depth(&self, index: usize) -> Bfs<T, A> {
493 Bfs::new(&self, index)
494 }
495
496 // # returns `Option<Iterator>`
497 /// * similar to self.bfs_index_depth, but allows for ignoring of vertices
498 ///
499 /// * the iterator will iterate over the vertices in breadth first search order,
500 /// beginning with vertex `index`.
501 /// * the iterator will ignore all vertices, where `filter(vertex, index_of_vertex)` returns false
502 /// * returns `None`if index is out of bounds or `filter(vertex, index)`retruns false
503 /// * Iterator returns tuple `(index, vertex, depth)`
504 ///
505 /// ### depth
506 /// * starts at 0 (i.e. the first element in the iterator will have `depth = 0`)
507 /// * `depth` equals number of edges in the *shortest path* from the *current* vertex to the
508 /// *first* vertex (i.e. to the vertex with index `index`), while ignoring paths that
509 /// go through filtered out vertices
510 ///
511 /// Order
512 ///------------------------
513 /// Order is guaranteed to be in BFS order, however
514 /// if this order is not unambigouse
515 /// adding edges and especially removing edges will shuffle the order.
516 ///
517 /// Note:
518 /// ----------------------
519 /// Will only iterate over vertices within the connected component that contains vertex `index`
520 pub fn bfs_filtered<'a, 'b, F>(&'a self, index: usize, filter: &'b mut F) -> Option<BfsFiltered<'a, 'b, T, A, F>>
521 where F: 'b + FnMut(&T, usize) -> bool,
522 {
523 BfsFiltered::new(self, index, filter)
524 }
525
526 /// | result | condition |
527 /// |--------------|----------------------------------------------------------|
528 /// | `None` | **if** graph does not contain any vertices |
529 /// | `Some(true)` | **else if** all vertices are connected by paths of edges |
530 /// | `Some(false)`| **otherwise** |
531 pub fn is_connected(&self) -> Option<bool> {
532 if self.vertex_count() == 0 {
533 None
534 } else {
535 Some(self.dfs(0).count() == self.vertex_count())
536 }
537 }
538
539 /// # definition
540 /// Calculates the size of the **q-core** (i.e. number of nodes in the biggest possible set of nodes,
541 /// where all nodes from the set are connected with at least `q` other nodes from the set)
542 ///
543 /// returns `None` if impossible to calculate (e.g. `vertex_count == 0` or `q <= 1`)
544 /// # Example
545 /// ```
546 /// use net_ensembles::EmptyNode;
547 /// use net_ensembles::Graph;
548 ///
549 /// let graph: Graph<EmptyNode> = Graph::new(0);
550 /// assert_eq!(graph.q_core(1), None);
551 /// assert_eq!(graph.q_core(2), None);
552 ///
553 /// let graph2: Graph<EmptyNode> = Graph::new(1);
554 ///
555 /// assert_eq!(graph2.q_core(1), None);
556 /// assert_eq!(graph2.q_core(2), Some(0));
557 ///
558 ///
559 /// // create complete graph
560 /// let mut graph3: Graph<EmptyNode> = Graph::new(20);
561 /// for i in 0..graph3.vertex_count() {
562 /// for j in i+1..graph3.vertex_count() {
563 /// graph3.add_edge(i, j).unwrap();
564 /// }
565 /// }
566 ///
567 /// // since this is a complete graph, the q-core should always consist of 20 nodes
568 /// // as long as q < 20, as every node has 19 neighbors
569 /// for i in 2..20 {
570 /// assert_eq!(graph3.q_core(i), Some(20));
571 /// }
572 ///
573 /// assert_eq!(graph3.q_core(20), Some(0));
574 /// ```
575 pub fn q_core(&self, q: usize) -> Option<usize> {
576 if q < 2 || self.vertex_count() == 0 {
577 return None;
578 }
579
580 let mut degree: Vec<_> = self.container_iter()
581 .map(|vertex| vertex.degree())
582 .collect();
583
584 // virtually: recursively remove all vertices with less then q neighbors
585 let mut something_changed = true;
586
587 while something_changed {
588 something_changed = false;
589 for i in 0..self.vertex_count() {
590 if degree[i] == 0 {
591 continue;
592 }
593 if degree[i] < q {
594 self.vertices[i]
595 .neighbors()
596 .for_each(|&n|
597 {
598 if degree[n] > 0 {
599 degree[n] -= 1;
600 }
601 }
602 );
603 degree[i] = 0;
604 something_changed = true;
605 }
606 }
607 }
608
609 // find biggest component
610 let mut result = 0;
611 // initiate stack
612 let mut stack: Vec<usize> = Vec::with_capacity(self.vertex_count());
613
614 for i in 0..self.vertex_count() {
615 // skip all nodes that are removed or in a known component
616 if degree[i] == 0 {
617 continue;
618 }
619 let mut counter = 0;
620 stack.push(i);
621
622 // i is in known component
623 degree[i] = 0;
624
625 while let Some(index) = stack.pop() {
626 counter += 1;
627
628 for &j in self
629 .container(index)
630 .neighbors() // iterate over neighbors
631 {
632 // skip if already handled
633 if degree[j] == 0 {
634 continue;
635 }
636
637 degree[j] = 0;
638 stack.push(j);
639 }
640 }
641 result = result.max(counter);
642 }
643
644 Some(result)
645 }
646
647 /// # compute connected component ids
648 /// * used for `self.connected_components()`
649 /// * each vertex gets an id, all vertices with the same id are in the same connected component
650 /// * returns (number of components, vector of ids)
651 pub fn connected_components_ids(&self) -> (usize, Vec<isize>)
652 {
653 let mut component_id : Vec<isize> = vec![-1; self.vertex_count()];
654 let mut current_id = 0;
655
656 for i in 0..self.vertex_count(){
657 // already in a component?
658 if component_id[i] != -1 {
659 continue;
660 }
661
662 // start depth first search over indices of vertices connected with vertex i
663 for (j, _) in self.dfs_with_index(i) {
664 component_id[j] = current_id;
665 }
666 current_id += 1;
667
668 }
669 // cast current_id as usize
670 let num_components = usize::try_from(current_id)
671 .expect("connected_components ERROR 0");
672
673 (num_components, component_id)
674 }
675
676 /// # compute sizes of all *connected components*
677 ///
678 /// * the **number** of connected components is the **size** of the returned vector, i.e. `result.len()`
679 /// * returns **empty** vector, if graph does not contain vertices
680 /// * returns (reverse) **ordered vector of sizes** of the connected components,
681 /// i.e. the biggest component is of size `result[0]` and the smallest is of size `result[result.len() - 1]`
682 pub fn connected_components(&self) -> Vec<usize> {
683
684 let (num_components, component_id) = self.connected_components_ids();
685
686 let mut result = vec![0; num_components];
687
688 for i in component_id {
689 let as_usize = usize::try_from(i)
690 .expect("connected_components ERROR 1");
691 result[as_usize] += 1;
692 }
693
694 // sort by reverse
695 // unstable here means inplace and ordering of equal elements is not guaranteed
696 result.sort_unstable_by(
697 |a, b|
698 a.partial_cmp(b)
699 .unwrap()
700 .reverse()
701 );
702 result
703 }
704
705 /// # Connects connected components (CCs)
706 /// * returns vector of indices, where each corresponding node is in a different
707 /// connected component
708 pub(crate) fn suggest_connections(& self) -> Vec<usize>
709 {
710 let mut suggestions = Vec::new();
711 let mut component_id : Vec<i32> = vec![-1; self.vertex_count()];
712 let mut current_id = 0;
713 for i in 0..self.vertex_count(){
714 // already in a component?
715 if component_id[i] != -1 {
716 continue;
717 }
718 suggestions.push(i);
719
720 // start depth first search over indices of vertices connected with vertex i
721 for (j, _) in self.dfs_with_index(i) {
722 component_id[j] = current_id;
723 }
724 current_id += 1;
725
726 }
727 suggestions
728 }
729
730 /// Count number of leaves in the graph, i.e. vertices with exactly one neighbor
731 pub fn leaf_count(&self) -> usize {
732 self.vertices
733 .iter()
734 .filter(|a| a.degree() == 1)
735 .count()
736 }
737
738 /// * Creates String which contains the topology of the network in a format
739 /// that can be used by **circo** etc. to generate a pdf of the graph.
740 /// * **indices** are used as **labels**
741 /// * search for **graphviz** to learn about **.dot** format
742 #[deprecated(
743 since = "0.3.0",
744 note = "Please use any method of the `Dot` trait instead, e.g., `dot_with_indices`"
745 )]
746 pub fn to_dot(&self) -> String {
747 let mut s = "graph{\n\t".to_string();
748
749 for i in 0..self.vertex_count() {
750 s += &format!("{} ", i);
751 }
752 s += "\n";
753
754 for i in 0..self.vertex_count() {
755 for &j in self.container(i).neighbors() {
756 if i < j {
757 s.push_str(&format!("\t{} -- {}\n", i, j));
758 }
759 }
760 }
761 s += "}";
762 s
763 }
764
765 /// # Example
766 /// ```
767 /// use std::fs::File;
768 /// use std::io::prelude::*;
769 /// use net_ensembles::{Graph, EmptyNode, dot_constants::EXAMPLE_DOT_OPTIONS};
770 ///
771 /// let mut graph: Graph<EmptyNode> = Graph::new(3);
772 /// graph.add_edge(0, 1).unwrap();
773 /// graph.add_edge(0, 2).unwrap();
774 /// graph.add_edge(1, 2).unwrap();
775 ///
776 /// // create string of dotfile
777 /// let s = graph.to_dot_with_labels_from_contained(
778 /// EXAMPLE_DOT_OPTIONS,
779 /// |_contained, index| format!("Hey {}!", index)
780 /// );
781 ///
782 /// // write to file
783 /// let mut f = File::create("example.dot").expect("Unable to create file");
784 /// f.write_all(s.as_bytes()).expect("Unable to write data");
785 ///
786 /// ```
787 /// In this example, `example.dot` now contains:
788 /// ```dot
789 /// graph G{
790 /// bgcolor="transparent";
791 /// fontsize=50;
792 /// node [shape=ellipse, penwidth=1, fontname="Courier", pin=true ];
793 /// splines=true;
794 /// 0 1 2 ;
795 /// "0" [label="Hey 0!"];
796 /// "1" [label="Hey 1!"];
797 /// "2" [label="Hey 2!"];
798 /// 0 -- 1
799 /// 0 -- 2
800 /// 1 -- 2
801 /// }
802 /// ```
803 ///
804 /// Then you can use, e.g.,
805 /// ```console
806 /// foo@bar:~$ circo example.dot -Tpdf > example.pdf
807 /// ```
808 /// to create a **pdf** representation from it.
809 /// Search for **graphviz** to learn more.
810 #[deprecated(
811 since = "0.3.0",
812 note = "Please use any method of the `DotExtra` trait instead, e.g., `dot_from_contained_index`"
813 )]
814 pub fn to_dot_with_labels_from_contained<F, S1, S2>(&self, dot_options: S1, f: F ) -> String
815 where
816 S1: AsRef<str>,
817 S2: AsRef<str>,
818 F: Fn(&T, usize) -> S2
819 {
820 let mut writer = Vec::<u8>::with_capacity(40 * self.vertices.len());
821 self.dot_from_contained_index(
822 &mut writer,
823 dot_options,
824 |index, c|
825 f(c, index)
826 ).unwrap();
827 String::from_utf8(writer)
828 .unwrap()
829 }
830
831 /// # Same as `to_dot_with_labels_from_contained` but with access to neighbor information
832 /// # Example
833 /// ```
834 /// use std::fs::File;
835 /// use std::io::prelude::*;
836 /// use net_ensembles::traits::*;
837 /// use net_ensembles::dot_constants::*;
838 /// use net_ensembles::{Graph,EmptyNode};
839 ///
840 /// let mut graph: Graph<EmptyNode> = Graph::new(5);
841 /// graph.add_edge(0, 1).unwrap();
842 /// graph.add_edge(0, 2).unwrap();
843 /// graph.add_edge(1, 2).unwrap();
844 /// graph.add_edge(0, 3).unwrap();
845 /// graph.add_edge(3, 4).unwrap();
846 ///
847 /// // create string of dotfile
848 /// let s = graph.to_dot_with_labels_from_container(
849 /// &[SPLINES, NO_OVERLAP].join("\n\t"),
850 /// |container, index|
851 /// {
852 /// container.contained(); // does nothing in this example, but you can still access
853 /// // contained, as you could in
854 /// // to_dot_with_labels_from_contained
855 /// format!("index {}, degree: {}", index, container.degree())
856 /// }
857 /// );
858 ///
859 /// // write to file
860 /// let mut f = File::create("example_2.dot").expect("Unable to create file");
861 /// f.write_all(s.as_bytes()).expect("Unable to write data");
862 ///
863 /// ```
864 /// In this example, `example_2.dot` now contains:
865 /// ```dot
866 /// graph G{
867 /// splines=true;
868 /// overlap=false;
869 /// 0 1 2 3 4 ;
870 /// "0" [label="index 0, degree: 3"];
871 /// "1" [label="index 1, degree: 2"];
872 /// "2" [label="index 2, degree: 2"];
873 /// "3" [label="index 3, degree: 2"];
874 /// "4" [label="index 4, degree: 1"];
875 /// 0 -- 1
876 /// 0 -- 2
877 /// 0 -- 3
878 /// 1 -- 2
879 /// 3 -- 4
880 /// }
881 /// ```
882 ///
883 /// Then you can use, e.g.,
884 /// ```console
885 /// foo@bar:~$ circo example_2.dot -Tpdf > example_2.pdf
886 /// ```
887 /// to create a **pdf** representation from it.
888 /// Search for **graphviz** to learn more.
889 #[deprecated(
890 since = "0.3.0",
891 note = "Please use any method of the `DotExtra` trait instead, e.g., `dot_from_container_index`"
892 )]
893 pub fn to_dot_with_labels_from_container<F, S1, S2>(&self, dot_options: S1, f: F ) -> String
894 where
895 S1: AsRef<str>,
896 S2: AsRef<str>,
897 F: Fn(&A, usize) -> S2,
898 {
899 let mut writer = Vec::<u8>::with_capacity(40 * self.vertices.len());
900 self.dot_from_container_index(
901 &mut writer,
902 dot_options,
903 |index, c|
904 f(c, index)
905 ).unwrap();
906 String::from_utf8(writer)
907 .unwrap()
908 }
909
910 /// * returns `None` **if** graph not connected **or** does not contain any vertices
911 /// * uses repeated breadth first search
912 pub fn diameter(&self) -> Option<usize> {
913 if !self.is_connected()? {
914 None
915 } else {
916 // well, then calculate from every node
917 // (except 1 node) and use maximum found
918
919 let mut max = 0;
920 let mut bfs = self.bfs_index_depth(0);
921 for index in 1..self.vertex_count() {
922 let mut depth = 0;
923 bfs.reuse(index);
924 for (.., d) in &mut bfs {
925 depth = d;
926 }
927 max = max.max(depth);
928 }
929
930 Some(max)
931 }
932 }
933
934 /// calculate the size of the longest shortest path **starting from** vertex with **index** `index`
935 /// using breadth first search
936 pub fn longest_shortest_path_from_index(&self, index: usize) -> Option<usize> {
937 let (.., depth) = self.bfs_index_depth(index)
938 .last()?;
939 Some(depth)
940 }
941
942 /// # calculate sizes of all binode connected components
943 /// * returns (reverse) **ordered vector of sizes**
944 /// i.e. the biggest component is of size `result[0]` and the smallest is of size `result[result.len() - 1]`
945 /// * destroys the underlying topology and therefore moves `self`
946 /// * if you still need your graph,
947 /// use `self.clone().vertex_biconnected_components(false/true)` for your calculations
948 /// # Definition: `vertex_biconnected_components(false)`
949 /// Here, the (vertex) biconnected component of a graph is defined as maximal subset of nodes,
950 /// where any one node could be removed and the remaining nodes would still be a connected component.
951 /// ## Note
952 /// Two vertices connected by an edge are considered to be biconnected, since after the
953 /// removal of one vertex (and the corresponding edge), only one vertex remains.
954 /// This vertex is in a connected component with itself.
955 /// # Alternative Definition: `vertex_biconnected_components(true)`
956 /// If you want to use the alternative definition:
957 /// > The biconnected component is defined as maximal subset of vertices, where each vertex can be
958 /// > reached by at least two node independent paths
959 ///
960 /// The alternative definition just removes all 2s from the result vector.
961 /// # Citations
962 /// I used the algorithm described in this paper:
963 /// > J. Hobcroft and R. Tarjan, "Algorithm 447: Efficient Algorithms for Graph Manipulation"
964 /// > *Commun. ACM*, **16**:372-378, 1973, DOI: [10.1145/362248.362272](https://doi.org/10.1145/362248.362272)
965 ///
966 /// You can also take a look at:
967 /// > M. E. J. Newman, "Networks: an Introduction" *Oxfort University Press*, 2010, ISBN: 978-0-19-920665-0.
968 pub fn vertex_biconnected_components(mut self, alternative_definition: bool) -> Vec<usize> {
969
970 let mut low: Vec<usize> = vec![0; self.vertex_count()];
971 let mut number: Vec<usize> = vec![0; self.vertex_count()];
972 let mut handled: Vec<bool> = vec![false; self.vertex_count()];
973 let mut edge_stack: Vec<(usize, usize)> = Vec::with_capacity(self.vertex_count());
974 let mut vertex_stack: Vec<usize> = Vec::with_capacity(self.vertex_count());
975 let mut biconnected_components: Vec<Vec<(usize, usize)>> = Vec::new();
976
977 let mut next_edge: (usize, usize);
978
979 for pivot in 0..self.vertex_count() {
980
981 if handled[pivot] {
982 continue;
983 }
984 low[pivot] = 0;
985 number[pivot] = 0;
986 handled[pivot] = true;
987 vertex_stack.push(pivot);
988
989 while let Some(&top_vertex) = vertex_stack.last() {
990 // if it has neighbors
991 // does the vertex have neighbors?
992 if self
993 .degree(top_vertex)
994 .unwrap() > 0
995 {
996 // remove one edge from graph, put it on stack
997 next_edge = (
998 top_vertex,
999 *self
1000 .container(top_vertex)
1001 .get_adj_first()
1002 .unwrap()
1003 );
1004 edge_stack.push(next_edge);
1005 let next_vertex = next_edge.1;
1006 self.remove_edge(next_edge.0, next_edge.1).unwrap();
1007
1008 // check if next_vertex is not handled yet
1009 if !handled[next_vertex] {
1010 // number new point
1011 number[next_vertex] = vertex_stack.len();
1012 // add to stack of points
1013 vertex_stack.push(next_edge.1);
1014 // set LOWPOINT of the new point to NUMBER of current point
1015 low[next_vertex] = number[top_vertex];
1016 // now the point was visited once -> handled
1017 handled[next_vertex] = true;
1018 }
1019 // Head of edge new point? NO -> Number of Head of edge lower than LOWPOINT of top point?
1020 else if number[next_vertex] < low[top_vertex] {
1021 // Set LOWPOINT of top Point to that number
1022 low[top_vertex] = number[next_vertex];
1023 }
1024 }
1025 // top point on stack has no edge
1026 else {
1027 vertex_stack.pop();
1028 // at least one point in stack?
1029 if let Some(&next_vertex) = vertex_stack.last() {
1030 // LOWPOINT of top point equals NUMBER of next point on stack?
1031 if low[top_vertex] == number[next_vertex]{
1032 let mut tmp_component: Vec<(usize, usize)> = Vec::new();
1033
1034 while let Some(current_edge) = edge_stack.last() {
1035 if number[current_edge.1] < number[next_vertex]
1036 || number[current_edge.0] < number[next_vertex]
1037 {
1038 break;
1039 }
1040 tmp_component.push(*current_edge);
1041 edge_stack.pop();
1042 }
1043 // add to biconnected_components
1044 if !tmp_component.is_empty(){
1045 biconnected_components.push(tmp_component);
1046 }
1047 }
1048 // LOWPOINT of top point equals NUMBER of next point on stack? NO
1049 else if low[top_vertex] < low[next_vertex] {
1050 // Set LOWPOINT of next point equal LOWPOINT of current point if less
1051 low[next_vertex] = low[top_vertex]
1052 }
1053
1054 }
1055 // no more vertices in stack stack?
1056 else {
1057 // exit loop
1058 break;
1059 }
1060 }
1061 }
1062 }
1063 let mut result = Vec::with_capacity(biconnected_components.len());
1064
1065 for component in biconnected_components {
1066 let mut size_set = HashSet::new();
1067 for edge in component {
1068 size_set.insert(edge.0);
1069 size_set.insert(edge.1);
1070 }
1071 result.push(size_set.len());
1072 }
1073
1074 if alternative_definition {
1075 result.retain(|&val| val > 2);
1076 }
1077 // sort by reverse
1078 // unstable here means inplace and ordering of equal elements is not guaranteed
1079 result.sort_unstable_by(
1080 |a, b|
1081 a.partial_cmp(b)
1082 .unwrap()
1083 .reverse()
1084 );
1085
1086 result
1087 }
1088
1089 /// # Closely related (most of the time equal) to betweeness
1090 /// ## calculates vertex_load of all vertices in O(edges * vertices)
1091 /// * calculates the vertex_load for every vertex
1092 /// * defined as how many shortest paths pass through each vertex
1093 ///
1094 /// | variant | |
1095 /// |---------------------|------------------------------------------------------------------------------------------------------------------------|
1096 /// | `vertex_load(true)` | includes endpoints in calculation (for a complete graph with `N` vertices, every node will have vertex_load `N - 1`) |
1097 /// | `vertex_load(false)` | excludes endpoints in calculation (for a complete graph with `N` vertices, every node will have vertex_load `0`) |
1098 /// # Citations
1099 /// I used the algorithm described in
1100 /// > M. E. J. Newman, "Scientific collaboration networks. II. Shortest paths, weighted networks, and centrality",
1101 /// > Phys. Rev. E **64**, 016132, 2001, DOI: [10.1103/PhysRevE.64.016132](https://doi.org/10.1103/PhysRevE.64.016132)
1102 ///
1103 /// see also:
1104 /// > M. E. J. Newman, "Erratum: Scientific collaboration networks. II. Shortest paths, weighted networks, and centrality",
1105 /// > Phys. Rev. E **73**, 039906, 2006, DOI: [10.1103/PhysRevE.73.039906](https://doi.org/10.1103/PhysRevE.73.039906)
1106 pub fn vertex_load(&self, include_endpoints: bool) -> Vec<f64> {
1107
1108 let mut queue0 = VecDeque::with_capacity(self.vertex_count());
1109 let mut queue1 = VecDeque::with_capacity(self.vertex_count());
1110 let mut ordering: Vec<usize> = Vec::with_capacity(self.vertex_count());
1111 let mut b = vec![0.0; self.vertex_count()];
1112 let mut b_k = vec![1f64; self.vertex_count()];
1113 let mut distance: Vec<Option<usize>> = vec![None; self.vertex_count()];
1114 let mut predecessor: Vec<Vec<usize>> = vec![Vec::new(); self.vertex_count()];
1115
1116
1117 for i in 0..self.vertex_count() {
1118
1119 // initialize without allocation
1120 if i > 0 {
1121 for j in 0..self.vertex_count()
1122 {
1123 b_k[j] = 1.0;
1124 distance[j] = None;
1125 // clear predecessors, way more efficient then new allocation
1126 predecessor[j].clear();
1127 }
1128 }
1129
1130
1131 let mut depth = 0;
1132 queue0.push_back(i);
1133 distance[i] = Some(depth);
1134
1135
1136 // build up predecessor and ordering information
1137 while let Some(index) = queue0.pop_front() {
1138 ordering.push(index); // to get indices in reverse order of distance
1139 let container = self.container(index);
1140 for &neighbor in container.neighbors() {
1141 if let Some(d) = distance[neighbor] {
1142 if d == depth + 1 {
1143 predecessor[neighbor].push(index);
1144 }
1145 }
1146 // None
1147 else {
1148 distance[neighbor] = Some(depth + 1);
1149 queue1.push_back(neighbor);
1150 predecessor[neighbor].push(index);
1151 }
1152 }
1153 if queue0.is_empty() {
1154 std::mem::swap(&mut queue0, &mut queue1);
1155 depth += 1;
1156 }
1157 }
1158
1159 // calculate vertex_load resulting from the shortest paths starting at vertex i
1160 while let Some(index) = ordering.pop() {
1161 // skip last vertex
1162 if ordering.is_empty(){
1163 break;
1164 }
1165 // add number of shortest path to total count
1166
1167 b[index] += b_k[index];
1168 if !include_endpoints {
1169 b[index] -= 1.0;
1170 }
1171
1172
1173 let fraction = b_k[index] / predecessor[index].len() as f64;
1174 for pred in predecessor[index].iter() {
1175 b_k[*pred] += fraction;
1176 }
1177 }
1178
1179 }
1180 b
1181 }
1182
1183 /// # Calculates transitivity of graph
1184 /// * related to cluster coefficient (Note: transitivity and cluster coefficient are similar,
1185 /// but **not** necessarily equal)
1186 /// * returns `NaN`, if there are no paths of length two in the graph
1187 /// ## Definition
1188 /// > transitivity = (number of closed paths of length two) / (number of paths of length two)
1189 /// ## Citations
1190 /// For the definition see for example:
1191 /// > M. E. J. Newman, "Networks: an Introduction" *Oxfort University Press*, 2010, ISBN: 978-0-19-920665-0.
1192 pub fn transitivity(&self) -> f64 {
1193 let mut path_count: usize = 0;
1194 let mut closed_path_count: usize = 0;
1195 for source_index in 0..self.vertex_count() {
1196 for neighbor_1 in self
1197 .container(source_index)
1198 .neighbors()
1199 {
1200 for neighbor_2 in self
1201 .container(*neighbor_1)
1202 .neighbors()
1203 .filter(|&i| *i != source_index) // do not use edge we came from
1204 {
1205 if self
1206 .container(*neighbor_2)
1207 .is_adjacent(source_index)
1208 {
1209 closed_path_count += 1;
1210 }
1211 path_count += 1;
1212 }
1213 }
1214 }
1215
1216 closed_path_count as f64 / path_count as f64
1217 }
1218
1219}
1220
1221impl<T, A> DotExtra<T, A> for GenericGraph<T, A>
1222where
1223 A: AdjContainer<T>,
1224{
1225 fn dot_from_container_index<F, S1, S2, W>(&self, mut writer: W, dot_options: S1, mut f: F)
1226 -> Result<(), std::io::Error>
1227 where
1228 S1: AsRef<str>,
1229 S2: AsRef<str>,
1230 F: FnMut(usize, &A) -> S2,
1231 W: Write
1232 {
1233 write!(writer, "graph G{{\n\t{}\n\t", dot_options.as_ref())?;
1234
1235 for i in 0..self.vertex_count() {
1236 write!(writer, "{} ", i)?;
1237 }
1238 writeln!(writer, ";")?;
1239
1240 for (index, container) in self.container_iter().enumerate() {
1241 let fun = f(index, container);
1242 writeln!(writer, "\t\"{}\" [label=\"{}\"];", index, fun.as_ref())?;
1243 }
1244
1245 for i in 0..self.vertex_count() {
1246 for &j in self.container(i).neighbors() {
1247 if i < j {
1248 writeln!(writer, "\t{} -- {}", i, j)?;
1249
1250 }
1251 }
1252 }
1253 write!(writer, "}}")
1254 }
1255
1256 fn dot_from_contained_index<F, S1, S2, W>(&self, writer: W, dot_options: S1, mut f: F)
1257 -> Result<(), std::io::Error>
1258 where
1259 W: Write,
1260 S1: AsRef<str>,
1261 S2: AsRef<str>,
1262 F: FnMut(usize, &T) -> S2
1263 {
1264 self.dot_from_container_index(
1265 writer,
1266 dot_options,
1267 |index, a| f(index, a.contained())
1268 )
1269 }
1270}
1271
1272impl<T, A> Dot for GenericGraph<T, A>
1273where T: Node,
1274 A: AdjContainer<T>
1275{
1276 fn dot_from_indices<F, W, S1, S2>(&self, mut writer: W, dot_options: S1, mut f: F) -> Result<(), std::io::Error>
1277 where
1278 S1: AsRef<str>,
1279 S2: AsRef<str>,
1280 W: Write,
1281 F: FnMut(usize) -> S2,
1282 {
1283 write!(writer, "graph G{{\n\t{}\n\t", dot_options.as_ref())?;
1284
1285 for i in 0..self.vertex_count() {
1286 write!(writer, "{} ", i)?;
1287 }
1288 writeln!(writer, ";")?;
1289
1290 for index in 0..self.vertex_count() {
1291 let fun = f(index);
1292 writeln!(writer, "\t\"{}\" [label=\"{}\"];", index, fun.as_ref())?;
1293 }
1294
1295 for i in 0..self.vertex_count() {
1296 for &j in self.container(i).neighbors() {
1297 if i < j {
1298 writeln!(writer, "\t{} -- {}", i, j)?;
1299
1300 }
1301 }
1302 }
1303 write!(writer, "}}")
1304 }
1305}
1306
1307// # Breadth first search Iterator with **index** and **depth** of corresponding nodes
1308/// * iterator returns tuple: `(index, node, depth)`
1309/// * iterator uses filter to decide, if a vertex should be considered
1310pub struct BfsFiltered<'a, 'b, T, A, F>
1311where T: 'a,
1312 A: AdjContainer<T>,
1313 F: FnMut(&T, usize) -> bool,
1314{
1315 graph: &'a GenericGraph<T, A>,
1316 handled: Vec<bool>,
1317 queue0: VecDeque<usize>,
1318 queue1: VecDeque<usize>,
1319 depth: usize,
1320 filter_fn: &'b mut F,
1321}
1322
1323impl<'a, 'b, T, A, F> BfsFiltered<'a, 'b, T, A, F>
1324where T: 'a,
1325 A: AdjContainer<T>,
1326 F: 'b + FnMut(&T, usize) -> bool,
1327{
1328 fn new(graph: &'a GenericGraph<T, A>, index: usize, filter: &'b mut F) -> Option<Self>
1329 {
1330 if index > graph.vertex_count() || !filter(graph.at(index), index) {
1331 return None;
1332 }
1333 let mut handled= vec![false; graph.vertex_count()];
1334 let mut queue0 = VecDeque::with_capacity(graph.vertex_count() / 2);
1335 let queue1 = VecDeque::with_capacity(graph.vertex_count() / 2);
1336
1337 queue0.push_back(index);
1338 handled[index] = true;
1339
1340 Some(
1341 Self{
1342 handled,
1343 graph,
1344 filter_fn: filter,
1345 queue0,
1346 queue1,
1347 depth: 0,
1348 }
1349 )
1350 }
1351
1352 /// At any state of the iterator, you can check if a given, valid Vertex, was encountered yet
1353 /// * Note: That can mean, that said vertex is still in the queue
1354 /// * **panics** if index is out of bounds
1355 pub fn is_handled(&self, index: usize) -> bool
1356 {
1357 self.handled[index]
1358 }
1359
1360 /// Efficiently reuse the iterator, now possibly starting at a new index
1361 /// * returns Err(self) without changing self, if index out of Bounds
1362 /// or filter (filter_fn) of (vertex_at_index, index) is false
1363 /// * otherwise: prepares iterator to be used again and returns Ok(self)
1364 pub fn reuse(mut self, index: usize) -> Result<Self, Self>
1365 {
1366 if index > self.graph.vertex_count() || !(self.filter_fn)(self.graph.at(index), index) {
1367 return Err(self);
1368 }
1369 for i in 0..self.handled.len() {
1370 self.handled[i] = false;
1371 }
1372 self.queue0.clear();
1373 self.queue1.clear();
1374 self.depth = 0;
1375
1376
1377 self.queue0.push_back(index);
1378 self.handled[index] = true;
1379 Ok(self)
1380 }
1381}
1382
1383impl<'a, 'b, T, A, F> Iterator for BfsFiltered<'a, 'b, T, A, F>
1384where T: 'a,
1385 A: AdjContainer<T>,
1386 F: 'b + FnMut(&T, usize) -> bool,
1387{
1388 type Item = (usize, &'a T, usize);
1389 fn next(&mut self) -> Option<Self::Item> {
1390 // if queue0 is not empty, take element from queue, push neighbors to other queue
1391 if let Some(index) = self.queue0.pop_front() {
1392 let container = self.graph.container(index);
1393 for &i in container.neighbors() {
1394 if self.handled[i] || !(self.filter_fn)(self.graph.at(i), i){
1395 continue;
1396 }
1397
1398 self.handled[i] = true;
1399 self.queue1.push_back(i);
1400
1401 }
1402 Some((index, container.contained(), self.depth))
1403 } else if self.queue1.is_empty() {
1404 None
1405 } else {
1406 std::mem::swap(&mut self.queue0, &mut self.queue1);
1407 self.depth += 1;
1408 self.next()
1409 }
1410 }
1411
1412 fn size_hint(&self) -> (usize, Option<usize>) {
1413 (self.queue0.len() + self.queue1.len(), Some(self.graph.vertex_count()))
1414 }
1415}
1416
1417/// # Breadth first search Iterator with **index** and **depth** of corresponding nodes
1418/// * iterator returns tuple: `(index, node, depth)`
1419pub struct Bfs<'a, T, A>
1420where T: 'a,
1421 A: AdjContainer<T>
1422{
1423 graph: &'a GenericGraph<T, A>,
1424 handled: Vec<bool>,
1425 queue0: VecDeque<usize>,
1426 queue1: VecDeque<usize>,
1427 depth: usize,
1428}
1429
1430impl<'a, T, A> Bfs<'a, T, A>
1431where T: 'a,
1432 A: AdjContainer<T>
1433{
1434 fn new(graph: &'a GenericGraph<T, A>, index: usize) -> Self {
1435 let mut handled= vec![false; graph.vertex_count()];
1436 let mut queue0 = VecDeque::with_capacity(graph.vertex_count() / 2);
1437 let queue1 = VecDeque::with_capacity(graph.vertex_count() / 2);
1438
1439 if index < graph.vertex_count() {
1440 queue0.push_back(index);
1441 handled[index] = true;
1442 }
1443
1444 Bfs {
1445 graph,
1446 handled,
1447 queue0,
1448 queue1,
1449 depth: 0,
1450 }
1451 }
1452
1453 fn reuse(&mut self, index: usize) {
1454 for i in 0..self.handled.len() {
1455 self.handled[i] = false;
1456 }
1457 self.queue0.clear();
1458 self.queue1.clear();
1459 self.depth = 0;
1460
1461 if index < self.graph.vertex_count() {
1462 self.queue0.push_back(index);
1463 self.handled[index] = true;
1464 }
1465 }
1466}
1467
1468/// # Iterator
1469/// - returns tuple: `(index, node, depth)`
1470impl<'a, T, A> Iterator for Bfs<'a, T, A>
1471where T: 'a,
1472 A: AdjContainer<T>
1473{
1474 type Item = (usize, &'a T, usize);
1475 fn next(&mut self) -> Option<Self::Item> {
1476 // if queue0 is not empty, take element from queue, push neighbors to other queue
1477 if let Some(index) = self.queue0.pop_front() {
1478 let container = self.graph.container(index);
1479 for &i in container.neighbors() {
1480 if !self.handled[i] {
1481 self.handled[i] = true;
1482 self.queue1.push_back(i);
1483 }
1484 }
1485 Some((index, container.contained(), self.depth))
1486 } else if self.queue1.is_empty() {
1487 None
1488 } else {
1489 std::mem::swap(&mut self.queue0, &mut self.queue1);
1490 self.depth += 1;
1491 self.next()
1492 }
1493 }
1494
1495 fn size_hint(&self) -> (usize, Option<usize>) {
1496 (self.queue0.len() + self.queue1.len(), Some(self.graph.vertex_count()))
1497 }
1498}
1499
1500/// Depth first search Iterator with **index** of corresponding nodes
1501pub struct DfsWithIndex<'a, T, A>
1502where T: 'a,
1503 A: AdjContainer<T>
1504{
1505 graph: &'a GenericGraph<T, A>,
1506 handled: Vec<bool>,
1507 stack: Vec<usize>,
1508}
1509
1510impl<'a, T, A> DfsWithIndex<'a, T, A>
1511 where T: 'a,
1512 A: AdjContainer<T>
1513{
1514
1515 fn new(graph: &'a GenericGraph<T, A>, index: usize) -> Self {
1516 let mut handled: Vec<bool> = vec![false; graph.vertex_count()];
1517 let mut stack: Vec<usize> = Vec::with_capacity(graph.vertex_count());
1518
1519 if index < handled.len()
1520 {
1521 stack.push(index);
1522 handled[index] = true;
1523 }
1524
1525 DfsWithIndex {
1526 graph,
1527 handled,
1528 stack,
1529 }
1530 }
1531
1532}
1533
1534impl<'a, T, A> Iterator for DfsWithIndex<'a, T, A>
1535where T: 'a,
1536 A: AdjContainer<T>
1537{
1538 type Item = (usize, &'a T);
1539
1540 fn next(&mut self) -> Option<Self::Item> {
1541 let index = self.stack.pop()?;
1542 let container = self.graph.container(index);
1543 for &i in container.neighbors() {
1544 if !self.handled[i] {
1545 self.handled[i] = true;
1546 self.stack.push(i);
1547 }
1548 }
1549 Some((index, container.contained()))
1550 }
1551
1552 fn size_hint(&self) -> (usize, Option<usize>) {
1553 (self.stack.len(), Some(self.graph.vertex_count()))
1554 }
1555}
1556
1557/// Depth first search Iterator
1558pub struct Dfs<'a, T, A>
1559where T: 'a,
1560 A: AdjContainer<T>
1561{
1562 graph: &'a GenericGraph<T, A>,
1563 handled: Vec<bool>,
1564 stack: Vec<usize>,
1565}
1566
1567
1568impl<'a, T, A> Dfs<'a, T, A>
1569where T: 'a,
1570 A: AdjContainer<T>
1571{
1572 fn new(graph: &'a GenericGraph<T, A>, index: usize) -> Self {
1573 let mut handled: Vec<bool> = vec![false; graph.vertex_count()];
1574 let mut stack: Vec<usize> = Vec::with_capacity(graph.vertex_count());
1575
1576 if index < handled.len()
1577 {
1578 stack.push(index);
1579 handled[index] = true;
1580 }
1581
1582 Dfs {
1583 graph,
1584 handled,
1585 stack,
1586 }
1587 }
1588}
1589
1590impl<'a, T, A> Iterator for Dfs<'a, T, A>
1591where T: 'a,
1592 A: AdjContainer<T>
1593{
1594 type Item = &'a T;
1595
1596 fn next(&mut self) -> Option<Self::Item> {
1597 let index = self.stack.pop()?;
1598 let container = self.graph.container(index);
1599 for &i in container.neighbors() {
1600 if !self.handled[i] {
1601 self.handled[i] = true;
1602 self.stack.push(i);
1603 }
1604 }
1605 Some(container.contained())
1606 }
1607
1608 fn size_hint(&self) -> (usize, Option<usize>) {
1609 (self.stack.len(), Some(self.graph.vertex_count()))
1610 }
1611}