Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
use petgraph::{
adj::List,
csr::Csr,
visit::{EdgeRef, GetAdjacencyMatrix, GraphProp, IntoEdgeReferences, IntoNodeIdentifiers},
Directed, EdgeType, Graph, Undirected,
};
#[cfg(feature = "graphmap")]
use petgraph::graphmap::GraphMap;
#[cfg(feature = "matrix_graph")]
use petgraph::matrix_graph::MatrixGraph;
#[cfg(feature = "stable_graph")]
use petgraph::stable_graph::StableGraph;
fn test_adjacency_matrix<G>(g: G)
where
G: GetAdjacencyMatrix + IntoNodeIdentifiers + IntoEdgeReferences + GraphProp,
{
let matrix = g.adjacency_matrix();
let node_ids: Vec<G::NodeId> = g.node_identifiers().collect();
let edges: Vec<(G::NodeId, G::NodeId)> = g
.edge_references()
.map(|edge| (edge.source(), edge.target()))
.collect();
for &a in &node_ids {
for &b in &node_ids {
if edges.contains(&(a, b)) || (!g.is_directed() && edges.contains(&(b, a))) {
assert!(g.is_adjacent(&matrix, a, b));
} else {
assert!(!g.is_adjacent(&matrix, a, b));
}
}
}
}
fn test_adjacency_matrix_for_graph<Ty: EdgeType>() {
for (order, edges) in TEST_CASES {
let mut g: Graph<(), (), Ty, u16> = Graph::with_capacity(order, edges.len());
for _ in 0..order {
g.add_node(());
}
g.extend_with_edges(edges);
test_adjacency_matrix(&g);
}
}
#[test]
fn test_adjacency_matrix_for_graph_directed() {
test_adjacency_matrix_for_graph::<Directed>();
}
#[test]
fn test_adjacency_matrix_for_graph_undirected() {
test_adjacency_matrix_for_graph::<Undirected>();
}
#[cfg(feature = "stable_graph")]
fn test_adjacency_matrix_for_stable_graph<Ty: EdgeType>() {
for (order, edges) in TEST_CASES {
let mut g: StableGraph<(), (), Ty, u16> = StableGraph::with_capacity(order, edges.len());
for _ in 0..order {
g.add_node(());
}
g.extend_with_edges(edges);
test_adjacency_matrix(&g);
}
}
#[cfg(feature = "stable_graph")]
#[test]
fn test_adjacency_matrix_for_stable_graph_directed() {
test_adjacency_matrix_for_stable_graph::<Directed>();
}
#[cfg(feature = "stable_graph")]
#[test]
fn test_adjacency_matrix_for_stable_graph_undirected() {
test_adjacency_matrix_for_stable_graph::<Undirected>();
}
#[cfg(feature = "graphmap")]
fn test_adjacency_matrix_for_graph_map<Ty: EdgeType>() {
for (order, edges) in TEST_CASES {
let mut g: GraphMap<u16, (), Ty> = GraphMap::with_capacity(order, edges.len());
for i in 0..order {
g.add_node(i as u16);
}
for &(a, b) in edges {
g.add_edge(a, b, ());
}
test_adjacency_matrix(&g);
}
}
#[cfg(feature = "graphmap")]
#[test]
fn test_adjacency_matrix_for_graph_map_directed() {
test_adjacency_matrix_for_graph_map::<Directed>();
}
#[cfg(feature = "graphmap")]
#[test]
fn test_adjacency_matrix_for_graph_map_undirected() {
test_adjacency_matrix_for_graph_map::<Undirected>();
}
#[cfg(feature = "matrix_graph")]
fn test_adjacency_matrix_for_matrix_graph<Ty: EdgeType>() {
for (order, edges) in TEST_CASES {
let mut g: MatrixGraph<(), (), Ty> = MatrixGraph::with_capacity(order);
for _ in 0..order {
g.add_node(());
}
g.extend_with_edges(edges);
test_adjacency_matrix(&g);
}
}
#[cfg(feature = "matrix_graph")]
#[test]
fn test_adjacency_matrix_for_matrix_graph_directed() {
test_adjacency_matrix_for_matrix_graph::<Directed>();
}
#[cfg(feature = "matrix_graph")]
#[test]
fn test_adjacency_matrix_for_matrix_graph_undirected() {
test_adjacency_matrix_for_matrix_graph::<Undirected>();
}
fn test_adjacency_matrix_for_csr<Ty: EdgeType>() {
for (order, edges) in TEST_CASES {
let mut g: Csr<(), (), Ty, u16> = Csr::new();
for _ in 0..order {
g.add_node(());
}
for &(a, b) in edges {
g.add_edge(a, b, ());
}
test_adjacency_matrix(&g);
}
}
#[test]
fn test_adjacency_matrix_for_csr_directed() {
test_adjacency_matrix_for_csr::<Directed>();
}
#[test]
fn test_adjacency_matrix_for_csr_undirected() {
test_adjacency_matrix_for_csr::<Undirected>();
}
#[test]
fn test_adjacency_matrix_for_adj_list() {
for (order, edges) in TEST_CASES {
let mut g: List<(), u16> = List::with_capacity(order);
for _ in 0..order {
g.add_node();
}
for &(a, b) in edges {
g.add_edge(a, b, ());
}
test_adjacency_matrix(&g);
}
}
// Test cases format: (graph order, graph edges)
#[rustfmt::skip]
const TEST_CASES: [(usize, &[(u16, u16)]); 10] = [
// Empty Graphs
(0, &[]),
(1, &[]),
(2, &[]),
// Graph with a loop
(2, &[(0, 0)]),
// Small Graphs
(5, &[(0, 2), (0, 4), (1, 3), (3, 4)]),
(6, &[(2, 3)]),
(9, &[(1, 4), (2, 8), (3, 7), (4, 8), (5, 8)]),
// Complete Graphs
(2, &[(0, 1)]),
(7, &[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]),
// Petersen
(10, &[(0, 1), (0, 4), (0, 5), (1, 2), (1, 6), (2, 3), (2, 7), (3, 4), (3, 8), (4, 9), (5, 7), (5, 8), (6, 8), (6, 9), (7, 9)]),
];

59
vendor/petgraph/tests/coloring.rs vendored Normal file
View File

@@ -0,0 +1,59 @@
use petgraph::algo::dsatur_coloring;
use petgraph::{Graph, Undirected};
#[test]
fn dsatur_coloring_cycle6() {
let mut graph: Graph<(), (), Undirected> = Graph::new_undirected();
let a = graph.add_node(());
let d = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let e = graph.add_node(());
let f = graph.add_node(());
graph.extend_with_edges(&[(a, b), (b, c), (c, d), (d, e), (e, f), (f, e)]);
let (coloring, nb_colors) = dsatur_coloring(&graph);
assert_eq!(nb_colors, 2);
assert_eq!(coloring.len(), 6);
}
#[test]
fn dsatur_coloring_bipartite() {
let mut graph: Graph<(), (), Undirected> = Graph::new_undirected();
let a = graph.add_node(());
let d = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let e = graph.add_node(());
let f = graph.add_node(());
let g = graph.add_node(());
let h = graph.add_node(());
let i = graph.add_node(());
let j = graph.add_node(());
let k = graph.add_node(());
let l = graph.add_node(());
graph.extend_with_edges(&[
(a, b),
(a, g),
(a, l),
(b, d),
(b, h),
(b, k),
(c, d),
(c, k),
(d, l),
(e, f),
(e, j),
(f, i),
(f, l),
(g, h),
(g, j),
(g, k),
(h, i),
(i, j),
(i, k),
]);
let (_, nb_colors) = dsatur_coloring(&graph);
assert_eq!(nb_colors, 2);
}

341
vendor/petgraph/tests/floyd_warshall.rs vendored Normal file
View File

@@ -0,0 +1,341 @@
use petgraph::algo::floyd_warshall;
use petgraph::{prelude::*, Directed, Graph, Undirected};
use std::collections::HashMap;
#[test]
fn floyd_warshall_uniform_weight() {
let mut graph: Graph<(), (), Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
let e = graph.add_node(());
let f = graph.add_node(());
let g = graph.add_node(());
let h = graph.add_node(());
graph.extend_with_edges(&[
(a, b),
(b, c),
(c, d),
(d, a),
(e, f),
(b, e),
(f, g),
(g, h),
(h, e),
]);
// a ----> b ----> e ----> f
// ^ | ^ |
// | v | v
// d <---- c h <---- g
let inf = std::i32::MAX;
let expected_res: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 2),
((a, d), 3),
((a, e), 2),
((a, f), 3),
((a, g), 4),
((a, h), 5),
((b, a), 3),
((b, b), 0),
((b, c), 1),
((b, d), 2),
((b, e), 1),
((b, f), 2),
((b, g), 3),
((b, h), 4),
((c, a), 2),
((c, b), 3),
((c, c), 0),
((c, d), 1),
((c, e), 4),
((c, f), 5),
((c, g), 6),
((c, h), 7),
((d, a), 1),
((d, b), 2),
((d, c), 3),
((d, d), 0),
((d, e), 3),
((d, f), 4),
((d, g), 5),
((d, h), 6),
((e, a), inf),
((e, b), inf),
((e, c), inf),
((e, d), inf),
((e, e), 0),
((e, f), 1),
((e, g), 2),
((e, h), 3),
((f, a), inf),
((f, b), inf),
((f, c), inf),
((f, d), inf),
((f, e), 3),
((f, f), 0),
((f, g), 1),
((f, h), 2),
((g, a), inf),
((g, b), inf),
((g, c), inf),
((g, d), inf),
((g, e), 2),
((g, f), 3),
((g, g), 0),
((g, h), 1),
((h, a), inf),
((h, b), inf),
((h, c), inf),
((h, d), inf),
((h, e), 1),
((h, f), 2),
((h, g), 3),
((h, h), 0),
]
.iter()
.cloned()
.collect();
let res = floyd_warshall(&graph, |_| 1_i32).unwrap();
let nodes = [a, b, c, d, e, f, g, h];
for node1 in &nodes {
for node2 in &nodes {
assert_eq!(
res.get(&(*node1, *node2)).unwrap(),
expected_res.get(&(*node1, *node2)).unwrap()
);
}
}
}
#[test]
fn floyd_warshall_weighted() {
let mut graph: Graph<(), (), Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
graph.extend_with_edges(&[(a, b), (a, c), (a, d), (b, c), (b, d), (c, d)]);
let inf = std::i32::MAX;
let expected_res: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 3),
((a, d), 3),
((b, a), inf),
((b, b), 0),
((b, c), 2),
((b, d), 2),
((c, a), inf),
((c, b), inf),
((c, c), 0),
((c, d), 2),
((d, a), inf),
((d, b), inf),
((d, c), inf),
((d, d), 0),
]
.iter()
.cloned()
.collect();
let weight_map: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 4),
((a, d), 10),
((b, b), 0),
((b, c), 2),
((b, d), 2),
((c, c), 0),
((c, d), 2),
]
.iter()
.cloned()
.collect();
let res = floyd_warshall(&graph, |edge| {
if let Some(weight) = weight_map.get(&(edge.source(), edge.target())) {
*weight
} else {
inf
}
})
.unwrap();
let nodes = [a, b, c, d];
for node1 in &nodes {
for node2 in &nodes {
assert_eq!(
res.get(&(*node1, *node2)).unwrap(),
expected_res.get(&(*node1, *node2)).unwrap()
);
}
}
}
#[test]
fn floyd_warshall_weighted_undirected() {
let mut graph: Graph<(), (), Undirected> = Graph::new_undirected();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
graph.extend_with_edges(&[(a, b), (a, c), (a, d), (b, d), (c, b), (c, d)]);
let inf = std::i32::MAX;
let expected_res: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 3),
((a, d), 3),
((b, a), 1),
((b, b), 0),
((b, c), 2),
((b, d), 2),
((c, a), 3),
((c, b), 2),
((c, c), 0),
((c, d), 2),
((d, a), 3),
((d, b), 2),
((d, c), 2),
((d, d), 0),
]
.iter()
.cloned()
.collect();
let weight_map: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 4),
((a, d), 10),
((b, b), 0),
((b, d), 2),
((c, b), 2),
((c, c), 0),
((c, d), 2),
]
.iter()
.cloned()
.collect();
let res = floyd_warshall(&graph, |edge| {
if let Some(weight) = weight_map.get(&(edge.source(), edge.target())) {
*weight
} else {
inf
}
})
.unwrap();
let nodes = [a, b, c, d];
for node1 in &nodes {
for node2 in &nodes {
assert_eq!(
res.get(&(*node1, *node2)).unwrap(),
expected_res.get(&(*node1, *node2)).unwrap()
);
}
}
}
#[test]
fn floyd_warshall_negative_cycle() {
let mut graph: Graph<(), (), Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
graph.extend_with_edges(&[(a, b), (b, c), (c, a)]);
let inf = std::i32::MAX;
let weight_map: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((b, b), 0),
((b, c), -3),
((c, c), 0),
((c, a), 1),
]
.iter()
.cloned()
.collect();
let res = floyd_warshall(&graph, |edge| {
if let Some(weight) = weight_map.get(&(edge.source(), edge.target())) {
*weight
} else {
inf
}
});
assert!(res.is_err());
}
#[test]
fn floyd_warshall_multiple_edges() {
let mut graph: Graph<(), i32, Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
graph.extend_with_edges(&[
(a, b, 10),
(a, b, 1),
(a, c, 4),
(a, d, 10),
(b, c, 2),
(b, d, 2),
(c, d, 2),
(a, d, 100),
(c, d, 20),
(a, a, 5),
]);
let inf = std::i32::MAX;
let expected_res: HashMap<(NodeIndex, NodeIndex), i32> = [
((a, a), 0),
((a, b), 1),
((a, c), 3),
((a, d), 3),
((b, a), inf),
((b, b), 0),
((b, c), 2),
((b, d), 2),
((c, a), inf),
((c, b), inf),
((c, c), 0),
((c, d), 2),
((d, a), inf),
((d, b), inf),
((d, c), inf),
((d, d), 0),
]
.iter()
.cloned()
.collect();
let res = floyd_warshall(&graph, |edge| *edge.weight()).unwrap();
let nodes = [a, b, c, d];
for node1 in &nodes {
for node2 in &nodes {
assert_eq!(
res.get(&(*node1, *node2)).unwrap(),
expected_res.get(&(*node1, *node2)).unwrap()
);
}
}
}

121
vendor/petgraph/tests/ford_fulkerson.rs vendored Normal file
View File

@@ -0,0 +1,121 @@
use petgraph::algo::ford_fulkerson;
use petgraph::prelude::Graph;
#[test]
fn test_ford_fulkerson() {
// Example from https://downey.io/blog/max-flow-ford-fulkerson-algorithm-explanation/
let mut graph = Graph::<usize, u16>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let destination = graph.add_node(3);
graph.extend_with_edges(&[(0, 1, 3), (0, 2, 2), (1, 2, 5), (1, 3, 2), (2, 3, 3)]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(5, max_flow);
// Example from https://brilliant.org/wiki/ford-fulkerson-algorithm/
let mut graph = Graph::<usize, f32>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let _ = graph.add_node(3);
let _ = graph.add_node(4);
let destination = graph.add_node(5);
graph.extend_with_edges(&[
(0, 1, 4.),
(0, 2, 3.),
(1, 3, 4.),
(2, 4, 6.),
(3, 2, 3.),
(3, 5, 2.),
(4, 5, 6.),
]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(7.0, max_flow);
// Example from https://cp-algorithms.com/graph/edmonds_karp.html
let mut graph = Graph::<usize, f32>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let _ = graph.add_node(3);
let _ = graph.add_node(4);
let destination = graph.add_node(5);
graph.extend_with_edges(&[
(0, 1, 7.),
(0, 2, 4.),
(1, 3, 5.),
(1, 4, 3.),
(2, 1, 3.),
(2, 4, 2.),
(3, 5, 8.),
(4, 3, 3.),
(4, 5, 5.),
]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(10.0, max_flow);
// Example from https://www.programiz.com/dsa/ford-fulkerson-algorithm (corrected: result not 6 but 5)
let mut graph = Graph::<u8, f32>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let _ = graph.add_node(3);
let _ = graph.add_node(4);
let destination = graph.add_node(5);
graph.extend_with_edges(&[
(0, 1, 8.),
(0, 2, 3.),
(1, 3, 9.),
(2, 3, 7.),
(2, 4, 4.),
(3, 5, 2.),
(4, 5, 5.),
]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(5.0, max_flow);
let mut graph = Graph::<u8, u8>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let _ = graph.add_node(3);
let _ = graph.add_node(4);
let destination = graph.add_node(5);
graph.extend_with_edges(&[
(0, 1, 16),
(0, 2, 13),
(1, 2, 10),
(1, 3, 12),
(2, 1, 4),
(2, 4, 14),
(3, 2, 9),
(3, 5, 20),
(4, 3, 7),
(4, 5, 4),
]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(23, max_flow);
// Example taken from https://medium.com/@jithmisha/solving-the-maximum-flow-problem-with-ford-fulkerson-method-3fccc2883dc7
let mut graph = Graph::<u8, u8>::new();
let source = graph.add_node(0);
let _ = graph.add_node(1);
let _ = graph.add_node(2);
let _ = graph.add_node(3);
let _ = graph.add_node(4);
let destination = graph.add_node(5);
graph.extend_with_edges(&[
(0, 1, 10),
(0, 2, 10),
(1, 2, 2),
(1, 3, 4),
(1, 4, 8),
(2, 4, 9),
(3, 5, 10),
(4, 3, 6),
(4, 5, 10),
]);
let (max_flow, _) = ford_fulkerson(&graph, source, destination);
assert_eq!(19, max_flow);
}

2454
vendor/petgraph/tests/graph.rs vendored Normal file

File diff suppressed because it is too large Load Diff

266
vendor/petgraph/tests/graph6.rs vendored Normal file

File diff suppressed because one or more lines are too long

443
vendor/petgraph/tests/graphmap.rs vendored Normal file
View File

@@ -0,0 +1,443 @@
#![cfg(feature = "graphmap")]
extern crate petgraph;
use std::collections::HashSet;
use std::fmt;
use petgraph::prelude::*;
use petgraph::visit::Walker;
use petgraph::algo::dijkstra;
use petgraph::dot::{Config, Dot};
#[test]
fn simple() {
//let root = TypedArena::<Node<_>>::new();
let mut gr = UnGraphMap::new();
//let node = |&: name: &'static str| Ptr(root.alloc(Node(name.to_string())));
let a = gr.add_node("A");
let b = gr.add_node("B");
let c = gr.add_node("C");
let d = gr.add_node("D");
let e = gr.add_node("E");
let f = gr.add_node("F");
gr.add_edge(a, b, 7);
gr.add_edge(a, c, 9);
gr.add_edge(a, d, 14);
gr.add_edge(b, c, 10);
gr.add_edge(c, d, 2);
gr.add_edge(d, e, 9);
gr.add_edge(b, f, 15);
gr.add_edge(c, f, 11);
assert!(gr.add_edge(e, f, 5).is_none());
// duplicate edges
assert_eq!(gr.add_edge(f, b, 16), Some(15));
assert_eq!(gr.add_edge(f, e, 6), Some(5));
println!("{:?}", gr);
println!("{}", Dot::with_config(&gr, &[]));
assert_eq!(gr.node_count(), 6);
assert_eq!(gr.edge_count(), 9);
// check updated edge weight
assert_eq!(gr.edge_weight(e, f), Some(&6));
let scores = dijkstra(&gr, a, None, |e| *e.weight());
let mut scores: Vec<_> = scores.into_iter().collect();
scores.sort();
assert_eq!(
scores,
vec![
("A", 0),
("B", 7),
("C", 9),
("D", 11),
("E", 20),
("F", 20)
]
);
}
#[test]
fn edges_directed() {
let mut gr = DiGraphMap::new();
let a = gr.add_node("A");
let b = gr.add_node("B");
let c = gr.add_node("C");
let d = gr.add_node("D");
let e = gr.add_node("E");
let f = gr.add_node("F");
gr.add_edge(a, b, 7);
gr.add_edge(a, c, 9);
gr.add_edge(a, d, 14);
gr.add_edge(b, c, 10);
gr.add_edge(c, d, 2);
gr.add_edge(d, e, 9);
gr.add_edge(b, f, 15);
gr.add_edge(c, f, 11);
let mut edges_out = gr.edges_directed(c, Direction::Outgoing);
assert_eq!(edges_out.next(), Some((c, d, &2)));
assert_eq!(edges_out.next(), Some((c, f, &11)));
assert_eq!(edges_out.next(), None);
let mut edges_in = gr.edges_directed(c, Direction::Incoming);
assert_eq!(edges_in.next(), Some((a, c, &9)));
assert_eq!(edges_in.next(), Some((b, c, &10)));
assert_eq!(edges_in.next(), None);
}
#[test]
fn remov() {
let mut g = UnGraphMap::new();
g.add_node(1);
g.add_node(2);
g.add_edge(1, 2, -1);
assert_eq!(g.edge_weight(1, 2), Some(&-1));
assert_eq!(g.edge_weight(2, 1), Some(&-1));
assert_eq!(g.neighbors(1).count(), 1);
let noexist = g.remove_edge(2, 3);
assert_eq!(noexist, None);
let exist = g.remove_edge(2, 1);
assert_eq!(exist, Some(-1));
assert_eq!(g.edge_count(), 0);
assert_eq!(g.edge_weight(1, 2), None);
assert_eq!(g.edge_weight(2, 1), None);
assert_eq!(g.neighbors(1).count(), 0);
}
#[test]
fn remove_node() {
// From #431
let mut graph = petgraph::graphmap::DiGraphMap::<u32, ()>::new();
graph.add_edge(1, 2, ());
graph.remove_node(2);
let neighbors: Vec<u32> = graph.neighbors(1).collect();
assert_eq!(neighbors, []);
let edges: Vec<(u32, u32, _)> = graph.all_edges().collect();
assert_eq!(edges, []);
}
#[test]
fn remove_directed() {
let mut g = GraphMap::<_, _, Directed>::with_capacity(0, 0);
g.add_edge(1, 2, -1);
println!("{:?}", g);
assert_eq!(g.edge_weight(1, 2), Some(&-1));
assert_eq!(g.edge_weight(2, 1), None);
assert_eq!(g.neighbors(1).count(), 1);
let noexist = g.remove_edge(2, 3);
assert_eq!(noexist, None);
let exist = g.remove_edge(2, 1);
assert_eq!(exist, None);
let exist = g.remove_edge(1, 2);
assert_eq!(exist, Some(-1));
println!("{:?}", g);
assert_eq!(g.edge_count(), 0);
assert_eq!(g.edge_weight(1, 2), None);
assert_eq!(g.edge_weight(2, 1), None);
assert_eq!(g.neighbors(1).count(), 0);
}
#[test]
fn dfs() {
let mut gr = UnGraphMap::default();
let h = gr.add_node("H");
let i = gr.add_node("I");
let j = gr.add_node("J");
let k = gr.add_node("K");
// Z is disconnected.
let z = gr.add_node("Z");
gr.add_edge(h, i, 1.);
gr.add_edge(h, j, 3.);
gr.add_edge(i, j, 1.);
gr.add_edge(i, k, 2.);
println!("{:?}", gr);
{
let mut cnt = 0;
let mut dfs = Dfs::new(&gr, h);
while dfs.next(&gr).is_some() {
cnt += 1;
}
assert_eq!(cnt, 4);
}
{
let mut cnt = 0;
let mut dfs = Dfs::new(&gr, z);
while dfs.next(&gr).is_some() {
cnt += 1;
}
assert_eq!(cnt, 1);
}
assert_eq!(Dfs::new(&gr, h).iter(&gr).count(), 4);
assert_eq!(Dfs::new(&gr, i).iter(&gr).count(), 4);
assert_eq!(Dfs::new(&gr, z).iter(&gr).count(), 1);
}
#[test]
fn edge_iterator() {
let mut gr = UnGraphMap::new();
let h = gr.add_node("H");
let i = gr.add_node("I");
let j = gr.add_node("J");
let k = gr.add_node("K");
gr.add_edge(h, i, 1);
gr.add_edge(h, j, 2);
gr.add_edge(i, j, 3);
gr.add_edge(i, k, 4);
let real_edges: HashSet<_> = gr.all_edges().map(|(a, b, &w)| (a, b, w)).collect();
let expected_edges: HashSet<_> =
vec![("H", "I", 1), ("H", "J", 2), ("I", "J", 3), ("I", "K", 4)]
.into_iter()
.collect();
assert_eq!(real_edges, expected_edges);
}
#[test]
fn from_edges() {
let gr =
GraphMap::<_, _, Undirected>::from_edges(&[("a", "b", 1), ("a", "c", 2), ("c", "d", 3)]);
assert_eq!(gr.node_count(), 4);
assert_eq!(gr.edge_count(), 3);
assert_eq!(gr[("a", "c")], 2);
let gr = GraphMap::<_, (), Undirected>::from_edges(&[
(0, 1),
(0, 2),
(0, 3),
(1, 2),
(1, 3),
(2, 3),
]);
assert_eq!(gr.node_count(), 4);
assert_eq!(gr.edge_count(), 6);
assert_eq!(gr.neighbors(0).count(), 3);
assert_eq!(gr.neighbors(1).count(), 3);
assert_eq!(gr.neighbors(2).count(), 3);
assert_eq!(gr.neighbors(3).count(), 3);
println!("{:?}", Dot::with_config(&gr, &[Config::EdgeNoLabel]));
}
#[test]
fn graphmap_directed() {
//let root = TypedArena::<Node<_>>::new();
let mut gr = DiGraphMap::<_, ()>::with_capacity(0, 0);
//let node = |&: name: &'static str| Ptr(root.alloc(Node(name.to_string())));
let a = gr.add_node("A");
let b = gr.add_node("B");
let c = gr.add_node("C");
let d = gr.add_node("D");
let e = gr.add_node("E");
let edges = [(a, b), (a, c), (a, d), (b, c), (c, d), (d, e), (b, b)];
gr.extend(&edges);
// Add reverse edges -- ok!
assert!(gr.add_edge(e, d, ()).is_none());
// duplicate edge - no
assert!(gr.add_edge(a, b, ()).is_some());
// duplicate self loop - no
assert!(gr.add_edge(b, b, ()).is_some());
println!("{:#?}", gr);
}
fn assert_sccs_eq<N>(mut res: Vec<Vec<N>>, mut answer: Vec<Vec<N>>)
where
N: Ord + fmt::Debug,
{
// normalize the result and compare with the answer.
for scc in &mut res {
scc.sort();
}
res.sort();
for scc in &mut answer {
scc.sort();
}
answer.sort();
assert_eq!(res, answer);
}
#[test]
fn scc() {
let gr: GraphMap<_, u32, Directed> = GraphMap::from_edges(&[
(6, 0, 0),
(0, 3, 1),
(3, 6, 2),
(8, 6, 3),
(8, 2, 4),
(2, 5, 5),
(5, 8, 6),
(7, 5, 7),
(1, 7, 8),
(7, 4, 9),
(4, 1, 10),
]);
assert_sccs_eq(
petgraph::algo::kosaraju_scc(&gr),
vec![vec![0, 3, 6], vec![1, 4, 7], vec![2, 5, 8]],
);
}
#[test]
fn test_into_graph() {
let gr: GraphMap<_, u32, Directed> = GraphMap::from_edges(&[
(6, 0, 0),
(0, 3, 1),
(3, 6, 2),
(8, 6, 3),
(8, 2, 4),
(2, 5, 5),
(5, 8, 6),
(7, 5, 7),
(1, 7, 8),
(7, 4, 9),
(4, 1, 10),
]);
let graph: Graph<_, _, _> = gr.clone().into_graph();
println!("{}", Dot::new(&gr));
println!("{}", Dot::new(&graph));
// node weigths in `graph` are node identifiers in `gr`.
for edge in graph.edge_references() {
let a = edge.source();
let b = edge.target();
let aw = graph[a];
let bw = graph[b];
assert_eq!(&gr[(aw, bw)], edge.weight());
}
}
#[test]
fn test_from_graph() {
let mut gr: Graph<u32, u32, Directed> = Graph::new();
let node_a = gr.add_node(12);
let node_b = gr.add_node(13);
let node_c = gr.add_node(14);
gr.add_edge(node_a, node_b, 1000);
gr.add_edge(node_b, node_c, 999);
gr.add_edge(node_c, node_a, 1111);
gr.add_node(42);
let gr = gr;
let graph: GraphMap<u32, u32, Directed> = GraphMap::from_graph(gr.clone());
println!("{}", Dot::new(&gr));
println!("{}", Dot::new(&graph));
assert!(petgraph::algo::is_isomorphic(&gr, &graph));
assert_eq!(graph[(12, 13)], 1000);
}
#[test]
fn test_all_edges_mut() {
// graph with edge weights equal to in+out
let mut graph: GraphMap<_, u32, Directed> =
GraphMap::from_edges(&[(0, 1, 1), (1, 2, 3), (2, 0, 2)]);
// change it so edge weight is equal to 2 * (in+out)
for (start, end, weight) in graph.all_edges_mut() {
*weight = (start + end) * 2;
}
// test it
for (start, end, weight) in graph.all_edges() {
assert_eq!((start + end) * 2, *weight);
}
}
#[test]
fn neighbors_incoming_includes_self_loops() {
let mut graph = DiGraphMap::new();
graph.add_node(());
graph.add_edge((), (), ());
let mut neighbors = graph.neighbors_directed((), Incoming);
assert_eq!(neighbors.next(), Some(()));
assert_eq!(neighbors.next(), None);
}
#[test]
fn undirected_neighbors_includes_self_loops() {
let mut graph = UnGraphMap::new();
graph.add_node(());
graph.add_edge((), (), ());
let mut neighbors = graph.neighbors(());
assert_eq!(neighbors.next(), Some(()));
assert_eq!(neighbors.next(), None);
}
#[test]
fn self_loops_can_be_removed() {
let mut graph = DiGraphMap::new();
graph.add_node(());
graph.add_edge((), (), ());
graph.remove_edge((), ());
assert_eq!(graph.neighbors_directed((), Outgoing).next(), None);
assert_eq!(graph.neighbors_directed((), Incoming).next(), None);
}
#[test]
#[cfg(feature = "rayon")]
fn test_parallel_iterator() {
use rayon::prelude::*;
let mut gr: DiGraphMap<u32, u32> = DiGraphMap::new();
for i in 0..1000 {
gr.add_node(i);
}
let serial_sum: u32 = gr.nodes().sum();
let parallel_sum: u32 = gr.par_nodes().sum();
assert_eq!(serial_sum, parallel_sum);
gr.par_nodes()
.enumerate()
.for_each(|(i, n)| assert_eq!(i as u32, n));
for i in 0..1000 {
gr.add_edge(i / 2, i, i + i / 2);
}
let serial_sum: u32 = gr.all_edges().map(|(.., &e)| e).sum();
let parallel_sum: u32 = gr.par_all_edges().map(|(.., &e)| e).sum();
assert_eq!(serial_sum, parallel_sum);
gr.par_all_edges_mut().for_each(|(n1, n2, e)| *e -= n1 + n2);
gr.all_edges().for_each(|(.., &e)| assert_eq!(e, 0));
}
#[test]
fn test_alternative_hasher() {
let mut gr: GraphMap<&str, u32, Directed, fxhash::FxBuildHasher> = GraphMap::new();
gr.add_node("abc");
gr.add_node("def");
gr.add_node("ghi");
gr.add_edge("abc", "def", 1);
assert!(gr.contains_edge("abc", "def"));
assert!(!gr.contains_edge("abc", "ghi"));
}

638
vendor/petgraph/tests/iso.rs vendored Normal file
View File

@@ -0,0 +1,638 @@
extern crate petgraph;
use std::collections::HashSet;
use std::fs::File;
use std::io::prelude::*;
use petgraph::graph::{edge_index, node_index};
use petgraph::prelude::*;
use petgraph::EdgeType;
use petgraph::algo::{
is_isomorphic, is_isomorphic_matching, is_isomorphic_subgraph, subgraph_isomorphisms_iter,
};
/// Petersen A and B are isomorphic
///
/// http://www.dharwadker.org/tevet/isomorphism/
const PETERSEN_A: &str = "
0 1 0 0 1 0 1 0 0 0
1 0 1 0 0 0 0 1 0 0
0 1 0 1 0 0 0 0 1 0
0 0 1 0 1 0 0 0 0 1
1 0 0 1 0 1 0 0 0 0
0 0 0 0 1 0 0 1 1 0
1 0 0 0 0 0 0 0 1 1
0 1 0 0 0 1 0 0 0 1
0 0 1 0 0 1 1 0 0 0
0 0 0 1 0 0 1 1 0 0
";
const PETERSEN_B: &str = "
0 0 0 1 0 1 0 0 0 1
0 0 0 1 1 0 1 0 0 0
0 0 0 0 0 0 1 1 0 1
1 1 0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 1 1
1 0 0 0 0 0 1 0 1 0
0 1 1 0 0 1 0 0 0 0
0 0 1 1 0 0 0 0 1 0
0 0 0 0 1 1 0 1 0 0
1 0 1 0 1 0 0 0 0 0
";
/// An almost full set, isomorphic
const FULL_A: &str = "
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 1 1 1 0 1
1 1 1 1 1 1 1 1 1 1
";
const FULL_B: &str = "
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 1 0 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
";
/// Praust A and B are not isomorphic
const PRAUST_A: &str = "
0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0
0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 0
";
const PRAUST_B: &str = "
0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0
1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1
0 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0 1 0 1 1 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1
0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1
0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 1 0
0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1
0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 1 0
";
const G1U: &str = "
0 1 1 0 1
1 0 1 0 0
1 1 0 0 0
0 0 0 0 0
1 0 0 0 0
";
const G2U: &str = "
0 1 0 1 0
1 0 0 1 1
0 0 0 0 0
1 1 0 0 0
0 1 0 0 0
";
const G4U: &str = "
0 1 1 0 1
1 0 0 1 0
1 0 0 0 0
0 1 0 0 0
1 0 0 0 0
";
const G1D: &str = "
0 1 1 0 1
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
";
const G4D: &str = "
0 1 1 0 1
0 0 0 1 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
";
// G8 1,2 are not iso
const G8_1: &str = "
0 1 1 0 0 1 1 1
1 0 1 0 1 0 1 1
1 1 0 1 0 0 1 1
0 0 1 0 1 1 1 1
0 1 0 1 0 1 1 1
1 0 0 1 1 0 1 1
1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 0
";
const G8_2: &str = "
0 1 0 1 0 1 1 1
1 0 1 0 1 0 1 1
0 1 0 1 0 1 1 1
1 0 1 0 1 0 1 1
0 1 0 1 0 1 1 1
1 0 1 0 1 0 1 1
1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 0
";
// G3 1,2 are not iso
const G3_1: &str = "
0 1 0
1 0 1
0 1 0
";
const G3_2: &str = "
0 1 1
1 0 1
1 1 0
";
// Non-isomorphic due to selfloop difference
const S1: &str = "
1 1 1
1 0 1
1 0 0
";
const S2: &str = "
1 1 1
0 1 1
1 0 0
";
/// Parse a text adjacency matrix format into a directed graph
fn parse_graph<Ty: EdgeType>(s: &str) -> Graph<(), (), Ty> {
let mut gr = Graph::with_capacity(0, 0);
let s = s.trim();
let lines = s.lines().filter(|l| !l.is_empty());
for (row, line) in lines.enumerate() {
for (col, word) in line.split(' ').filter(|s| !s.is_empty()).enumerate() {
let has_edge = word.parse::<i32>().unwrap();
assert!(has_edge == 0 || has_edge == 1);
if has_edge == 0 {
continue;
}
while col >= gr.node_count() || row >= gr.node_count() {
gr.add_node(());
}
gr.update_edge(node_index(row), node_index(col), ());
}
}
gr
}
fn str_to_graph(s: &str) -> Graph<(), (), Undirected> {
parse_graph(s)
}
fn str_to_digraph(s: &str) -> Graph<(), (), Directed> {
parse_graph(s)
}
/// Parse a file in adjacency matrix format into a directed graph
fn graph_from_file(path: &str) -> Graph<(), (), Directed> {
let mut f = File::open(path).expect("file not found");
let mut contents = String::new();
f.read_to_string(&mut contents)
.expect("failed to read from file");
parse_graph(&contents)
}
/*
fn graph_to_ad_matrix<N, E, Ty: EdgeType>(g: &Graph<N,E,Ty>)
{
let n = g.node_count();
for i in (0..n) {
for j in (0..n) {
let ix = NodeIndex::new(i);
let jx = NodeIndex::new(j);
let out = match g.find_edge(ix, jx) {
None => "0",
Some(_) => "1",
};
print!("{} ", out);
}
println!("");
}
}
*/
#[test]
fn petersen_iso() {
// The correct isomorphism is
// 0 => 0, 1 => 3, 2 => 1, 3 => 4, 5 => 2, 6 => 5, 7 => 7, 8 => 6, 9 => 8, 4 => 9
let peta = str_to_digraph(PETERSEN_A);
let petb = str_to_digraph(PETERSEN_B);
/*
println!("{:?}", peta);
graph_to_ad_matrix(&peta);
println!("");
graph_to_ad_matrix(&petb);
*/
assert!(petgraph::algo::is_isomorphic(&peta, &petb));
}
#[test]
fn petersen_undir_iso() {
// The correct isomorphism is
// 0 => 0, 1 => 3, 2 => 1, 3 => 4, 5 => 2, 6 => 5, 7 => 7, 8 => 6, 9 => 8, 4 => 9
let peta = str_to_digraph(PETERSEN_A);
let petb = str_to_digraph(PETERSEN_B);
assert!(petgraph::algo::is_isomorphic(&peta, &petb));
}
#[test]
fn full_iso() {
let a = str_to_graph(FULL_A);
let b = str_to_graph(FULL_B);
assert!(petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
#[cfg_attr(miri, ignore = "Takes too long to run in Miri")]
fn praust_dir_no_iso() {
let a = str_to_digraph(PRAUST_A);
let b = str_to_digraph(PRAUST_B);
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
#[cfg_attr(miri, ignore = "Takes too long to run in Miri")]
fn praust_undir_no_iso() {
let a = str_to_graph(PRAUST_A);
let b = str_to_graph(PRAUST_B);
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn coxeter_di_iso() {
// The correct isomorphism is
let a = str_to_digraph(COXETER_A);
let b = str_to_digraph(COXETER_B);
assert!(petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn coxeter_undi_iso() {
// The correct isomorphism is
let a = str_to_graph(COXETER_A);
let b = str_to_graph(COXETER_B);
assert!(petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn g14_dir_not_iso() {
let a = str_to_digraph(G1D);
let b = str_to_digraph(G4D);
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn g14_undir_not_iso() {
let a = str_to_digraph(G1U);
let b = str_to_digraph(G4U);
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn g12_undir_iso() {
let a = str_to_digraph(G1U);
let b = str_to_digraph(G2U);
assert!(petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn g3_not_iso() {
let a = str_to_digraph(G3_1);
let b = str_to_digraph(G3_2);
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn g8_not_iso() {
let a = str_to_digraph(G8_1);
let b = str_to_digraph(G8_2);
assert_eq!(a.edge_count(), b.edge_count());
assert_eq!(a.node_count(), b.node_count());
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn s12_not_iso() {
let a = str_to_digraph(S1);
let b = str_to_digraph(S2);
assert_eq!(a.edge_count(), b.edge_count());
assert_eq!(a.node_count(), b.node_count());
assert!(!petgraph::algo::is_isomorphic(&a, &b));
}
#[test]
fn iso1() {
let mut g0 = Graph::<_, ()>::new();
let mut g1 = Graph::<_, ()>::new();
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
// very simple cases
let a0 = g0.add_node(0);
let a1 = g1.add_node(0);
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
let b0 = g0.add_node(1);
let b1 = g1.add_node(1);
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
let _ = g0.add_node(2);
assert!(!petgraph::algo::is_isomorphic(&g0, &g1));
let _ = g1.add_node(2);
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
g0.add_edge(a0, b0, ());
assert!(!petgraph::algo::is_isomorphic(&g0, &g1));
g1.add_edge(a1, b1, ());
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
}
#[test]
fn iso2() {
let mut g0 = Graph::<_, ()>::new();
let mut g1 = Graph::<_, ()>::new();
let a0 = g0.add_node(0);
let a1 = g1.add_node(0);
let b0 = g0.add_node(1);
let b1 = g1.add_node(1);
let c0 = g0.add_node(2);
let c1 = g1.add_node(2);
g0.add_edge(a0, b0, ());
g1.add_edge(c1, b1, ());
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
// a -> b
// a -> c
// vs.
// c -> b
// c -> a
g0.add_edge(a0, c0, ());
g1.add_edge(c1, a1, ());
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
// add
// b -> c
// vs
// b -> a
let _ = g0.add_edge(b0, c0, ());
let _ = g1.add_edge(b1, a1, ());
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
let d0 = g0.add_node(3);
let d1 = g1.add_node(3);
let e0 = g0.add_node(4);
let e1 = g1.add_node(4);
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
// add
// b -> e -> d
// vs
// b -> d -> e
g0.add_edge(b0, e0, ());
g0.add_edge(e0, d0, ());
g1.add_edge(b1, d1, ());
g1.add_edge(d1, e1, ());
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
}
#[test]
fn iso_matching() {
let g0 = Graph::<(), _>::from_edges(&[(0, 0, 1), (0, 1, 2), (0, 2, 3), (1, 2, 4)]);
let mut g1 = g0.clone();
g1[edge_index(0)] = 0;
assert!(!is_isomorphic_matching(
&g0,
&g1,
|x, y| x == y,
|x, y| x == y
));
let mut g2 = g0.clone();
g2[edge_index(1)] = 0;
assert!(!is_isomorphic_matching(
&g0,
&g2,
|x, y| x == y,
|x, y| x == y
));
}
#[test]
fn iso_100n_100e() {
let g0 = str_to_digraph(include_str!("res/graph_100n_100e.txt"));
let g1 = str_to_digraph(include_str!("res/graph_100n_100e_iso.txt"));
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
}
#[test]
#[cfg_attr(miri, ignore = "Too large for Miri")]
fn iso_large() {
let g0 = graph_from_file("tests/res/graph_1000n_1000e.txt");
let g1 = graph_from_file("tests/res/graph_1000n_1000e.txt");
assert!(petgraph::algo::is_isomorphic(&g0, &g1));
}
// isomorphism isn't correct for multigraphs.
// Keep this testcase to document how
#[should_panic]
#[test]
fn iso_multigraph_failure() {
let g0 = Graph::<(), ()>::from_edges(&[(0, 0), (0, 0), (0, 1), (1, 1), (1, 1), (1, 0)]);
let g1 = Graph::<(), ()>::from_edges(&[(0, 0), (0, 1), (0, 1), (1, 1), (1, 0), (1, 0)]);
assert!(!is_isomorphic(&g0, &g1));
}
#[test]
#[cfg_attr(miri, ignore = "Takes too long to run in Miri")]
fn iso_subgraph() {
let g0 = Graph::<(), ()>::from_edges(&[(0, 1), (1, 2), (2, 0)]);
let g1 = Graph::<(), ()>::from_edges(&[(0, 1), (1, 2), (2, 0), (2, 3), (0, 4)]);
assert!(!is_isomorphic(&g0, &g1));
assert!(is_isomorphic_subgraph(&g0, &g1));
}
#[test]
#[cfg_attr(miri, ignore = "Takes too long to run in Miri")]
fn iter_subgraph() {
let a = Graph::<(), ()>::from_edges(&[(0, 1), (1, 2), (2, 0)]);
let b = Graph::<(), ()>::from_edges(&[(0, 1), (1, 2), (2, 0), (2, 3), (0, 4)]);
let a_ref = &a;
let b_ref = &b;
let mut node_match = { |x: &(), y: &()| x == y };
let mut edge_match = { |x: &(), y: &()| x == y };
let mappings =
subgraph_isomorphisms_iter(&a_ref, &b_ref, &mut node_match, &mut edge_match).unwrap();
// Verify the iterator returns the expected mappings
let expected_mappings: Vec<Vec<usize>> = vec![vec![0, 1, 2], vec![1, 2, 0], vec![2, 0, 1]];
for mapping in mappings {
assert!(expected_mappings.contains(&mapping))
}
// Verify all the mappings from the iterator are different
let a = str_to_digraph(COXETER_A);
let b = str_to_digraph(COXETER_B);
let a_ref = &a;
let b_ref = &b;
let mut unique = HashSet::new();
assert!(
subgraph_isomorphisms_iter(&a_ref, &b_ref, &mut node_match, &mut edge_match)
.unwrap()
.all(|x| unique.insert(x))
);
// The iterator should return None for graphs that are not isomorphic
let a = str_to_digraph(G8_1);
let b = str_to_digraph(G8_2);
let a_ref = &a;
let b_ref = &b;
assert!(
subgraph_isomorphisms_iter(&a_ref, &b_ref, &mut node_match, &mut edge_match)
.unwrap()
.next()
.is_none()
);
// https://github.com/petgraph/petgraph/issues/534
let mut g = Graph::<String, ()>::new();
let e1 = g.add_node("l1".to_string());
let e2 = g.add_node("l2".to_string());
g.add_edge(e1, e2, ());
let e3 = g.add_node("l3".to_string());
g.add_edge(e2, e3, ());
let e4 = g.add_node("l4".to_string());
g.add_edge(e3, e4, ());
let mut sub = Graph::<String, ()>::new();
let e3 = sub.add_node("l3".to_string());
let e4 = sub.add_node("l4".to_string());
sub.add_edge(e3, e4, ());
let mut node_match = { |x: &String, y: &String| x == y };
let mut edge_match = { |x: &(), y: &()| x == y };
assert_eq!(
subgraph_isomorphisms_iter(&&sub, &&g, &mut node_match, &mut edge_match)
.unwrap()
.collect::<Vec<_>>(),
vec![vec![2, 3]]
);
}
/// Isomorphic pair
const COXETER_A: &str = "
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
";
const COXETER_B: &str = "
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0
1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0
";

View File

@@ -0,0 +1,63 @@
use petgraph::algo::k_shortest_path;
use petgraph::prelude::*;
use petgraph::Graph;
use std::collections::HashMap;
#[test]
fn second_shortest_path() {
let mut graph: Graph<(), (), Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
let e = graph.add_node(());
let f = graph.add_node(());
let g = graph.add_node(());
let h = graph.add_node(());
let i = graph.add_node(());
let j = graph.add_node(());
let k = graph.add_node(());
let l = graph.add_node(());
let m = graph.add_node(());
graph.extend_with_edges(&[
(a, b),
(b, c),
(c, d),
(b, f),
(f, g),
(c, g),
(g, h),
(d, e),
(e, h),
(h, i),
(h, j),
(h, k),
(h, l),
(i, m),
(l, k),
(j, k),
(j, m),
(k, m),
(l, m),
(m, e),
]);
let res = k_shortest_path(&graph, a, None, 2, |_| 1);
let expected_res: HashMap<NodeIndex, usize> = [
(e, 7),
(g, 3),
(h, 4),
(i, 5),
(j, 5),
(k, 5),
(l, 5),
(m, 6),
]
.iter()
.cloned()
.collect();
assert_eq!(res, expected_res);
}

259
vendor/petgraph/tests/list.rs vendored Normal file
View File

@@ -0,0 +1,259 @@
extern crate itertools;
extern crate petgraph;
#[macro_use]
extern crate defmac;
use petgraph::adj::DefaultIx;
use petgraph::adj::IndexType;
use petgraph::adj::{List, UnweightedList};
use petgraph::algo::tarjan_scc;
use petgraph::data::{DataMap, DataMapMut};
use petgraph::dot::Dot;
use petgraph::prelude::*;
use petgraph::visit::{
IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNodeReferences, NodeCount, NodeIndexable,
};
use itertools::assert_equal;
fn n(x: u32) -> DefaultIx {
DefaultIx::new(x as _)
}
#[test]
fn node_indices() {
let mut g = List::<()>::new();
let a = g.add_node();
let b = g.add_node();
let c = g.add_node();
let mut iter = g.node_indices();
assert_eq!(iter.next(), Some(a));
assert_eq!(iter.next(), Some(b));
assert_eq!(iter.next(), Some(c));
assert_eq!(iter.next(), None);
}
fn test_node_count<E>(g: &List<E>, n: usize) {
assert_eq!(n, g.node_count());
assert_eq!(g.node_bound(), n);
assert_eq!(g.node_indices().count(), n);
assert_eq!(g.node_indices().len(), n);
assert_eq!(g.node_references().count(), n);
assert_eq!(g.node_references().len(), n);
}
#[test]
fn node_bound() {
let mut g = List::<()>::new();
test_node_count(&g, 0);
for i in 0..10 {
g.add_node();
test_node_count(&g, i + 1);
}
g.clear();
test_node_count(&g, 0);
}
fn assert_sccs_eq<Ix: IndexType>(mut res: Vec<Vec<Ix>>, normalized: Vec<Vec<Ix>>) {
// normalize the result and compare with the answer.
for scc in &mut res {
scc.sort();
}
// sort by minimum element
res.sort_by(|v, w| v[0].cmp(&w[0]));
assert_eq!(res, normalized);
}
fn scc_graph() -> UnweightedList<DefaultIx> {
let mut gr = List::new();
for _ in 0..9 {
gr.add_node();
}
for (a, b) in &[
(6, 0),
(0, 3),
(3, 6),
(8, 6),
(8, 2),
(2, 5),
(5, 8),
(7, 5),
(1, 7),
] {
gr.add_edge(n(*a), n(*b), ());
}
// make an identical replacement of n(4) and leave a hole
let x = gr.add_node();
gr.add_edge(n(7), x, ());
gr.add_edge(x, n(1), ());
gr
}
#[test]
fn test_tarjan_scc() {
let gr = scc_graph();
let x = n(gr.node_bound() as u32 - 1);
assert_sccs_eq(
tarjan_scc(&gr),
vec![
vec![n(0), n(3), n(6)],
vec![n(1), n(7), x],
vec![n(2), n(5), n(8)],
vec![n(4)],
],
);
}
fn make_graph() -> List<i32> {
let mut gr = List::new();
let mut c = 0..;
let mut e = || -> i32 { c.next().unwrap() };
for _ in 0..=9 {
gr.add_node();
}
for &(from, to) in &[
(6, 0),
(0, 3),
(3, 6),
(8, 6),
(8, 2),
(2, 5),
(5, 8),
(7, 5),
(1, 7),
(7, 9),
(8, 6), // parallel edge
(9, 1),
(9, 9),
(9, 9),
] {
gr.add_edge(n(from), n(to), e());
}
gr
}
defmac!(edges ref gr, x => gr.edges(x).map(|r| (r.target(), *r.weight())));
#[test]
fn test_edges_directed() {
let gr = make_graph();
dbg!(&gr);
let x = n(9);
assert_equal(edges!(&gr, x), vec![(1, 11), (x, 12), (x, 13)]);
assert_equal(edges!(&gr, n(0)), vec![(n(3), 1)]);
//assert_equal(edges!(&gr, n(4)), vec![]);
}
#[test]
fn test_edge_references() {
let mut gr = make_graph();
assert_eq!(gr.edge_count(), gr.edge_references().count());
for i in gr.edge_references() {
assert_eq!(gr.edge_endpoints(i.id()), Some((i.source(), i.target())));
assert_eq!(gr.edge_weight(i.id()), Some(i.weight()));
}
for n in gr.node_indices() {
for e in gr.edge_indices_from(n) {
match gr.edge_weight_mut(e) {
None => {}
Some(r) => {
*r = 1;
}
}
}
}
for i in gr.edge_references() {
assert_eq!(*i.weight(), 1);
}
}
#[test]
fn test_edge_iterators() {
let gr = make_graph();
for i in gr.node_indices() {
itertools::assert_equal(
gr.neighbors(n(i)),
gr.edges(n(i)).map(|r| {
assert_eq!(r.source(), n(i));
r.target()
}),
);
}
}
#[test]
#[should_panic(expected = "is not a valid node")]
fn add_edge_vacant() {
let mut g = List::new();
let a: DefaultIx = g.add_node();
let b = g.add_node();
let _ = g.add_node();
g.clear();
g.add_edge(a, b, 1);
}
#[test]
#[should_panic(expected = "is not a valid node")]
fn add_edge_oob() {
let mut g = List::new();
let a = g.add_node();
let _ = g.add_node();
let _ = g.add_node();
g.add_edge(a, n(4), 1);
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn add_edge_oob_2() {
let mut g = List::new();
let a = g.add_node();
let _ = g.add_node();
let _ = g.add_node();
g.add_edge(n(4), a, 1);
}
#[test]
fn test_node_references() {
let gr = scc_graph();
itertools::assert_equal(gr.node_references(), gr.node_indices());
}
#[test]
fn iterators_undir() {
let mut g = List::with_capacity(2);
let a = g.add_node();
let b = g.add_node();
let c = g.add_node();
let d = g.add_node();
for &(from, to, w) in &[(a, b, 1), (a, c, 2), (b, c, 3), (c, c, 4), (a, d, 5)] {
g.add_edge(n(from), n(to), w);
}
itertools::assert_equal(g.neighbors(a), vec![b, c, d]);
itertools::assert_equal(g.neighbors(c), vec![c]);
itertools::assert_equal(g.neighbors(d), vec![]);
itertools::assert_equal(g.neighbors(b), vec![c]);
}
#[test]
fn dot() {
let mut gr = List::new();
let a: DefaultIx = gr.add_node();
let b = gr.add_node();
gr.add_edge(a, a, 10u8);
gr.add_edge(a, b, 20);
let dot_output = format!("{:?}", Dot::new(&gr));
assert_eq!(
dot_output,
r#"digraph {
0 [ label = "()" ]
1 [ label = "()" ]
0 -> 0 [ label = "10" ]
0 -> 1 [ label = "20" ]
}
"#
);
}

141
vendor/petgraph/tests/matching.rs vendored Normal file
View File

@@ -0,0 +1,141 @@
use std::collections::HashSet;
use std::hash::Hash;
use petgraph::algo::{greedy_matching, maximum_matching};
use petgraph::prelude::*;
macro_rules! assert_one_of {
($actual:expr, [$($expected:expr),+]) => {
let expected = &[$($expected),+];
if !expected.iter().any(|expected| expected == &$actual) {
let expected = expected.iter().map(|e| format!("\n{:?}", e)).collect::<Vec<_>>();
let comma_separated = expected.join(", ");
panic!("assertion failed: `actual does not equal to any of expected`\nactual:\n{:?}\nexpected:{}", $actual, comma_separated);
}
};
}
macro_rules! set {
() => {
HashSet::new()
};
($(($source:expr, $target:expr)),+) => {
{
let mut set = HashSet::new();
$(
set.insert(($source.into(), $target.into()));
)*
set
}
};
($($elem:expr),+) => {
{
let mut set = HashSet::new();
$(
set.insert($elem.into());
)*
set
}
};
}
// So we don't have to type `.collect::<HashSet<_>>`.
fn collect<'a, T: Copy + Eq + Hash + 'a>(iter: impl Iterator<Item = T>) -> HashSet<T> {
iter.collect()
}
#[test]
fn greedy_empty() {
let g: UnGraph<(), ()> = UnGraph::default();
let m = greedy_matching(&g);
assert_eq!(collect(m.edges()), set![]);
assert_eq!(collect(m.nodes()), set![]);
}
#[test]
fn greedy_disjoint() {
let g: UnGraph<(), ()> = UnGraph::from_edges(&[(0, 1), (2, 3)]);
let m = greedy_matching(&g);
assert_eq!(collect(m.edges()), set![(0, 1), (2, 3)]);
assert_eq!(collect(m.nodes()), set![0, 1, 2, 3]);
}
#[test]
fn greedy_odd_path() {
let g: UnGraph<(), ()> = UnGraph::from_edges(&[(0, 1), (1, 2), (2, 3)]);
let m = greedy_matching(&g);
assert_one_of!(collect(m.edges()), [set![(0, 1), (2, 3)], set![(1, 2)]]);
assert_one_of!(collect(m.nodes()), [set![0, 1, 2, 3], set![1, 2]]);
}
#[test]
fn greedy_star() {
let g: UnGraph<(), ()> = UnGraph::from_edges(&[(0, 1), (0, 2), (0, 3)]);
let m = greedy_matching(&g);
assert_one_of!(
collect(m.edges()),
[set![(0, 1)], set![(0, 2)], set![(0, 3)]]
);
assert_one_of!(collect(m.nodes()), [set![0, 1], set![0, 2], set![0, 3]]);
}
#[test]
fn maximum_empty() {
let g: UnGraph<(), ()> = UnGraph::default();
let m = maximum_matching(&g);
assert_eq!(collect(m.edges()), set![]);
assert_eq!(collect(m.nodes()), set![]);
}
#[test]
fn maximum_disjoint() {
let g: UnGraph<(), ()> = UnGraph::from_edges(&[(0, 1), (2, 3)]);
let m = maximum_matching(&g);
assert_eq!(collect(m.edges()), set![(0, 1), (2, 3)]);
assert_eq!(collect(m.nodes()), set![0, 1, 2, 3]);
}
#[test]
fn maximum_odd_path() {
let g: UnGraph<(), ()> = UnGraph::from_edges(&[(0, 1), (1, 2), (2, 3)]);
let m = maximum_matching(&g);
assert_eq!(collect(m.edges()), set![(0, 1), (2, 3)]);
assert_eq!(collect(m.nodes()), set![0, 1, 2, 3]);
}
#[cfg(feature = "stable_graph")]
#[test]
fn maximum_in_stable_graph() {
let mut g: StableUnGraph<(), ()> =
StableUnGraph::from_edges(&[(0, 1), (0, 2), (1, 2), (1, 3), (2, 4), (3, 4), (3, 5)]);
// Create a hole by removing node that would otherwise belong to the maximum
// matching.
g.remove_node(NodeIndex::new(4));
let m = maximum_matching(&g);
assert_one_of!(
collect(m.edges()),
[
set![(0, 1), (3, 5)],
set![(0, 2), (1, 3)],
set![(0, 2), (3, 5)]
]
);
assert_one_of!(
collect(m.nodes()),
[set![0, 1, 3, 5], set![0, 2, 1, 3], set![0, 2, 3, 5]]
);
}
#[cfg(feature = "stable_graph")]
#[test]
fn is_perfect_in_stable_graph() {
let mut g: StableUnGraph<(), ()> = StableUnGraph::from_edges(&[(0, 1), (1, 2), (2, 3)]);
g.remove_node(NodeIndex::new(0));
g.remove_node(NodeIndex::new(1));
let m = maximum_matching(&g);
assert_eq!(m.len(), 1);
assert!(m.is_perfect());
}

View File

@@ -0,0 +1,59 @@
use petgraph::{algo::min_spanning_tree, dot::Dot, graph::UnGraph, Graph};
#[test]
fn mst() {
use petgraph::data::FromElements;
let mut gr = Graph::<_, _>::new();
let a = gr.add_node("A");
let b = gr.add_node("B");
let c = gr.add_node("C");
let d = gr.add_node("D");
let e = gr.add_node("E");
let f = gr.add_node("F");
let g = gr.add_node("G");
gr.add_edge(a, b, 7.);
gr.add_edge(a, d, 5.);
gr.add_edge(d, b, 9.);
gr.add_edge(b, c, 8.);
gr.add_edge(b, e, 7.);
gr.add_edge(c, e, 5.);
gr.add_edge(d, e, 15.);
gr.add_edge(d, f, 6.);
gr.add_edge(f, e, 8.);
gr.add_edge(f, g, 11.);
gr.add_edge(e, g, 9.);
// add a disjoint part
let h = gr.add_node("H");
let i = gr.add_node("I");
let j = gr.add_node("J");
gr.add_edge(h, i, 1.);
gr.add_edge(h, j, 3.);
gr.add_edge(i, j, 1.);
println!("{}", Dot::new(&gr));
let mst = UnGraph::from_elements(min_spanning_tree(&gr));
println!("{}", Dot::new(&mst));
println!("{:?}", Dot::new(&mst));
println!("MST is:\n{:#?}", mst);
assert!(mst.node_count() == gr.node_count());
// |E| = |N| - 2 because there are two disconnected components.
assert!(mst.edge_count() == gr.node_count() - 2);
// check the exact edges are there
assert!(mst.find_edge(a, b).is_some());
assert!(mst.find_edge(a, d).is_some());
assert!(mst.find_edge(b, e).is_some());
assert!(mst.find_edge(e, c).is_some());
assert!(mst.find_edge(e, g).is_some());
assert!(mst.find_edge(d, f).is_some());
assert!(mst.find_edge(h, i).is_some());
assert!(mst.find_edge(i, j).is_some());
assert!(mst.find_edge(d, b).is_none());
assert!(mst.find_edge(b, c).is_none());
}

40
vendor/petgraph/tests/operator.rs vendored Normal file
View File

@@ -0,0 +1,40 @@
use petgraph::operator::complement;
use petgraph::prelude::*;
use petgraph::Graph;
#[test]
fn test_complement() {
let mut graph: Graph<(), (), Directed> = Graph::new();
let a = graph.add_node(());
let b = graph.add_node(());
let c = graph.add_node(());
let d = graph.add_node(());
graph.extend_with_edges(&[(a, b), (b, c), (c, d)]);
let mut output: Graph<(), (), Directed> = Graph::new();
complement(&graph, &mut output, ());
let mut expected_res: Graph<(), (), Directed> = Graph::new();
let a = expected_res.add_node(());
let b = expected_res.add_node(());
let c = expected_res.add_node(());
let d = expected_res.add_node(());
expected_res.extend_with_edges(&[
(a, c),
(a, d),
(b, a),
(b, d),
(c, a),
(c, b),
(d, a),
(d, b),
(d, c),
]);
for x in graph.node_indices() {
for y in graph.node_indices() {
assert_eq!(output.contains_edge(x, y), expected_res.contains_edge(x, y));
}
}
}

83
vendor/petgraph/tests/page_rank.rs vendored Normal file
View File

@@ -0,0 +1,83 @@
use petgraph::{algo::page_rank, Graph};
#[cfg(feature = "rayon")]
use petgraph::algo::page_rank::parallel_page_rank;
fn graph_example() -> Graph<String, f32> {
// Taken and adapted from https://github.com/neo4j-labs/graph?tab=readme-ov-file#how-to-run-algorithms
let mut graph = Graph::<_, f32>::new();
graph.add_node("A".to_owned());
graph.add_node("B".to_owned());
graph.add_node("C".to_owned());
graph.add_node("D".to_owned());
graph.add_node("E".to_owned());
graph.add_node("F".to_owned());
graph.add_node("G".to_owned());
graph.add_node("H".to_owned());
graph.add_node("I".to_owned());
graph.add_node("J".to_owned());
graph.add_node("K".to_owned());
graph.add_node("L".to_owned());
graph.add_node("M".to_owned());
graph.extend_with_edges(&[
(1, 2), // B->C
(2, 1), // C->B
(4, 0), // D->A
(4, 1), // D->B
(5, 4), // E->D
(5, 1), // E->B
(5, 6), // E->F
(6, 1), // F->B
(6, 5), // F->E
(7, 1), // G->B
(7, 5), // F->E
(8, 1), // G->B
(8, 5), // G->E
(9, 1), // H->B
(9, 5), // H->E
(10, 1), // I->B
(10, 5), // I->E
(11, 5), // J->B
(12, 5), // K->B
]);
graph
}
fn expected_ranks() -> Vec<f32> {
vec![
0.029228685,
0.38176042,
0.3410649,
0.014170233,
0.035662483,
0.077429585,
0.035662483,
0.014170233,
0.014170233,
0.014170233,
0.014170233,
0.014170233,
0.014170233,
]
}
#[test]
fn test_page_rank() {
let graph = graph_example();
let output_ranks = page_rank(&graph, 0.85_f32, 100);
assert_eq!(expected_ranks(), output_ranks);
}
#[test]
#[cfg(feature = "rayon")]
fn test_par_page_rank() {
let graph = graph_example();
let output_ranks = parallel_page_rank(&graph, 0.85_f32, 100, Some(1e-12));
assert!(!expected_ranks()
.iter()
.zip(output_ranks)
.any(|(expected, computed)| ((expected - computed).abs() > 1e-6)
|| computed.is_nan()
|| expected.is_nan()));
}

1457
vendor/petgraph/tests/quickcheck.rs vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,100 @@
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

495
vendor/petgraph/tests/stable_graph.rs vendored Normal file
View File

@@ -0,0 +1,495 @@
#![cfg(feature = "stable_graph")]
extern crate itertools;
extern crate petgraph;
#[macro_use]
extern crate defmac;
use std::collections::HashSet;
use itertools::assert_equal;
use petgraph::algo::{kosaraju_scc, min_spanning_tree, tarjan_scc};
use petgraph::dot::Dot;
use petgraph::prelude::*;
use petgraph::stable_graph::edge_index as e;
use petgraph::stable_graph::node_index as n;
use petgraph::visit::{EdgeIndexable, IntoEdgeReferences, IntoNodeReferences, NodeIndexable};
use petgraph::EdgeType;
#[test]
fn node_indices() {
let mut g = StableGraph::<_, ()>::new();
let a = g.add_node(0);
let b = g.add_node(1);
let c = g.add_node(2);
g.remove_node(b);
let mut iter = g.node_indices();
assert_eq!(iter.next(), Some(a));
assert_eq!(iter.next(), Some(c));
assert_eq!(iter.next(), None);
}
#[test]
fn node_bound() {
let mut g = StableGraph::<_, ()>::new();
assert_eq!(g.node_bound(), g.node_count());
for i in 0..10 {
g.add_node(i);
assert_eq!(g.node_bound(), g.node_count());
}
let full_count = g.node_count();
g.remove_node(n(0));
g.remove_node(n(2));
assert_eq!(g.node_bound(), full_count);
g.clear();
assert_eq!(g.node_bound(), 0);
}
#[test]
fn edge_bound() {
let mut g = StableGraph::<_, _>::new();
assert_eq!(g.edge_bound(), g.edge_count());
for i in 0..10 {
g.add_node(i);
}
for i in 0..9 {
g.add_edge(n(i), n(i + 1), i);
assert_eq!(g.edge_bound(), g.edge_count());
}
let full_count = g.edge_count();
g.remove_edge(e(0));
g.remove_edge(e(2));
assert_eq!(g.edge_bound(), full_count);
g.clear();
assert_eq!(g.edge_bound(), 0);
}
#[test]
fn clear_edges() {
let mut gr = scc_graph();
gr.remove_node(n(1));
gr.clear_edges();
// check that we use the free list for the vacancies
assert_eq!(gr.add_node(()), n(1));
assert_eq!(gr.add_node(()), n(4));
assert!(gr.edge_references().next().is_none());
assert!(gr.node_indices().all(|i| gr.neighbors(i).next().is_none()));
}
fn assert_sccs_eq(mut res: Vec<Vec<NodeIndex>>, normalized: Vec<Vec<NodeIndex>>) {
// normalize the result and compare with the answer.
for scc in &mut res {
scc.sort();
}
// sort by minimum element
res.sort_by(|v, w| v[0].cmp(&w[0]));
assert_eq!(res, normalized);
}
fn scc_graph() -> StableGraph<(), ()> {
let mut gr: StableGraph<(), ()> = StableGraph::from_edges(&[
(6, 0),
(0, 3),
(3, 6),
(8, 6),
(8, 2),
(2, 5),
(5, 8),
(7, 5),
(1, 7),
(7, 4),
(4, 1),
]);
// make an identical replacement of n(4) and leave a hole
let x = gr.add_node(());
gr.add_edge(n(7), x, ());
gr.add_edge(x, n(1), ());
gr.remove_node(n(4));
gr
}
#[test]
fn test_scc() {
let gr = scc_graph();
println!("{:?}", gr);
let x = n(gr.node_bound() - 1);
assert_sccs_eq(
kosaraju_scc(&gr),
vec![
vec![n(0), n(3), n(6)],
vec![n(1), n(7), x],
vec![n(2), n(5), n(8)],
],
);
}
#[test]
fn test_tarjan_scc() {
let gr = scc_graph();
let x = n(gr.node_bound() - 1);
assert_sccs_eq(
tarjan_scc(&gr),
vec![
vec![n(0), n(3), n(6)],
vec![n(1), n(7), x],
vec![n(2), n(5), n(8)],
],
);
}
fn make_graph<Ty>() -> StableGraph<(), i32, Ty>
where
Ty: EdgeType,
{
let mut gr = StableGraph::default();
let mut c = 0..;
let mut e = || -> i32 { c.next().unwrap() };
gr.extend_with_edges(&[
(6, 0, e()),
(0, 3, e()),
(3, 6, e()),
(8, 6, e()),
(8, 2, e()),
(2, 5, e()),
(5, 8, e()),
(7, 5, e()),
(1, 7, e()),
(7, 4, e()),
(8, 6, e()), // parallel edge
(4, 1, e()),
]);
// make an identical replacement of n(4) and leave a hole
let x = gr.add_node(());
gr.add_edge(n(7), x, e());
gr.add_edge(x, n(1), e());
gr.add_edge(x, x, e()); // make two self loops
let rm_self_loop = gr.add_edge(x, x, e());
gr.add_edge(x, x, e());
gr.remove_node(n(4));
gr.remove_node(n(6));
gr.remove_edge(rm_self_loop);
gr
}
defmac!(edges ref gr, x => gr.edges(x).map(|r| (r.target(), *r.weight())));
#[test]
fn test_edges_directed() {
let gr = make_graph::<Directed>();
let x = n(9);
assert_equal(edges!(&gr, x), vec![(x, 16), (x, 14), (n(1), 13)]);
assert_equal(edges!(&gr, n(0)), vec![(n(3), 1)]);
assert_equal(edges!(&gr, n(4)), vec![]);
}
#[test]
fn test_edge_references() {
let gr = make_graph::<Directed>();
assert_eq!(gr.edge_count(), gr.edge_references().count());
}
#[test]
fn test_edges_undirected() {
let gr = make_graph::<Undirected>();
let x = n(9);
assert_equal(
edges!(&gr, x),
vec![(x, 16), (x, 14), (n(1), 13), (n(7), 12)],
);
assert_equal(edges!(&gr, n(0)), vec![(n(3), 1)]);
assert_equal(edges!(&gr, n(4)), vec![]);
}
#[test]
fn test_edge_iterators_directed() {
let gr = make_graph::<Directed>();
for i in gr.node_indices() {
itertools::assert_equal(gr.edges_directed(i, Outgoing), gr.edges(i));
for edge in gr.edges_directed(i, Outgoing) {
assert_eq!(
edge.source(),
i,
"outgoing edges should have a fixed source"
);
}
}
let mut incoming = vec![Vec::new(); gr.node_bound()];
for i in gr.node_indices() {
for j in gr.neighbors(i) {
incoming[j.index()].push(i);
}
}
println!("{:#?}", gr);
for i in gr.node_indices() {
itertools::assert_equal(
gr.edges_directed(i, Incoming).map(|e| e.source()),
incoming[i.index()].iter().rev().cloned(),
);
for edge in gr.edges_directed(i, Incoming) {
assert_eq!(
edge.target(),
i,
"incoming edges should have a fixed target"
);
}
}
}
#[test]
fn test_edge_iterators_undir() {
let gr = make_graph::<Undirected>();
for i in gr.node_indices() {
itertools::assert_equal(gr.edges_directed(i, Outgoing), gr.edges(i));
for edge in gr.edges_directed(i, Outgoing) {
assert_eq!(
edge.source(),
i,
"outgoing edges should have a fixed source"
);
}
}
for i in gr.node_indices() {
itertools::assert_equal(gr.edges_directed(i, Incoming), gr.edges(i));
for edge in gr.edges_directed(i, Incoming) {
assert_eq!(
edge.target(),
i,
"incoming edges should have a fixed target"
);
}
}
}
#[test]
#[should_panic(expected = "is not a node")]
fn add_edge_vacant() {
let mut g = StableGraph::<_, _>::new();
let a = g.add_node(0);
let b = g.add_node(1);
let _ = g.add_node(2);
let _ = g.remove_node(b);
g.add_edge(a, b, 1);
}
#[test]
#[should_panic(expected = "is not a node")]
fn add_edge_oob() {
let mut g = StableGraph::<_, _>::new();
let a = g.add_node(0);
let _ = g.add_node(1);
let _ = g.add_node(2);
g.add_edge(a, n(4), 1);
}
#[test]
fn test_node_references() {
let gr = scc_graph();
itertools::assert_equal(gr.node_references().map(|(i, _)| i), gr.node_indices());
}
#[test]
fn iterators_undir() {
let mut g = StableUnGraph::<_, _>::default();
let a = g.add_node(0);
let b = g.add_node(1);
let c = g.add_node(2);
let d = g.add_node(3);
g.extend_with_edges(&[(a, b, 1), (a, c, 2), (b, c, 3), (c, c, 4), (a, d, 5)]);
g.remove_node(b);
itertools::assert_equal(g.neighbors(a), vec![d, c]);
itertools::assert_equal(g.neighbors(c), vec![c, a]);
itertools::assert_equal(g.neighbors(d), vec![a]);
// the node that was removed
itertools::assert_equal(g.neighbors(b), vec![]);
// remove one more
g.remove_node(c);
itertools::assert_equal(g.neighbors(c), vec![]);
}
#[test]
fn iter_multi_edges() {
let mut gr = StableGraph::new();
let a = gr.add_node("a");
let b = gr.add_node("b");
let c = gr.add_node("c");
let mut connecting_edges = HashSet::new();
gr.add_edge(a, a, ());
connecting_edges.insert(gr.add_edge(a, b, ()));
gr.add_edge(a, c, ());
gr.add_edge(c, b, ());
connecting_edges.insert(gr.add_edge(a, b, ()));
gr.add_edge(b, a, ());
let mut iter = gr.edges_connecting(a, b);
let edge_id = iter.next().unwrap().id();
assert!(connecting_edges.contains(&edge_id));
connecting_edges.remove(&edge_id);
let edge_id = iter.next().unwrap().id();
assert!(connecting_edges.contains(&edge_id));
connecting_edges.remove(&edge_id);
assert_eq!(None, iter.next());
assert!(connecting_edges.is_empty());
}
#[test]
fn iter_multi_undirected_edges() {
let mut gr: StableUnGraph<_, _> = Default::default();
let a = gr.add_node("a");
let b = gr.add_node("b");
let c = gr.add_node("c");
let mut connecting_edges = HashSet::new();
gr.add_edge(a, a, ());
connecting_edges.insert(gr.add_edge(a, b, ()));
gr.add_edge(a, c, ());
gr.add_edge(c, b, ());
connecting_edges.insert(gr.add_edge(a, b, ()));
connecting_edges.insert(gr.add_edge(b, a, ()));
let mut iter = gr.edges_connecting(a, b);
let edge_id = iter.next().unwrap().id();
assert!(connecting_edges.contains(&edge_id));
connecting_edges.remove(&edge_id);
let edge_id = iter.next().unwrap().id();
assert!(connecting_edges.contains(&edge_id));
connecting_edges.remove(&edge_id);
let edge_id = iter.next().unwrap().id();
assert!(connecting_edges.contains(&edge_id));
connecting_edges.remove(&edge_id);
assert_eq!(None, iter.next());
assert!(connecting_edges.is_empty());
}
#[test]
fn dot() {
let mut gr = StableGraph::new();
let a = gr.add_node("x");
let b = gr.add_node("y");
gr.add_edge(a, a, "10");
gr.add_edge(a, b, "20");
let dot_output = format!("{}", Dot::new(&gr));
assert_eq!(
dot_output,
r#"digraph {
0 [ label = "x" ]
1 [ label = "y" ]
0 -> 0 [ label = "10" ]
0 -> 1 [ label = "20" ]
}
"#
);
}
defmac!(iter_eq a, b => a.eq(b));
defmac!(nodes_eq ref a, ref b => a.node_references().eq(b.node_references()));
defmac!(edgew_eq ref a, ref b => a.edge_references().eq(b.edge_references()));
defmac!(edges_eq ref a, ref b =>
iter_eq!(
a.edge_references().map(|e| (e.source(), e.target())),
b.edge_references().map(|e| (e.source(), e.target()))));
#[test]
fn from() {
let mut gr1 = StableGraph::new();
let a = gr1.add_node(1);
let b = gr1.add_node(2);
let c = gr1.add_node(3);
gr1.add_edge(a, a, 10);
gr1.add_edge(a, b, 20);
gr1.add_edge(b, c, 30);
gr1.add_edge(a, c, 40);
let gr2 = Graph::from(gr1.clone());
let gr3 = StableGraph::from(gr2);
assert!(nodes_eq!(&gr1, &gr3));
assert!(edgew_eq!(&gr1, &gr3));
assert!(edges_eq!(&gr1, &gr3));
gr1.remove_node(b);
let gr4 = Graph::from(gr1);
let gr5 = StableGraph::from(gr4.clone());
let mut ans = StableGraph::new();
let a = ans.add_node(1);
let c = ans.add_node(3);
ans.add_edge(a, a, 10);
ans.add_edge(a, c, 40);
assert!(nodes_eq!(&gr4, &ans));
assert!(edges_eq!(&gr4, &ans));
assert!(nodes_eq!(&gr5, &ans));
assert!(edgew_eq!(&gr5, &ans));
assert!(edges_eq!(&gr5, &ans));
}
use petgraph::data::FromElements;
use petgraph::stable_graph::StableGraph;
#[test]
fn from_min_spanning_tree() {
let mut g = StableGraph::new();
let mut nodes = Vec::new();
for _ in 0..6 {
nodes.push(g.add_node(()));
}
let es = [(4, 5), (3, 4), (3, 5)];
for &(a, b) in es.iter() {
g.add_edge(NodeIndex::new(a), NodeIndex::new(b), ());
}
for &node in nodes.iter().take(3) {
let _ = g.remove_node(node);
}
let _ = StableGraph::<(), (), Undirected, usize>::from_elements(min_spanning_tree(&g));
}
#[test]
fn weights_mut_iterator() {
let mut gr = StableGraph::new();
let a = gr.add_node(1);
let b = gr.add_node(2);
let c = gr.add_node(3);
let e1 = gr.add_edge(a, a, 10);
let e2 = gr.add_edge(a, b, 20);
let e3 = gr.add_edge(b, c, 30);
let e4 = gr.add_edge(a, c, 40);
for n in gr.node_weights_mut() {
*n += 1;
}
assert_eq!(gr[a], 2);
assert_eq!(gr[b], 3);
assert_eq!(gr[c], 4);
for e in gr.edge_weights_mut() {
*e -= 1;
}
assert_eq!(gr[e1], 9);
assert_eq!(gr[e2], 19);
assert_eq!(gr[e3], 29);
assert_eq!(gr[e4], 39);
// test on deletion
gr.remove_node(b);
assert_eq!(gr.node_weights_mut().count(), gr.node_count());
assert_eq!(gr.edge_weights_mut().count(), gr.edge_count());
}

105
vendor/petgraph/tests/unionfind.rs vendored Normal file
View File

@@ -0,0 +1,105 @@
extern crate petgraph;
extern crate rand;
use petgraph::unionfind::UnionFind;
use rand::{thread_rng, ChaChaRng, Rng, SeedableRng};
use std::collections::HashSet;
#[test]
fn uf_test() {
let n = 8;
let mut u = UnionFind::new(n);
for i in 0..n {
assert_eq!(u.find(i), i);
assert_eq!(u.find_mut(i), i);
assert!(!u.union(i, i));
}
u.union(0, 1);
assert_eq!(u.find(0), u.find(1));
u.union(1, 3);
u.union(1, 4);
u.union(4, 7);
assert_eq!(u.find(0), u.find(3));
assert_eq!(u.find(1), u.find(3));
assert!(u.find(0) != u.find(2));
assert_eq!(u.find(7), u.find(0));
u.union(5, 6);
assert_eq!(u.find(6), u.find(5));
assert!(u.find(6) != u.find(7));
// check that there are now 3 disjoint sets
let set = (0..n).map(|i| u.find(i)).collect::<HashSet<_>>();
assert_eq!(set.len(), 3);
}
#[test]
fn uf_test_with_equiv() {
let n = 8;
let mut u = UnionFind::new(n);
for i in 0..n {
assert_eq!(u.find(i), i);
assert_eq!(u.find_mut(i), i);
assert!(u.equiv(i, i));
}
u.union(0, 1);
assert!(u.equiv(0, 1));
u.union(1, 3);
u.union(1, 4);
u.union(4, 7);
assert!(u.equiv(0, 7));
assert!(u.equiv(1, 3));
assert!(!u.equiv(0, 2));
assert!(u.equiv(7, 0));
u.union(5, 6);
assert!(u.equiv(6, 5));
assert!(!u.equiv(6, 7));
// check that there are now 3 disjoint sets
let set = (0..n).map(|i| u.find(i)).collect::<HashSet<_>>();
assert_eq!(set.len(), 3);
}
#[test]
fn uf_rand() {
let n = 1 << 14;
let mut rng = ChaChaRng::from_rng(thread_rng()).unwrap();
let mut u = UnionFind::new(n);
for _ in 0..100 {
let a = rng.gen_range(0, n);
let b = rng.gen_range(0, n);
let ar = u.find(a);
let br = u.find(b);
assert_eq!(ar != br, u.union(a, b));
}
}
#[test]
fn uf_u8() {
let n = 256;
let mut rng = ChaChaRng::from_rng(thread_rng()).unwrap();
let mut u = UnionFind::<u8>::new(n);
for _ in 0..(n * 8) {
let a = rng.gen();
let b = rng.gen();
let ar = u.find(a);
let br = u.find(b);
assert_eq!(ar != br, u.union(a, b));
}
}
#[test]
fn labeling() {
let mut u = UnionFind::<u32>::new(48);
for i in 0..24 {
u.union(i + 1, i);
}
for i in 25..47 {
u.union(i, i + 1);
}
u.union(23, 25);
u.union(24, 23);
let v = u.into_labeling();
assert!(v.iter().all(|x| *x == v[0]));
}

3
vendor/petgraph/tests/utils/mod.rs vendored Normal file
View File

@@ -0,0 +1,3 @@
mod qc;
pub use self::qc::*;

69
vendor/petgraph/tests/utils/qc.rs vendored Normal file
View File

@@ -0,0 +1,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))
}
}