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}