123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- """Unit tests for the sparsifier computation functions."""
- import pytest
- import networkx as nx
- from networkx.utils import py_random_state
- _seed = 2
- def _test_spanner(G, spanner, stretch, weight=None):
- """Test whether a spanner is valid.
- This function tests whether the given spanner is a subgraph of the
- given graph G with the same node set. It also tests for all shortest
- paths whether they adhere to the given stretch.
- Parameters
- ----------
- G : NetworkX graph
- The original graph for which the spanner was constructed.
- spanner : NetworkX graph
- The spanner to be tested.
- stretch : float
- The proclaimed stretch of the spanner.
- weight : object
- The edge attribute to use as distance.
- """
- # check node set
- assert set(G.nodes()) == set(spanner.nodes())
- # check edge set and weights
- for u, v in spanner.edges():
- assert G.has_edge(u, v)
- if weight:
- assert spanner[u][v][weight] == G[u][v][weight]
- # check connectivity and stretch
- original_length = dict(nx.shortest_path_length(G, weight=weight))
- spanner_length = dict(nx.shortest_path_length(spanner, weight=weight))
- for u in G.nodes():
- for v in G.nodes():
- if u in original_length and v in original_length[u]:
- assert spanner_length[u][v] <= stretch * original_length[u][v]
- @py_random_state(1)
- def _assign_random_weights(G, seed=None):
- """Assigns random weights to the edges of a graph.
- Parameters
- ----------
- G : NetworkX graph
- The original graph for which the spanner was constructed.
- seed : integer, random_state, or None (default)
- Indicator of random number generation state.
- See :ref:`Randomness<randomness>`.
- """
- for u, v in G.edges():
- G[u][v]["weight"] = seed.random()
- def test_spanner_trivial():
- """Test a trivial spanner with stretch 1."""
- G = nx.complete_graph(20)
- spanner = nx.spanner(G, 1, seed=_seed)
- for u, v in G.edges:
- assert spanner.has_edge(u, v)
- def test_spanner_unweighted_complete_graph():
- """Test spanner construction on a complete unweighted graph."""
- G = nx.complete_graph(20)
- spanner = nx.spanner(G, 4, seed=_seed)
- _test_spanner(G, spanner, 4)
- spanner = nx.spanner(G, 10, seed=_seed)
- _test_spanner(G, spanner, 10)
- def test_spanner_weighted_complete_graph():
- """Test spanner construction on a complete weighted graph."""
- G = nx.complete_graph(20)
- _assign_random_weights(G, seed=_seed)
- spanner = nx.spanner(G, 4, weight="weight", seed=_seed)
- _test_spanner(G, spanner, 4, weight="weight")
- spanner = nx.spanner(G, 10, weight="weight", seed=_seed)
- _test_spanner(G, spanner, 10, weight="weight")
- def test_spanner_unweighted_gnp_graph():
- """Test spanner construction on an unweighted gnp graph."""
- G = nx.gnp_random_graph(20, 0.4, seed=_seed)
- spanner = nx.spanner(G, 4, seed=_seed)
- _test_spanner(G, spanner, 4)
- spanner = nx.spanner(G, 10, seed=_seed)
- _test_spanner(G, spanner, 10)
- def test_spanner_weighted_gnp_graph():
- """Test spanner construction on an weighted gnp graph."""
- G = nx.gnp_random_graph(20, 0.4, seed=_seed)
- _assign_random_weights(G, seed=_seed)
- spanner = nx.spanner(G, 4, weight="weight", seed=_seed)
- _test_spanner(G, spanner, 4, weight="weight")
- spanner = nx.spanner(G, 10, weight="weight", seed=_seed)
- _test_spanner(G, spanner, 10, weight="weight")
- def test_spanner_unweighted_disconnected_graph():
- """Test spanner construction on a disconnected graph."""
- G = nx.disjoint_union(nx.complete_graph(10), nx.complete_graph(10))
- spanner = nx.spanner(G, 4, seed=_seed)
- _test_spanner(G, spanner, 4)
- spanner = nx.spanner(G, 10, seed=_seed)
- _test_spanner(G, spanner, 10)
- def test_spanner_invalid_stretch():
- """Check whether an invalid stretch is caught."""
- with pytest.raises(ValueError):
- G = nx.empty_graph()
- nx.spanner(G, 0)
|