"""Unit tests for the :mod:`networkx.algorithms.tournament` module."""
from itertools import combinations
import pytest
from networkx import DiGraph
from networkx.algorithms.tournament import (
hamiltonian_path,
index_satisfying,
is_reachable,
is_strongly_connected,
is_tournament,
random_tournament,
score_sequence,
tournament_matrix,
)
def test_condition_not_satisfied():
condition = lambda x: x > 0
iter_in = [0]
assert index_satisfying(iter_in, condition) == 1
def test_empty_iterable():
condition = lambda x: x > 0
with pytest.raises(ValueError):
index_satisfying([], condition)
def test_is_tournament():
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3), (0, 2)])
assert is_tournament(G)
def test_self_loops():
"""A tournament must have no self-loops."""
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3), (0, 2)])
G.add_edge(0, 0)
assert not is_tournament(G)
def test_missing_edges():
"""A tournament must not have any pair of nodes without at least
one edge joining the pair.
"""
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3)])
assert not is_tournament(G)
def test_bidirectional_edges():
"""A tournament must not have any pair of nodes with greater
than one edge joining the pair.
"""
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3), (0, 2)])
G.add_edge(1, 0)
assert not is_tournament(G)
def test_graph_is_tournament():
for _ in range(10):
G = random_tournament(5)
assert is_tournament(G)
def test_graph_is_tournament_seed():
for _ in range(10):
G = random_tournament(5, seed=1)
assert is_tournament(G)
def test_graph_is_tournament_one_node():
G = random_tournament(1)
assert is_tournament(G)
def test_graph_is_tournament_zero_node():
G = random_tournament(0)
assert is_tournament(G)
def test_hamiltonian_empty_graph():
path = hamiltonian_path(DiGraph())
assert len(path) == 0
def test_path_is_hamiltonian():
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3), (0, 2)])
path = hamiltonian_path(G)
assert len(path) == 4
assert all(v in G[u] for u, v in zip(path, path[1:]))
def test_hamiltonian_cycle():
"""Tests that :func:`networkx.tournament.hamiltonian_path`
returns a Hamiltonian cycle when provided a strongly connected
tournament.
"""
G = DiGraph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (1, 3), (0, 2)])
path = hamiltonian_path(G)
assert len(path) == 4
assert all(v in G[u] for u, v in zip(path, path[1:]))
assert path[0] in G[path[-1]]
def test_score_sequence_edge():
G = DiGraph([(0, 1)])
assert score_sequence(G) == [0, 1]
def test_score_sequence_triangle():
G = DiGraph([(0, 1), (1, 2), (2, 0)])
assert score_sequence(G) == [1, 1, 1]
def test_tournament_matrix():
np = pytest.importorskip("numpy")
pytest.importorskip("scipy")
npt = np.testing
G = DiGraph([(0, 1)])
m = tournament_matrix(G)
npt.assert_array_equal(m.todense(), np.array([[0, 1], [-1, 0]]))
def test_reachable_pair():
"""Tests for a reachable pair of nodes."""
G = DiGraph([(0, 1), (1, 2), (2, 0)])
assert is_reachable(G, 0, 2)
def test_same_node_is_reachable():
"""Tests that a node is always reachable from it."""
# G is an arbitrary tournament on ten nodes.
G = DiGraph(sorted(p) for p in combinations(range(10), 2))
assert all(is_reachable(G, v, v) for v in G)
def test_unreachable_pair():
"""Tests for an unreachable pair of nodes."""
G = DiGraph([(0, 1), (0, 2), (1, 2)])
assert not is_reachable(G, 1, 0)
def test_is_strongly_connected():
"""Tests for a strongly connected tournament."""
G = DiGraph([(0, 1), (1, 2), (2, 0)])
assert is_strongly_connected(G)
def test_not_strongly_connected():
"""Tests for a tournament that is not strongly connected."""
G = DiGraph([(0, 1), (0, 2), (1, 2)])
assert not is_strongly_connected(G)