1pub use crate::node::NodeTrait;
7
8use crate::edge::{AllEdges, CompactDirection, Direction, EdgeType, Edges, IntoWeightedEdge};
9use crate::node::Nodes;
10use crate::traverse::{Neighbors, NeighborsDirected};
11use indexmap::IndexMap;
12use std::fmt;
13use std::hash::Hash;
14use std::iter::FromIterator;
15use std::marker::PhantomData;
16
17#[derive(Copy, Debug)]
19pub enum Directed {}
20copyclone!(Directed);
21
22#[derive(Copy, Debug)]
24pub enum Undirected {}
25copyclone!(Undirected);
26
27pub type UndirectedGraph<N, E> = Graph<N, E, Undirected>;
32
33#[derive(Clone)]
56pub struct Graph<N, E, Ty = Directed> {
57 nodes: IndexMap<N, Vec<(N, CompactDirection)>>,
58 edges: IndexMap<(N, N), E>,
59 ty: PhantomData<Ty>,
60}
61
62impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType> fmt::Debug for Graph<N, E, Ty> {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 self.nodes.fmt(f)
65 }
66}
67
68impl<N, E, Ty> Graph<N, E, Ty>
69where
70 N: NodeTrait,
71 Ty: EdgeType,
72{
73 pub fn new() -> Self {
82 Self::default()
83 }
84
85 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
87 Self {
88 nodes: IndexMap::with_capacity(nodes),
89 edges: IndexMap::with_capacity(edges),
90 ty: PhantomData,
91 }
92 }
93
94 pub fn capacity(&self) -> (usize, usize) {
96 (self.nodes.capacity(), self.edges.capacity())
97 }
98
99 #[inline]
101 pub fn edge_key(a: N, b: N) -> (N, N) {
102 if Ty::is_directed() || a <= b {
103 (a, b)
104 } else {
105 (b, a)
106 }
107 }
108
109 pub fn is_directed(&self) -> bool {
111 Ty::is_directed()
112 }
113
114 pub fn from_edges<I>(iterable: I) -> Self
136 where
137 I: IntoIterator,
138 I::Item: IntoWeightedEdge<E, NodeId = N>,
139 {
140 Self::from_iter(iterable)
141 }
142
143 pub fn node_count(&self) -> usize {
145 self.nodes.len()
146 }
147
148 pub fn edge_count(&self) -> usize {
150 self.edges.len()
151 }
152
153 pub fn clear(&mut self) {
155 self.nodes.clear();
156 self.edges.clear();
157 }
158
159 pub fn add_node(&mut self, n: N) -> N {
161 self.nodes.entry(n).or_insert(Vec::new());
162 n
163 }
164
165 pub fn contains_node(&self, n: N) -> bool {
167 self.nodes.contains_key(&n)
168 }
169
170 pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
194 if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
195 old
196 } else {
197 self.nodes
199 .entry(a)
200 .or_insert_with(|| Vec::with_capacity(1))
201 .push((b, CompactDirection::Outgoing));
202
203 if a != b {
205 self.nodes
206 .entry(b)
207 .or_insert_with(|| Vec::with_capacity(1))
208 .push((a, CompactDirection::Incoming));
209 }
210
211 None
212 }
213 }
214
215 pub fn contains_edge(&self, a: N, b: N) -> bool {
217 self.edges.contains_key(&Self::edge_key(a, b))
218 }
219
220 pub fn nodes(&self) -> Nodes<N> {
224 Nodes::new(self.nodes.keys().cloned())
225 }
226
227 pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
235 let iter = match self.nodes.get(&a) {
236 Some(neigh) => neigh.iter(),
237 None => [].iter(),
238 };
239
240 Neighbors::new(iter, self.ty)
241 }
242
243 pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
254 let iter = match self.nodes.get(&a) {
255 Some(neigh) => neigh.iter(),
256 None => [].iter(),
257 };
258
259 NeighborsDirected::new(iter, dir, self.ty)
260 }
261
262 pub fn edges(&self, from: N) -> Edges<N, E, Ty> {
271 Edges::new(from, &self.edges, self.neighbors(from))
272 }
273
274 pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
277 self.edges.get(&Self::edge_key(a, b))
278 }
279
280 pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
283 self.edges.get_mut(&Self::edge_key(a, b))
284 }
285
286 pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
290 AllEdges::new(self.edges.iter(), self.ty)
291 }
292}
293
294impl<N, E, Ty> Default for Graph<N, E, Ty>
296where
297 N: NodeTrait,
298 Ty: EdgeType,
299{
300 fn default() -> Self {
301 Graph::with_capacity(0, 0)
302 }
303}
304
305impl<N, E, Ty, Item> FromIterator<Item> for Graph<N, E, Ty>
307where
308 Item: IntoWeightedEdge<E, NodeId = N>,
309 N: NodeTrait,
310 Ty: EdgeType,
311{
312 fn from_iter<I>(iterable: I) -> Self
313 where
314 I: IntoIterator<Item = Item>,
315 {
316 let iter = iterable.into_iter();
317 let (low, _) = iter.size_hint();
318 let mut g = Self::with_capacity(0, low);
319 g.extend(iter);
320 g
321 }
322}
323
324impl<N, E, Ty, Item> Extend<Item> for Graph<N, E, Ty>
328where
329 Item: IntoWeightedEdge<E, NodeId = N>,
330 N: NodeTrait,
331 Ty: EdgeType,
332{
333 fn extend<I>(&mut self, iterable: I)
334 where
335 I: IntoIterator<Item = Item>,
336 {
337 let iter = iterable.into_iter();
338 let (low, _) = iter.size_hint();
339 self.edges.reserve(low);
340
341 for elt in iter {
342 let (source, target, weight) = elt.into_weighted_edge();
343 self.add_edge(source, target, weight);
344 }
345 }
346}
347
348#[cfg(test)]
349mod tests {
350 use crate::edge::Direction::{Incoming, Outgoing};
351 use crate::graph::{Directed, Graph, Undirected};
352
353 #[test]
354 fn new() {
355 let graph: Graph<&str, f32> = Graph::new();
356
357 assert_eq!(graph.node_count(), 0);
359 assert_eq!(graph.edge_count(), 0);
360 }
361
362 #[test]
363 fn new_with_tuple_as_node() {
364 let graph: Graph<(&str, &str), f32> = Graph::new();
365
366 assert_eq!(graph.node_count(), 0);
368 assert_eq!(graph.edge_count(), 0);
369 }
370
371 #[test]
372 fn with_capacity() {
373 let graph: Graph<&str, f32> = Graph::with_capacity(4, 6);
374
375 assert_eq!(graph.node_count(), 0);
377 assert_eq!(graph.edge_count(), 0);
378 }
379
380 #[test]
381 fn capacity() {
382 let nodes_capacity = 4;
383 let edges_capacity = 8;
384
385 let graph: Graph<&str, f32> = Graph::with_capacity(nodes_capacity, edges_capacity);
386 let (n, e) = graph.capacity();
388 assert!(
390 n >= nodes_capacity,
391 "Allocated nodes capacity `{}` must be equal or bigger then requested capacity `{}`.",
392 n,
393 nodes_capacity
394 );
395 assert!(
397 e >= edges_capacity,
398 "Allocated edges capacity `{}` must be equal or bigger then requested capacity `{}`.",
399 e,
400 edges_capacity
401 );
402 }
403
404 #[test]
405 fn edge_key() {
406 assert_eq!(Graph::<&str, f32, Directed>::edge_key("a", "b"), ("a", "b"));
408 assert_eq!(Graph::<&str, f32, Directed>::edge_key("b", "a"), ("b", "a"));
409
410 assert_eq!(
412 Graph::<&str, f32, Undirected>::edge_key("a", "b"),
413 ("a", "b")
414 );
415 assert_eq!(
416 Graph::<&str, f32, Undirected>::edge_key("b", "a"),
417 ("a", "b")
418 );
419 }
420
421 #[test]
422 fn is_directed_true() {
423 let graph: Graph<&str, f32, Directed> = Graph::new();
424
425 assert_eq!(graph.is_directed(), true)
426 }
427
428 #[test]
429 fn is_directed_false() {
430 let graph: Graph<&str, f32, Undirected> = Graph::new();
431
432 assert_eq!(graph.is_directed(), false)
433 }
434
435 #[test]
436 fn from_edges() {
437 let graph = Graph::<_, _>::from_edges(&[
440 (0, 1, 0.12),
441 (0, 2, 0.99),
442 (0, 3, 0.1),
443 (1, 2, 0.9),
444 (1, 3, 0.44),
445 (2, 3, 0.8),
446 ]);
447
448 assert_eq!(graph.node_count(), 4);
450 assert_eq!(graph.edge_count(), 6);
451
452 assert_eq!(graph.edge_weight(0, 1), Some(&0.12));
454 assert_eq!(graph.edge_weight(2, 3), Some(&0.8));
455 }
456
457 #[test]
458 fn node_count() {
459 let mut graph: Graph<&str, f32> = Graph::new();
460
461 assert_eq!(graph.node_count(), 0);
463
464 graph.add_node("a");
465 graph.add_node("b");
466
467 assert_eq!(graph.node_count(), 2);
469 }
470
471 #[test]
472 fn edge_count() {
473 let mut graph: Graph<&str, f32> = Graph::new();
474
475 assert_eq!(graph.edge_count(), 0);
477
478 graph.add_edge("a", "b", 2.3);
479 graph.add_edge("b", "c", 4.1);
480
481 assert_eq!(graph.edge_count(), 2);
483 }
484
485 #[test]
486 fn clear() {
487 let mut graph: Graph<&str, f32> = Graph::new();
488
489 graph.add_edge("a", "b", 2.3);
491
492 assert_eq!(graph.node_count(), 2);
494 assert_eq!(graph.edge_count(), 1);
495
496 graph.clear();
497
498 assert_eq!(graph.node_count(), 0);
500 assert_eq!(graph.edge_count(), 0);
501 }
502
503 #[test]
504 fn add_node() {
505 let mut graph: Graph<&str, f32> = Graph::new();
506
507 graph.add_node("a");
509
510 assert_eq!(graph.node_count(), 1);
512 }
513
514 #[test]
515 fn add_node_as_tuple() {
516 let mut graph: Graph<(&str, &str), f32> = Graph::new();
517
518 graph.add_node(("s", "a"));
520
521 assert_eq!(graph.node_count(), 1);
523 }
524
525 #[test]
526 fn add_node_as_tuple_twide() {
527 let mut graph: Graph<(&str, &str), f32> = Graph::new();
528
529 graph.add_node(("s", "a"));
531 graph.add_node(("s", "a"));
532
533 assert_eq!(graph.node_count(), 1);
535 }
536
537 #[test]
538 fn add_edge() {
539 let mut graph: Graph<&str, f32> = Graph::new();
540
541 graph.add_edge("a", "b", 2.3);
543
544 assert_eq!(graph.node_count(), 2);
546 assert_eq!(graph.edge_count(), 1);
547 }
548
549 #[test]
550 fn add_edge_with_nodes_as_tuples() {
551 let mut graph: Graph<(&str, &str), f32> = Graph::new();
552
553 graph.add_edge(("s", "a"), ("r", "b"), 2.3);
555
556 assert_eq!(graph.node_count(), 2);
558 assert_eq!(graph.edge_count(), 1);
559 }
560
561 #[test]
562 fn edge_weight() {
563 let mut graph: Graph<&str, f32> = Graph::new();
564
565 let edge_weight = 2.4;
567 graph.add_edge("a", "b", edge_weight);
568
569 assert_eq!(graph.edge_weight("a", "b"), Some(&edge_weight));
571 }
572
573 #[test]
574 fn edge_weight_mut() {
575 let mut graph: Graph<&str, f32> = Graph::new();
576
577 let mut edge_weight = 2.4;
579 graph.add_edge("a", "b", edge_weight);
580
581 assert_eq!(graph.edge_weight_mut("a", "b"), Some(&mut edge_weight));
583 }
584
585 #[test]
586 fn edge_weight_with_nodes_as_tuples() {
587 let mut graph: Graph<(&str, &str), f32> = Graph::new();
588
589 let edge_weight = 2.4;
591 graph.add_edge(("s", "a"), ("r", "a"), 8.0);
592 graph.add_edge(("s", "a"), ("r", "a"), edge_weight);
593
594 assert_eq!(
596 graph.edge_weight(("s", "a"), ("r", "a")),
597 Some(&edge_weight)
598 );
599 }
600
601 #[test]
602 fn nodes() {
603 let mut graph: Graph<&str, f32> = Graph::new();
604
605 let list = ["a", "b", "c", "d"];
607
608 for index in list.iter() {
610 graph.add_node(*index);
611 }
612
613 for (i, node) in graph.nodes().enumerate() {
615 assert_eq!(list[i], node);
616 }
617 }
618
619 #[test]
620 fn check_nodes_and_edges() {
621 let mut graph: Graph<&str, f32> = Graph::with_capacity(4, 6);
622 graph.add_edge("a", "b", 2.0);
623
624 assert_eq!(graph.node_count(), 2);
625 assert_eq!(graph.edge_count(), 1);
626 assert!(graph.contains_edge("a", "b"));
627 assert!(!graph.contains_edge("b", "a"));
628
629 graph.add_edge("a", "c", 1.2);
630 graph.add_edge("a", "d", 4.2);
631 graph.add_edge("b", "c", 0.2);
632 graph.add_edge("b", "d", 3.3);
633 graph.add_edge("c", "b", 12.2);
634
635 assert_eq!(graph.node_count(), 4);
637 assert_eq!(graph.edge_count(), 6);
638
639 assert_eq!(graph.edge_weight("a", "b"), Some(&2.0));
641 assert_eq!(graph.edge_weight("a", "c"), Some(&1.2));
642
643 graph.add_edge("a", "b", 4.4);
645
646 assert_eq!(graph.edge_weight("a", "b"), Some(&4.4));
647
648 let weight = graph.edge_weight("c", "d");
650
651 assert_eq!(weight, None);
652 }
653
654 #[test]
655 fn fmt() {
656 let mut graph: Graph<u32, f32> = Graph::with_capacity(2, 1);
657 graph.add_edge(1, 2, 2.0);
658
659 let _text = print!("Debug::fmt() result:{:?}", graph);
660 }
661
662 #[test]
663 fn contains_node() {
664 let mut graph: Graph<u32, f32> = Graph::with_capacity(2, 0);
665 graph.add_node(1);
666 graph.add_node(2);
667
668 assert_eq!(graph.contains_node(1), true);
669 assert_eq!(graph.contains_node(2), true);
670 assert_eq!(graph.contains_node(3), false);
671 }
672
673 #[test]
674 fn contains_edge() {
675 let mut graph: Graph<u32, f32> = Graph::with_capacity(2, 1);
676 graph.add_edge(1, 2, 2.0);
677
678 assert_eq!(graph.contains_edge(1, 2), true);
679 assert_eq!(graph.contains_edge(1, 3), false);
680 }
681
682 #[test]
683 fn edges() {
684 let mut graph: Graph<u32, f32> = Graph::with_capacity(3, 3);
685 graph.add_edge(1, 2, 3.0);
686 graph.add_edge(2, 3, 5.0);
687 graph.add_edge(1, 3, 4.0);
688
689 let mut edges = graph.edges(1);
690
691 assert_eq!(edges.next(), Some((1, 2, &3.0)));
692 assert_eq!(edges.next(), Some((1, 3, &4.0)));
693 assert_eq!(edges.next(), None);
694 }
695
696 #[test]
697 fn all_edges() {
698 let mut graph: Graph<u32, f32> = Graph::with_capacity(3, 3);
699 graph.add_edge(1, 2, 3.0);
700 graph.add_edge(2, 3, 5.0);
701 graph.add_edge(1, 3, 4.0);
702
703 let mut edges = graph.all_edges();
704
705 assert_eq!(edges.next(), Some((1, 2, &3.0)));
706 assert_eq!(edges.next(), Some((2, 3, &5.0)));
707 assert_eq!(edges.next(), Some((1, 3, &4.0)));
708 assert_eq!(edges.next(), None);
709 }
710
711 #[test]
712 fn neighbors() {
713 let mut graph: Graph<u32, f32> = Graph::with_capacity(3, 3);
714 graph.add_edge(1, 2, 3.0);
715 graph.add_edge(2, 3, 5.0);
716 graph.add_edge(1, 3, 4.0);
717
718 let mut neighbors_1 = graph.neighbors(1);
720
721 assert_eq!(neighbors_1.next(), Some(2));
722 assert_eq!(neighbors_1.next(), Some(3));
723 assert_eq!(neighbors_1.next(), None);
724
725 let mut neighbors_2 = graph.neighbors(2);
727
728 assert_eq!(neighbors_2.next(), Some(3));
729 assert_eq!(neighbors_2.next(), None);
730
731 let mut neighbors_3 = graph.neighbors(3);
733
734 assert_eq!(neighbors_3.next(), None);
735
736 let mut neighbors_4 = graph.neighbors(4);
738 assert_eq!(neighbors_4.next(), None);
739 }
740
741 #[test]
742 fn neighbors_directed() {
743 let mut graph: Graph<u32, f32> = Graph::with_capacity(3, 3);
744 graph.add_edge(1, 2, 3.0);
745 graph.add_edge(2, 3, 5.0);
746 graph.add_edge(1, 3, 4.0);
747
748 let mut neighbors_1_incoming = graph.neighbors_directed(1, Incoming);
750
751 assert_eq!(neighbors_1_incoming.next(), None);
752
753 let mut neighbors_1_outgoing = graph.neighbors_directed(1, Outgoing);
755
756 assert_eq!(neighbors_1_outgoing.next(), Some(2));
757 assert_eq!(neighbors_1_outgoing.next(), Some(3));
758 assert_eq!(neighbors_1_outgoing.next(), None);
759
760 let mut neighbors_2_incoming = graph.neighbors_directed(2, Incoming);
762
763 assert_eq!(neighbors_2_incoming.next(), Some(1));
764 assert_eq!(neighbors_2_incoming.next(), None);
765
766 let mut neighbors_2_outgoing = graph.neighbors_directed(2, Outgoing);
768
769 assert_eq!(neighbors_2_outgoing.next(), Some(3));
770 assert_eq!(neighbors_2_outgoing.next(), None);
771
772 let mut neighbors_4 = graph.neighbors_directed(4, Incoming);
774 assert_eq!(neighbors_4.next(), None);
775 }
776}