1use algs::{Components, Trees};
79use prelude::*;
80use props::Color;
81use sets::FastVecSet;
82
83use std::cmp;
84use std::mem;
85
86use fera_fun::set;
87use rand::prelude::*;
88use rand::distributions::Range;
89
90#[macro_export]
150macro_rules! graph {
151 () => (
152 {
153 use $crate::builder::WithBuilder;
154 WithBuilder::new_empty(0)
155 }
156 );
157
158 ($n:expr) => (
159 {
160 use $crate::builder::WithBuilder;
161 WithBuilder::new_empty($n)
162 }
163 );
164
165 ($n:expr, $(($u:expr, $v:expr)),+) => (
166 {
167 let edges = [$(($u, $v)),*];
168 $crate::builder::WithBuilder::new_with_edges($n, edges.iter().cloned())
169 }
170 );
171
172 ($n:expr, $(($u:expr, $v:expr)),+,) => (
173 graph!($n, $(($u, $v)),+)
174 );
175
176 ($n:expr, $(($u:expr, $v:expr) -> $p:expr),+) => (
177 {
178 let edges = [$(($u, $v, $p)),*];
179 $crate::builder::WithBuilder::new_with_edges_prop($n, &edges)
180 }
181 );
182
183 ($n:expr, $(($u:expr, $v:expr) -> $p:expr),+,) => (
184 graph!($n, $(($u, $v) -> $p),+)
185 );
186}
187
188pub trait Builder {
195 type Graph: WithEdge;
197
198 fn new(n: usize, m: usize) -> Self;
206
207 fn add_edge(&mut self, u: usize, v: usize);
213
214 fn finalize(self) -> Self::Graph;
216
217 #[doc(hidden)]
218 fn finalize_(
219 self,
220 ) -> (
221 Self::Graph,
222 Vec<Vertex<Self::Graph>>,
223 Vec<Edge<Self::Graph>>,
224 );
225}
226
227pub trait WithBuilder: WithEdge {
235 type Builder: Builder<Graph = Self>;
237
238 fn builder(num_vertices: usize, num_edges: usize) -> Self::Builder {
241 Self::Builder::new(num_vertices, num_edges)
242 }
243
244 fn new_with_edges<I>(n: usize, edges: I) -> Self
250 where
251 I: IntoIterator<Item = (usize, usize)>,
252 {
253 let edges = edges.into_iter();
254 let mut b = Self::Builder::new(n, edges.size_hint().1.unwrap_or(0));
255 for (u, v) in edges {
256 b.add_edge(u, v);
257 }
258 b.finalize()
259 }
260
261 #[doc(hidden)]
262 fn new_with_edges_prop<T>(
263 n: usize,
264 edges: &[(usize, usize, T)],
265 ) -> (Self, DefaultEdgePropMut<Self, T>)
266 where
267 T: Copy + Default,
268 Self: WithEdgeProp<T>,
269 {
270 let mut b = Self::Builder::new(n, edges.len());
272 for &(ref u, ref v, _) in edges {
273 b.add_edge(*u, *v);
274 }
275 let (g, _, ee) = b.finalize_();
276 let mut p = g.default_edge_prop(T::default());
277 for (e, val) in ee.into_iter().zip(edges.iter().map(|x| x.2)) {
278 p[e] = val;
279 }
280 (g, p)
281 }
282
283 fn new_empty(n: usize) -> Self {
285 Self::Builder::new(n, 0).finalize()
286 }
287
288 fn new_complete(n: usize) -> Self
292 where
293 Self: WithEdge<Kind = Undirected>,
294 {
295 complete::<Self>(n).finalize()
296 }
297
298 fn new_complete_binary_tree(h: u32) -> Self
303 where
304 Self: WithEdge<Kind = Undirected>,
305 {
306 complete_binary_tree::<Self>(h).finalize()
307 }
308
309 fn new_regular<R: Rng>(d: usize, n: usize, rng: R) -> Option<Self>
315 where
316 Self: WithEdge<Kind = Undirected>,
317 {
318 regular::<Self, R>(d, n, rng).map(Builder::finalize)
319 }
320
321 fn new_random_tree<R: Rng>(n: usize, rng: R) -> Self {
327 random_tree::<Self, _>(n, rng).finalize()
328 }
329
330 fn new_random_tree_with_diameter<R: Rng>(n: u32, d: u32, rng: R) -> Option<Self> {
334 random_tree_with_diameter::<Self, _>(n, d, rng).map(Builder::finalize)
335 }
336
337 fn new_gn<R>(n: usize, mut rng: R) -> Self
339 where
340 Self::Kind: UniformEdgeKind,
341 R: Rng,
342 {
343 let m = if n > 1 {
344 rng.gen_range(0, max_num_edges::<Self>(n))
345 } else {
346 0
347 };
348 Self::new_gnm(n, m, rng).unwrap()
349 }
350
351 fn new_gn_connected<R: Rng>(n: usize, mut rng: R) -> Self
353 where
354 Self::Kind: UniformEdgeKind,
355 {
356 let m = max_num_edges::<Self>(n);
357 let m = if m > n {
358 rng.gen_range(n, m)
359 } else {
360 cmp::min(n, m)
361 };
362 Self::new_gnm_connected(n, m, rng).unwrap()
363 }
364
365 fn new_gnm<R>(n: usize, m: usize, rng: R) -> Option<Self>
369 where
370 Self::Kind: UniformEdgeKind,
371 R: Rng,
372 {
373 gnm::<Self, _>(n, m, rng).map(Builder::finalize)
374 }
375
376 fn new_gnm_connected<R: Rng>(n: usize, m: usize, rng: R) -> Option<Self>
381 where
382 Self::Kind: UniformEdgeKind,
383 {
384 gnm_connected::<Self, _>(n, m, rng).map(Builder::finalize)
385 }
386}
387
388fn complete<G: WithBuilder>(n: usize) -> G::Builder {
389 let mut b = G::builder(n, (n * n - n) / 2);
390 for u in 0..n {
391 for v in u + 1..n {
392 b.add_edge(u, v);
393 }
394 }
395 b
396}
397
398fn complete_binary_tree<G: WithBuilder>(height: u32) -> G::Builder {
399 let num_vertices = 2usize.pow(height + 1) - 1;
400 let mut b = G::builder(num_vertices, num_vertices - 1);
401 for i in 0..2usize.pow(height) - 1 {
402 b.add_edge(i, 2 * i + 1);
403 b.add_edge(i, 2 * i + 2);
404 }
405 b
406}
407
408fn random_tree<G, R>(n: usize, rng: R) -> G::Builder
409where
410 G: WithBuilder,
411 R: Rng,
412{
413 if n == 0 {
414 return G::builder(0, 0);
415 }
416 let mut b = G::builder(n, n - 1);
417 for (u, v) in RandomTreeIter::new(n, rng) {
418 b.add_edge(u, v);
419 }
420 b
421}
422
423fn random_tree_with_diameter<G, R>(n: u32, d: u32, mut rng: R) -> Option<G::Builder>
424where
425 G: WithBuilder,
426 R: Rng,
427{
428 if n == 0 {
429 return if d == 0 { Some(G::builder(0, 0)) } else { None };
430 }
431
432 if d > n - 1 || n > 2 && d < 2 {
433 return None;
434 }
435
436 let mut b = G::builder(n as usize, (n - 1) as usize);
437 let mut vertices: Vec<_> = (0..n).collect();
438 let mut visited = vec![false; n as usize];
439 let mut maxd = vec![0; n as usize];
440 let g = CompleteGraph::new(n);
442 let mut dist = g.default_edge_prop(0);
443 let mut num_edges = 0;
444
445 rng.shuffle(&mut vertices);
447 vertices.truncate(d as usize + 1);
448 for i in 0..vertices.len() - 1 {
449 for j in (i + 1)..vertices.len() {
450 let (u, v) = (vertices[i], vertices[j]);
451 let duv = (j - i) as u32;
452 dist[g.edge_by_ends(u, v)] = duv;
453 maxd[u as usize] = maxd[u as usize].max(duv);
454 maxd[v as usize] = maxd[v as usize].max(duv);
455 }
456 b.add_edge(vertices[i] as usize, vertices[i + 1] as usize);
457 num_edges += 1;
458 }
459
460 if num_edges == n - 1 {
461 return Some(b);
462 }
463
464 let mut good = FastVecSet::new_vertex_set(&g);
466 for &v in &vertices {
467 visited[v as usize] = true;
468 }
469 for v in 0..n {
470 if maxd[v as usize] != d {
471 good.insert(v);
472 }
473 }
474
475 let mut cur = *good.choose(&mut rng).unwrap();
477 while !visited[cur as usize] {
478 cur = *good.choose(&mut rng).unwrap();
479 }
480 while num_edges != n - 1 {
481 if !good.contains(cur) {
483 cur = *good.choose(&mut rng).unwrap();
484 while !visited[cur as usize] {
485 cur = *good.choose(&mut rng).unwrap();
486 }
487 }
488 let v = *good.choose(&mut rng).unwrap();
489 if visited[v as usize] || cur == v {
490 cur = v;
491 continue;
492 }
493 assert!(maxd[cur as usize] < d);
494
495 for i in 0..n {
497 if i == cur {
498 continue;
499 }
500 let dci = dist[g.edge_by_ends(cur, i)];
501 if dci != 0 && v != i {
502 dist[g.edge_by_ends(v, i)] = dci + 1;
503 }
504 }
505
506 maxd[v as usize] = maxd[cur as usize] + 1;
508 if maxd[v as usize] == d {
509 good.remove(v);
510 }
511 for i in 0..n {
512 if v == i {
513 continue;
514 }
515 maxd[i as usize] = maxd[i as usize].max(dist[g.edge_by_ends(v, i)]);
516 if maxd[i as usize] == d && good.contains(i) {
517 good.remove(i);
518 }
519 assert!(maxd[i as usize] <= d);
520 }
521
522 b.add_edge(cur as usize, v as usize);
524 num_edges += 1;
525 visited[v as usize] = true;
526
527 cur = v;
529 }
530
531 Some(b)
532}
533
534fn max_num_edges<G>(n: usize) -> usize
535where
536 G: WithEdge,
537 G::Kind: UniformEdgeKind,
538{
539 if G::Kind::is_directed() {
540 n * n
541 } else {
542 (n * n - n) / 2
543 }
544}
545
546fn gnm_connected<G, R>(n: usize, m: usize, mut rng: R) -> Option<G::Builder>
547where
548 G: WithBuilder,
549 G::Kind: UniformEdgeKind,
550 R: Rng,
551{
552 use std::collections::HashSet;
553
554 if n == 0 {
555 return Some(G::builder(0, 0));
556 }
557
558 if m > max_num_edges::<G>(n) || m < n - 1 {
559 return None;
560 }
561
562 let mut b = G::builder(n, m);
563 let mut set = HashSet::new();
564 for (u, v) in RandomTreeIter::new(n, &mut rng) {
565 set.insert((u, v));
566 b.add_edge(u, v)
567 }
568
569 while set.len() != m {
570 let u = rng.gen_range(0, n);
571 let v = rng.gen_range(0, n);
572 if u == v || set.contains(&(u, v)) || G::Kind::is_undirected() && set.contains(&(v, u)) {
573 continue;
574 }
575 set.insert((u, v));
576 b.add_edge(u, v)
577 }
578
579 Some(b)
580}
581
582fn gnm<G, R>(n: usize, m: usize, mut rng: R) -> Option<G::Builder>
583where
584 G: WithBuilder,
585 G::Kind: UniformEdgeKind,
586 R: Rng,
587{
588 use std::collections::HashSet;
589
590 if m > max_num_edges::<G>(n) {
591 return None;
592 }
593
594 let mut b = G::builder(n, m);
595 let mut set = HashSet::new();
596 while set.len() != m {
597 let u = rng.gen_range(0, n);
598 let v = rng.gen_range(0, n);
599 if u == v || set.contains(&(u, v)) || G::Kind::is_undirected() && set.contains(&(v, u)) {
600 continue;
601 }
602 set.insert((u, v));
603 b.add_edge(u, v)
604 }
605
606 Some(b)
607}
608
609fn regular<G, R>(d: usize, n: usize, mut rng: R) -> Option<G::Builder>
610where
611 G: WithBuilder,
612 R: Rng,
613{
614 use fera_fun::vec;
615 use std::collections::HashSet;
616
617 let dn = d * n;
618
619 if d >= n {
620 return None;
621 }
622
623 if dn % 2 != 0 {
624 return None;
625 }
626
627 if d == 0 {
628 return Some(Builder::new(n, 0));
629 }
630
631 let max_tries = 10 * dn;
632 let mut edges = HashSet::new();
633 let mut u = vec((0..d).flat_map(|_| 0..n));
634 let mut len = u.len();
635 let mut tries = 0;
636 loop {
637 if tries == max_tries {
638 len = u.len();
639 edges.clear();
640 tries = 0;
641 }
642
643 let i = rng.gen_range(0, len);
644 let j = rng.gen_range(0, len);
645
646 if u[i] == u[j] {
647 tries += 1;
648 continue;
649 }
650
651 let (a, b) = if u[i] < u[j] {
653 (u[i], u[j])
654 } else {
655 (u[j], u[i])
656 };
657
658 if !edges.insert((a, b)) {
659 tries += 1;
660 continue;
661 }
662
663 if edges.len() == dn / 2 {
664 break;
665 }
666
667 if j == len - 1 {
668 u.swap(i, len - 2);
669 } else {
670 u.swap(i, len - 1);
671 u.swap(j, len - 2);
672 }
673 len -= 2;
674 }
675
676 let mut b = G::builder(n, edges.len());
677 for (u, v) in edges {
678 b.add_edge(u, v);
679 }
680 Some(b)
681}
682
683struct RandomTreeIter<R> {
686 visited: Vec<bool>,
687 rem: usize,
688 rng: R,
689 range: Range<usize>,
690 cur: usize,
691}
692
693impl<R: Rng> RandomTreeIter<R> {
694 fn new(n: usize, mut rng: R) -> Self {
695 let range = Range::new(0, n);
696 let cur = range.sample(&mut rng);
697 let mut visited = vec![false; n];
698 visited[cur] = true;
699 RandomTreeIter {
700 visited,
701 rem: n.checked_sub(1).unwrap_or(0),
702 rng,
703 range,
704 cur,
705 }
706 }
707}
708
709impl<R: Rng> Iterator for RandomTreeIter<R> {
710 type Item = (usize, usize);
711
712 fn next(&mut self) -> Option<Self::Item> {
713 if self.rem == 0 {
714 return None;
715 }
716 loop {
717 let v = self.range.sample(&mut self.rng);
718 if self.visited[v] {
719 self.cur = v;
720 } else {
721 self.rem -= 1;
722 self.visited[v] = true;
723 let u = mem::replace(&mut self.cur, v);
724 return Some((u, v));
725 }
726 }
727 }
728}
729
730#[doc(hidden)]
733pub trait BuilderTests {
734 type G: WithBuilder + VertexList + EdgeList;
735
736 fn graph_macro() {
737 let g: Self::G = graph!(5, (1, 2), (4, 0),);
738 assert_eq!(5, g.num_vertices());
739 assert_eq!(2, g.num_edges());
740 }
741
742 fn graph_prop_macro()
743 where
744 Self::G: WithEdgeProp<u32>,
745 {
746 let (g, w): (Self::G, _) = graph!(
747 5,
748 (1, 2) -> 3,
749 (4, 0) -> 4,
750 );
751 assert_eq!(5, g.num_vertices());
752 assert_eq!(2, g.num_edges());
753 let mut sum = 0;
754 for e in g.edges() {
755 sum += w[e];
756 }
757 assert_eq!(7, sum);
758 }
759
760 fn complete() {
761 let (g, v, e) = complete::<Self::G>(3).finalize_();
762 assert_eq!((v[0], v[1]), g.ends(e[0]));
763 assert_eq!((v[0], v[2]), g.ends(e[1]));
764 assert_eq!((v[1], v[2]), g.ends(e[2]));
765
766 for (n, &m) in (0..5).zip(&[0, 0, 1, 3, 6, 10]) {
767 let (g, v, _) = complete::<Self::G>(n).finalize_();
768 assert_eq!(n, g.num_vertices());
769 assert_eq!(m, g.num_edges());
770 assert_eq!(set(v), set(g.vertices()));
771 }
772 }
773
774 #[cfg_attr(feature = "cargo-clippy", allow(needless_range_loop))]
775 fn complete_binary_tree()
776 where
777 Self::G: Incidence + WithVertexProp<Color>,
778 {
779 let (g, _, _) = complete_binary_tree::<Self::G>(0).finalize_();
780 assert_eq!(1, g.num_vertices());
781 assert_eq!(0, g.num_edges());
782
783 let (g, v, _) = complete_binary_tree::<Self::G>(1).finalize_();
784 assert_eq!(3, g.num_vertices());
785 assert_eq!(2, g.num_edges());
786 assert_eq!(
787 set(vec![(v[0], v[1]), (v[0], v[2])]),
788 set(g.out_edges_ends(v[0]))
789 );
790
791 for h in 2..10 {
792 let (g, v, _) = complete_binary_tree::<Self::G>(h).finalize_();
793 assert!(g.is_tree());
794 assert_eq!(2, g.out_degree(v[0]));
795 for i in 1..g.num_vertices() / 2 - 1 {
796 assert_eq!(3, g.out_degree(v[i]));
797 }
798 for i in (g.num_vertices() / 2)..g.num_vertices() {
799 assert_eq!(1, g.out_degree(v[i]));
800 }
801 }
802 }
803
804 fn random_tree()
805 where
806 Self::G: Incidence + WithVertexProp<Color>,
807 {
808 let mut rng = SmallRng::from_entropy();
809 for n in 0..100 {
810 for _ in 0..10 {
811 let g = Self::G::new_random_tree(n, &mut rng);
812 assert_eq!(n, g.num_vertices());
813 if n > 0 {
814 assert_eq!(n - 1, g.num_edges());
815 }
816 assert!(g.is_tree());
817 }
818 }
819 }
820
821 fn gnm()
822 where
823 Self::G: WithEdge + VertexList + EdgeList,
824 <Self::G as WithEdge>::Kind: UniformEdgeKind,
825 {
826 let mut rng = SmallRng::from_entropy();
827
828 assert!(Self::G::new_gnm(4, 20, &mut rng).is_none());
829
830 for n in 0..10 {
831 for m in 0..30 {
832 if let Some(g) = Self::G::new_gnm(n, m, &mut rng) {
833 assert_eq!(n, g.num_vertices());
834 assert_eq!(m, g.num_edges());
835 }
836 }
837 }
838 }
839
840 fn gnm_connected()
841 where
842 Self::G: Incidence + WithVertexProp<Color>,
843 <Self::G as WithEdge>::Kind: UniformEdgeKind,
844 {
845 let mut rng = SmallRng::from_entropy();
846
847 assert!(Self::G::new_gnm_connected(4, 20, &mut rng).is_none());
848 assert!(Self::G::new_gnm_connected(4, 2, &mut rng).is_none());
849
850 for n in 1..10 {
851 for m in (n - 1)..30 {
852 if let Some(g) = Self::G::new_gnm_connected(n, m, &mut rng) {
853 assert!(g.is_connected());
854 assert_eq!(n, g.num_vertices());
855 assert_eq!(m, g.num_edges());
856 }
857 }
858 }
859 }
860
861 fn regular()
862 where
863 Self::G: Adjacency + WithEdge<Kind = Undirected> + VertexList,
864 {
865 use algs::degrees::Degrees;
866 let mut rng = SmallRng::from_entropy();
867 for d in 1..9 {
868 for n in (d + 1)..30 {
869 let g = Self::G::new_regular(d, n, &mut rng);
870 if n * d % 2 == 0 {
871 assert!(g.unwrap().is_k_regular(d));
872 } else {
873 assert!(g.is_none());
874 }
875 }
876 }
877 }
878}
879
880#[doc(hidden)]
881#[macro_export]
882macro_rules! graph_builder_tests {
883 ($T:ident) => {
884 delegate_tests!{
885 $T,
886 graph_macro,
887 graph_prop_macro,
888 complete,
889 complete_binary_tree,
890 random_tree,
891 gnm,
892 gnm_connected,
893 regular
894 }
895 };
896}
897
898#[cfg(test)]
899mod tests {
900 use super::*;
901
902 #[test]
903 fn random_tree_mean_diameter() {
904 let mut rng = SmallRng::from_entropy();
905 let n = 100;
906 let times = 1000;
907 let sum: Result<usize, _> = (0..times)
908 .map(|_| StaticGraph::new_random_tree(n, &mut rng).tree_diameter())
909 .sum();
910 let mean = sum.unwrap() / times;
911 assert!(27 == mean || 28 == mean || 29 == mean);
912 }
913}