File: qc.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 893,176 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (69 lines) | stat: -rw-r--r-- 1,999 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use petgraph::{graph::DiGraph, graphmap::NodeTrait};
use quickcheck::{Arbitrary, Gen, StdGen};
use std::ops::Deref;

#[derive(Copy, Clone, Debug)]
/// quickcheck Arbitrary adaptor - half the size of `T` on average
pub struct Small<T>(pub T);

impl<T> Deref for Small<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> Arbitrary for Small<T>
where
    T: Arbitrary,
{
    fn arbitrary<G: Gen>(g: &mut G) -> Self {
        let sz = g.size() / 2;
        Small(T::arbitrary(&mut StdGen::new(g, sz)))
    }

    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
        Box::new((**self).shrink().map(Small))
    }
}

#[cfg(feature = "stable_graph")]
/// A directed graph where each pair of nodes has exactly one edge between them, and no loops.
#[derive(Clone, Debug)]
pub struct Tournament<N, E>(pub DiGraph<N, E>);

/// `Arbitrary` for `Tournament` creates a graph with arbitrary node count, and exactly one edge of
/// arbitrary direction between each pair of nodes, and no loops. The average node count is reduced,
/// to mitigate the high edge count.
impl<N, E> Arbitrary for Tournament<N, E>
where
    N: NodeTrait + Arbitrary,
    E: Arbitrary,
{
    fn arbitrary<G: Gen>(g: &mut G) -> Self {
        let nodes = usize::arbitrary(g) / 4;
        if nodes == 0 {
            return Tournament(DiGraph::with_capacity(0, 0));
        }

        let mut gr = DiGraph::new();
        for _ in 0..nodes {
            gr.add_node(N::arbitrary(g));
        }
        for i in gr.node_indices() {
            for j in gr.node_indices() {
                if i >= j {
                    continue;
                }
                let (source, target) = if bool::arbitrary(g) { (i, j) } else { (j, i) };
                gr.add_edge(source, target, E::arbitrary(g));
            }
        }
        Tournament(gr)
    }

    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
        let Tournament(gr) = self;
        Box::new(gr.shrink().map(Tournament))
    }
}