Fixed database typo and removed unnecessary class identifier.
This commit is contained in:
parent
00ad49a143
commit
45fb349a7d
5098 changed files with 952558 additions and 85 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,27 @@
|
|||
"""Unit tests for the beam search functions."""
|
||||
|
||||
import networkx as nx
|
||||
|
||||
|
||||
def identity(x):
|
||||
return x
|
||||
|
||||
|
||||
class TestBeamSearch:
|
||||
"""Unit tests for the beam search function."""
|
||||
|
||||
def test_narrow(self):
|
||||
"""Tests that a narrow beam width may cause an incomplete search."""
|
||||
# In this search, we enqueue only the neighbor 3 at the first
|
||||
# step, then only the neighbor 2 at the second step. Once at
|
||||
# node 2, the search chooses node 3, since it has a higher value
|
||||
# that node 1, but node 3 has already been visited, so the
|
||||
# search terminates.
|
||||
G = nx.cycle_graph(4)
|
||||
edges = nx.bfs_beam_edges(G, 0, identity, width=1)
|
||||
assert list(edges) == [(0, 3), (3, 2)]
|
||||
|
||||
def test_wide(self):
|
||||
G = nx.cycle_graph(4)
|
||||
edges = nx.bfs_beam_edges(G, 0, identity, width=2)
|
||||
assert list(edges) == [(0, 3), (0, 1), (3, 2)]
|
|
@ -0,0 +1,100 @@
|
|||
from functools import partial
|
||||
import networkx as nx
|
||||
|
||||
|
||||
class TestBFS:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
# simple graph
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)])
|
||||
cls.G = G
|
||||
|
||||
def test_successor(self):
|
||||
assert dict(nx.bfs_successors(self.G, source=0)) == {0: [1], 1: [2, 3], 2: [4]}
|
||||
|
||||
def test_predecessor(self):
|
||||
assert dict(nx.bfs_predecessors(self.G, source=0)) == {1: 0, 2: 1, 3: 1, 4: 2}
|
||||
|
||||
def test_bfs_tree(self):
|
||||
T = nx.bfs_tree(self.G, source=0)
|
||||
assert sorted(T.nodes()) == sorted(self.G.nodes())
|
||||
assert sorted(T.edges()) == [(0, 1), (1, 2), (1, 3), (2, 4)]
|
||||
|
||||
def test_bfs_edges(self):
|
||||
edges = nx.bfs_edges(self.G, source=0)
|
||||
assert list(edges) == [(0, 1), (1, 2), (1, 3), (2, 4)]
|
||||
|
||||
def test_bfs_edges_reverse(self):
|
||||
D = nx.DiGraph()
|
||||
D.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)])
|
||||
edges = nx.bfs_edges(D, source=4, reverse=True)
|
||||
assert list(edges) == [(4, 2), (4, 3), (2, 1), (1, 0)]
|
||||
|
||||
def test_bfs_edges_sorting(self):
|
||||
D = nx.DiGraph()
|
||||
D.add_edges_from([(0, 1), (0, 2), (1, 4), (1, 3), (2, 5)])
|
||||
sort_desc = partial(sorted, reverse=True)
|
||||
edges_asc = nx.bfs_edges(D, source=0, sort_neighbors=sorted)
|
||||
edges_desc = nx.bfs_edges(D, source=0, sort_neighbors=sort_desc)
|
||||
assert list(edges_asc) == [(0, 1), (0, 2), (1, 3), (1, 4), (2, 5)]
|
||||
assert list(edges_desc) == [(0, 2), (0, 1), (2, 5), (1, 4), (1, 3)]
|
||||
|
||||
def test_bfs_tree_isolates(self):
|
||||
G = nx.Graph()
|
||||
G.add_node(1)
|
||||
G.add_node(2)
|
||||
T = nx.bfs_tree(G, source=1)
|
||||
assert sorted(T.nodes()) == [1]
|
||||
assert sorted(T.edges()) == []
|
||||
|
||||
|
||||
class TestBreadthLimitedSearch:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
# a tree
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, [0, 1, 2, 3, 4, 5, 6])
|
||||
nx.add_path(G, [2, 7, 8, 9, 10])
|
||||
cls.G = G
|
||||
# a disconnected graph
|
||||
D = nx.Graph()
|
||||
D.add_edges_from([(0, 1), (2, 3)])
|
||||
nx.add_path(D, [2, 7, 8, 9, 10])
|
||||
cls.D = D
|
||||
|
||||
def test_limited_bfs_successor(self):
|
||||
assert dict(nx.bfs_successors(self.G, source=1, depth_limit=3)) == {
|
||||
1: [0, 2],
|
||||
2: [3, 7],
|
||||
3: [4],
|
||||
7: [8],
|
||||
}
|
||||
result = {
|
||||
n: sorted(s) for n, s in nx.bfs_successors(self.D, source=7, depth_limit=2)
|
||||
}
|
||||
assert result == {8: [9], 2: [3], 7: [2, 8]}
|
||||
|
||||
def test_limited_bfs_predecessor(self):
|
||||
assert dict(nx.bfs_predecessors(self.G, source=1, depth_limit=3)) == {
|
||||
0: 1,
|
||||
2: 1,
|
||||
3: 2,
|
||||
4: 3,
|
||||
7: 2,
|
||||
8: 7,
|
||||
}
|
||||
assert dict(nx.bfs_predecessors(self.D, source=7, depth_limit=2)) == {
|
||||
2: 7,
|
||||
3: 2,
|
||||
8: 7,
|
||||
9: 8,
|
||||
}
|
||||
|
||||
def test_limited_bfs_tree(self):
|
||||
T = nx.bfs_tree(self.G, source=3, depth_limit=1)
|
||||
assert sorted(T.edges()) == [(3, 2), (3, 4)]
|
||||
|
||||
def test_limited_bfs_edges(self):
|
||||
edges = nx.bfs_edges(self.G, source=9, depth_limit=4)
|
||||
assert list(edges) == [(9, 8), (9, 10), (8, 7), (7, 2), (2, 1), (2, 3)]
|
|
@ -0,0 +1,148 @@
|
|||
import networkx as nx
|
||||
|
||||
|
||||
class TestDFS:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
# simple graph
|
||||
G = nx.Graph()
|
||||
G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4)])
|
||||
cls.G = G
|
||||
# simple graph, disconnected
|
||||
D = nx.Graph()
|
||||
D.add_edges_from([(0, 1), (2, 3)])
|
||||
cls.D = D
|
||||
|
||||
def test_preorder_nodes(self):
|
||||
assert list(nx.dfs_preorder_nodes(self.G, source=0)) == [0, 1, 2, 4, 3]
|
||||
assert list(nx.dfs_preorder_nodes(self.D)) == [0, 1, 2, 3]
|
||||
|
||||
def test_postorder_nodes(self):
|
||||
assert list(nx.dfs_postorder_nodes(self.G, source=0)) == [3, 4, 2, 1, 0]
|
||||
assert list(nx.dfs_postorder_nodes(self.D)) == [1, 0, 3, 2]
|
||||
|
||||
def test_successor(self):
|
||||
assert nx.dfs_successors(self.G, source=0) == {0: [1], 1: [2], 2: [4], 4: [3]}
|
||||
assert nx.dfs_successors(self.D) == {0: [1], 2: [3]}
|
||||
|
||||
def test_predecessor(self):
|
||||
assert nx.dfs_predecessors(self.G, source=0) == {1: 0, 2: 1, 3: 4, 4: 2}
|
||||
assert nx.dfs_predecessors(self.D) == {1: 0, 3: 2}
|
||||
|
||||
def test_dfs_tree(self):
|
||||
exp_nodes = sorted(self.G.nodes())
|
||||
exp_edges = [(0, 1), (1, 2), (2, 4), (4, 3)]
|
||||
# Search from first node
|
||||
T = nx.dfs_tree(self.G, source=0)
|
||||
assert sorted(T.nodes()) == exp_nodes
|
||||
assert sorted(T.edges()) == exp_edges
|
||||
# Check source=None
|
||||
T = nx.dfs_tree(self.G, source=None)
|
||||
assert sorted(T.nodes()) == exp_nodes
|
||||
assert sorted(T.edges()) == exp_edges
|
||||
# Check source=None is the default
|
||||
T = nx.dfs_tree(self.G)
|
||||
assert sorted(T.nodes()) == exp_nodes
|
||||
assert sorted(T.edges()) == exp_edges
|
||||
|
||||
def test_dfs_edges(self):
|
||||
edges = nx.dfs_edges(self.G, source=0)
|
||||
assert list(edges) == [(0, 1), (1, 2), (2, 4), (4, 3)]
|
||||
edges = nx.dfs_edges(self.D)
|
||||
assert list(edges) == [(0, 1), (2, 3)]
|
||||
|
||||
def test_dfs_labeled_edges(self):
|
||||
edges = list(nx.dfs_labeled_edges(self.G, source=0))
|
||||
forward = [(u, v) for (u, v, d) in edges if d == "forward"]
|
||||
assert forward == [(0, 0), (0, 1), (1, 2), (2, 4), (4, 3)]
|
||||
|
||||
def test_dfs_labeled_disconnected_edges(self):
|
||||
edges = list(nx.dfs_labeled_edges(self.D))
|
||||
forward = [(u, v) for (u, v, d) in edges if d == "forward"]
|
||||
assert forward == [(0, 0), (0, 1), (2, 2), (2, 3)]
|
||||
|
||||
def test_dfs_tree_isolates(self):
|
||||
G = nx.Graph()
|
||||
G.add_node(1)
|
||||
G.add_node(2)
|
||||
T = nx.dfs_tree(G, source=1)
|
||||
assert sorted(T.nodes()) == [1]
|
||||
assert sorted(T.edges()) == []
|
||||
T = nx.dfs_tree(G, source=None)
|
||||
assert sorted(T.nodes()) == [1, 2]
|
||||
assert sorted(T.edges()) == []
|
||||
|
||||
|
||||
class TestDepthLimitedSearch:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
# a tree
|
||||
G = nx.Graph()
|
||||
nx.add_path(G, [0, 1, 2, 3, 4, 5, 6])
|
||||
nx.add_path(G, [2, 7, 8, 9, 10])
|
||||
cls.G = G
|
||||
# a disconnected graph
|
||||
D = nx.Graph()
|
||||
D.add_edges_from([(0, 1), (2, 3)])
|
||||
nx.add_path(D, [2, 7, 8, 9, 10])
|
||||
cls.D = D
|
||||
|
||||
def test_dls_preorder_nodes(self):
|
||||
assert list(nx.dfs_preorder_nodes(self.G, source=0, depth_limit=2)) == [0, 1, 2]
|
||||
assert list(nx.dfs_preorder_nodes(self.D, source=1, depth_limit=2)) == ([1, 0])
|
||||
|
||||
def test_dls_postorder_nodes(self):
|
||||
assert list(nx.dfs_postorder_nodes(self.G, source=3, depth_limit=3)) == [
|
||||
1,
|
||||
7,
|
||||
2,
|
||||
5,
|
||||
4,
|
||||
3,
|
||||
]
|
||||
assert list(nx.dfs_postorder_nodes(self.D, source=2, depth_limit=2)) == (
|
||||
[3, 7, 2]
|
||||
)
|
||||
|
||||
def test_dls_successor(self):
|
||||
result = nx.dfs_successors(self.G, source=4, depth_limit=3)
|
||||
assert {n: set(v) for n, v in result.items()} == {
|
||||
2: {1, 7},
|
||||
3: {2},
|
||||
4: {3, 5},
|
||||
5: {6},
|
||||
}
|
||||
result = nx.dfs_successors(self.D, source=7, depth_limit=2)
|
||||
assert {n: set(v) for n, v in result.items()} == {8: {9}, 2: {3}, 7: {8, 2}}
|
||||
|
||||
def test_dls_predecessor(self):
|
||||
assert nx.dfs_predecessors(self.G, source=0, depth_limit=3) == {
|
||||
1: 0,
|
||||
2: 1,
|
||||
3: 2,
|
||||
7: 2,
|
||||
}
|
||||
assert nx.dfs_predecessors(self.D, source=2, depth_limit=3) == {
|
||||
8: 7,
|
||||
9: 8,
|
||||
3: 2,
|
||||
7: 2,
|
||||
}
|
||||
|
||||
def test_dls_tree(self):
|
||||
T = nx.dfs_tree(self.G, source=3, depth_limit=1)
|
||||
assert sorted(T.edges()) == [(3, 2), (3, 4)]
|
||||
|
||||
def test_dls_edges(self):
|
||||
edges = nx.dfs_edges(self.G, source=9, depth_limit=4)
|
||||
assert list(edges) == [(9, 8), (8, 7), (7, 2), (2, 1), (2, 3), (9, 10)]
|
||||
|
||||
def test_dls_labeled_edges(self):
|
||||
edges = list(nx.dfs_labeled_edges(self.G, source=5, depth_limit=1))
|
||||
forward = [(u, v) for (u, v, d) in edges if d == "forward"]
|
||||
assert forward == [(5, 5), (5, 4), (5, 6)]
|
||||
|
||||
def test_dls_labeled_disconnected_edges(self):
|
||||
edges = list(nx.dfs_labeled_edges(self.G, source=6, depth_limit=2))
|
||||
forward = [(u, v) for (u, v, d) in edges if d == "forward"]
|
||||
assert forward == [(6, 6), (6, 5), (5, 4)]
|
|
@ -0,0 +1,151 @@
|
|||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
|
||||
edge_bfs = nx.edge_bfs
|
||||
|
||||
FORWARD = nx.algorithms.edgedfs.FORWARD
|
||||
REVERSE = nx.algorithms.edgedfs.REVERSE
|
||||
|
||||
|
||||
class TestEdgeBFS:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.nodes = [0, 1, 2, 3]
|
||||
cls.edges = [(0, 1), (1, 0), (1, 0), (2, 0), (2, 1), (3, 1)]
|
||||
|
||||
def test_empty(self):
|
||||
G = nx.Graph()
|
||||
edges = list(edge_bfs(G))
|
||||
assert edges == []
|
||||
|
||||
def test_graph_single_source(self):
|
||||
G = nx.Graph(self.edges)
|
||||
G.add_edge(4, 5)
|
||||
x = list(edge_bfs(G, [0]))
|
||||
x_ = [(0, 1), (0, 2), (1, 2), (1, 3)]
|
||||
assert x == x_
|
||||
|
||||
def test_graph(self):
|
||||
G = nx.Graph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes))
|
||||
x_ = [(0, 1), (0, 2), (1, 2), (1, 3)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes))
|
||||
x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_orientation_invalid(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
edge_iterator = edge_bfs(G, self.nodes, orientation="hello")
|
||||
pytest.raises(nx.NetworkXError, list, edge_iterator)
|
||||
|
||||
def test_digraph_orientation_none(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation=None))
|
||||
x_ = [(0, 1), (1, 0), (2, 0), (2, 1), (3, 1)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_orientation_original(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation="original"))
|
||||
x_ = [
|
||||
(0, 1, FORWARD),
|
||||
(1, 0, FORWARD),
|
||||
(2, 0, FORWARD),
|
||||
(2, 1, FORWARD),
|
||||
(3, 1, FORWARD),
|
||||
]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_bfs(G, [0]))
|
||||
x_ = [(0, 1), (1, 2), (2, 3)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_rev(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation="reverse"))
|
||||
x_ = [
|
||||
(1, 0, REVERSE),
|
||||
(2, 0, REVERSE),
|
||||
(0, 1, REVERSE),
|
||||
(2, 1, REVERSE),
|
||||
(3, 1, REVERSE),
|
||||
]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_rev2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_bfs(G, [3], orientation="reverse"))
|
||||
x_ = [(2, 3, REVERSE), (1, 2, REVERSE), (0, 1, REVERSE)]
|
||||
assert x == x_
|
||||
|
||||
def test_multigraph(self):
|
||||
G = nx.MultiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes))
|
||||
x_ = [(0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (1, 2, 0), (1, 3, 0)]
|
||||
# This is an example of where hash randomization can break.
|
||||
# There are 3! * 2 alternative outputs, such as:
|
||||
# [(0, 1, 1), (1, 0, 0), (0, 1, 2), (1, 3, 0), (1, 2, 0)]
|
||||
# But note, the edges (1,2,0) and (1,3,0) always follow the (0,1,k)
|
||||
# edges. So the algorithm only guarantees a partial order. A total
|
||||
# order is guaranteed only if the graph data structures are ordered.
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes))
|
||||
x_ = [(0, 1, 0), (1, 0, 0), (1, 0, 1), (2, 0, 0), (2, 1, 0), (3, 1, 0)]
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph_rev(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation="reverse"))
|
||||
x_ = [
|
||||
(1, 0, 0, REVERSE),
|
||||
(1, 0, 1, REVERSE),
|
||||
(2, 0, 0, REVERSE),
|
||||
(0, 1, 0, REVERSE),
|
||||
(2, 1, 0, REVERSE),
|
||||
(3, 1, 0, REVERSE),
|
||||
]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_ignore(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation="ignore"))
|
||||
x_ = [
|
||||
(0, 1, FORWARD),
|
||||
(1, 0, REVERSE),
|
||||
(2, 0, REVERSE),
|
||||
(2, 1, REVERSE),
|
||||
(3, 1, REVERSE),
|
||||
]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_ignore2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_bfs(G, [0], orientation="ignore"))
|
||||
x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 3, FORWARD)]
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph_ignore(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_bfs(G, self.nodes, orientation="ignore"))
|
||||
x_ = [
|
||||
(0, 1, 0, FORWARD),
|
||||
(1, 0, 0, REVERSE),
|
||||
(1, 0, 1, REVERSE),
|
||||
(2, 0, 0, REVERSE),
|
||||
(2, 1, 0, REVERSE),
|
||||
(3, 1, 0, REVERSE),
|
||||
]
|
||||
assert x == x_
|
|
@ -0,0 +1,134 @@
|
|||
import pytest
|
||||
|
||||
import networkx as nx
|
||||
|
||||
edge_dfs = nx.algorithms.edge_dfs
|
||||
|
||||
FORWARD = nx.algorithms.edgedfs.FORWARD
|
||||
REVERSE = nx.algorithms.edgedfs.REVERSE
|
||||
|
||||
# These tests can fail with hash randomization. The easiest and clearest way
|
||||
# to write these unit tests is for the edges to be output in an expected total
|
||||
# order, but we cannot guarantee the order amongst outgoing edges from a node,
|
||||
# unless each class uses an ordered data structure for neighbors. This is
|
||||
# painful to do with the current API. The alternative is that the tests are
|
||||
# written (IMO confusingly) so that there is not a total order over the edges,
|
||||
# but only a partial order. Due to the small size of the graphs, hopefully
|
||||
# failures due to hash randomization will not occur. For an example of how
|
||||
# this can fail, see TestEdgeDFS.test_multigraph.
|
||||
|
||||
|
||||
class TestEdgeDFS:
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
cls.nodes = [0, 1, 2, 3]
|
||||
cls.edges = [(0, 1), (1, 0), (1, 0), (2, 1), (3, 1)]
|
||||
|
||||
def test_empty(self):
|
||||
G = nx.Graph()
|
||||
edges = list(edge_dfs(G))
|
||||
assert edges == []
|
||||
|
||||
def test_graph(self):
|
||||
G = nx.Graph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes))
|
||||
x_ = [(0, 1), (1, 2), (1, 3)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes))
|
||||
x_ = [(0, 1), (1, 0), (2, 1), (3, 1)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_orientation_invalid(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
edge_iterator = edge_dfs(G, self.nodes, orientation="hello")
|
||||
pytest.raises(nx.NetworkXError, list, edge_iterator)
|
||||
|
||||
def test_digraph_orientation_none(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation=None))
|
||||
x_ = [(0, 1), (1, 0), (2, 1), (3, 1)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_orientation_original(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation="original"))
|
||||
x_ = [(0, 1, FORWARD), (1, 0, FORWARD), (2, 1, FORWARD), (3, 1, FORWARD)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_dfs(G, [0]))
|
||||
x_ = [(0, 1), (1, 2), (2, 3)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_rev(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation="reverse"))
|
||||
x_ = [(1, 0, REVERSE), (0, 1, REVERSE), (2, 1, REVERSE), (3, 1, REVERSE)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_rev2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_dfs(G, [3], orientation="reverse"))
|
||||
x_ = [(2, 3, REVERSE), (1, 2, REVERSE), (0, 1, REVERSE)]
|
||||
assert x == x_
|
||||
|
||||
def test_multigraph(self):
|
||||
G = nx.MultiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes))
|
||||
x_ = [(0, 1, 0), (1, 0, 1), (0, 1, 2), (1, 2, 0), (1, 3, 0)]
|
||||
# This is an example of where hash randomization can break.
|
||||
# There are 3! * 2 alternative outputs, such as:
|
||||
# [(0, 1, 1), (1, 0, 0), (0, 1, 2), (1, 3, 0), (1, 2, 0)]
|
||||
# But note, the edges (1,2,0) and (1,3,0) always follow the (0,1,k)
|
||||
# edges. So the algorithm only guarantees a partial order. A total
|
||||
# order is guaranteed only if the graph data structures are ordered.
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes))
|
||||
x_ = [(0, 1, 0), (1, 0, 0), (1, 0, 1), (2, 1, 0), (3, 1, 0)]
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph_rev(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation="reverse"))
|
||||
x_ = [
|
||||
(1, 0, 0, REVERSE),
|
||||
(0, 1, 0, REVERSE),
|
||||
(1, 0, 1, REVERSE),
|
||||
(2, 1, 0, REVERSE),
|
||||
(3, 1, 0, REVERSE),
|
||||
]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_ignore(self):
|
||||
G = nx.DiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation="ignore"))
|
||||
x_ = [(0, 1, FORWARD), (1, 0, FORWARD), (2, 1, REVERSE), (3, 1, REVERSE)]
|
||||
assert x == x_
|
||||
|
||||
def test_digraph_ignore2(self):
|
||||
G = nx.DiGraph()
|
||||
nx.add_path(G, range(4))
|
||||
x = list(edge_dfs(G, [0], orientation="ignore"))
|
||||
x_ = [(0, 1, FORWARD), (1, 2, FORWARD), (2, 3, FORWARD)]
|
||||
assert x == x_
|
||||
|
||||
def test_multidigraph_ignore(self):
|
||||
G = nx.MultiDiGraph(self.edges)
|
||||
x = list(edge_dfs(G, self.nodes, orientation="ignore"))
|
||||
x_ = [
|
||||
(0, 1, 0, FORWARD),
|
||||
(1, 0, 0, FORWARD),
|
||||
(1, 0, 1, REVERSE),
|
||||
(2, 1, 0, REVERSE),
|
||||
(3, 1, 0, REVERSE),
|
||||
]
|
||||
assert x == x_
|
Loading…
Add table
Add a link
Reference in a new issue