Fixed database typo and removed unnecessary class identifier.

This commit is contained in:
Batuhan Berk Başoğlu 2020-10-14 10:10:37 -04:00
parent 00ad49a143
commit 45fb349a7d
5098 changed files with 952558 additions and 85 deletions

View file

@ -0,0 +1,127 @@
import pytest
from networkx import Graph, NetworkXError
from networkx.algorithms.community.asyn_fluid import asyn_fluidc
def test_exceptions():
test = Graph()
test.add_node("a")
pytest.raises(NetworkXError, asyn_fluidc, test, "hi")
pytest.raises(NetworkXError, asyn_fluidc, test, -1)
pytest.raises(NetworkXError, asyn_fluidc, test, 3)
test.add_node("b")
pytest.raises(NetworkXError, asyn_fluidc, test, 1)
def test_single_node():
test = Graph()
test.add_node("a")
# ground truth
ground_truth = {frozenset(["a"])}
communities = asyn_fluidc(test, 1)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_two_nodes():
test = Graph()
test.add_edge("a", "b")
# ground truth
ground_truth = {frozenset(["a"]), frozenset(["b"])}
communities = asyn_fluidc(test, 2)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_two_clique_communities():
test = Graph()
# c1
test.add_edge("a", "b")
test.add_edge("a", "c")
test.add_edge("b", "c")
# connection
test.add_edge("c", "d")
# c2
test.add_edge("d", "e")
test.add_edge("d", "f")
test.add_edge("f", "e")
# ground truth
ground_truth = {frozenset(["a", "c", "b"]), frozenset(["e", "d", "f"])}
communities = asyn_fluidc(test, 2, seed=7)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_five_clique_ring():
test = Graph()
# c1
test.add_edge("1a", "1b")
test.add_edge("1a", "1c")
test.add_edge("1a", "1d")
test.add_edge("1b", "1c")
test.add_edge("1b", "1d")
test.add_edge("1c", "1d")
# c2
test.add_edge("2a", "2b")
test.add_edge("2a", "2c")
test.add_edge("2a", "2d")
test.add_edge("2b", "2c")
test.add_edge("2b", "2d")
test.add_edge("2c", "2d")
# c3
test.add_edge("3a", "3b")
test.add_edge("3a", "3c")
test.add_edge("3a", "3d")
test.add_edge("3b", "3c")
test.add_edge("3b", "3d")
test.add_edge("3c", "3d")
# c4
test.add_edge("4a", "4b")
test.add_edge("4a", "4c")
test.add_edge("4a", "4d")
test.add_edge("4b", "4c")
test.add_edge("4b", "4d")
test.add_edge("4c", "4d")
# c5
test.add_edge("5a", "5b")
test.add_edge("5a", "5c")
test.add_edge("5a", "5d")
test.add_edge("5b", "5c")
test.add_edge("5b", "5d")
test.add_edge("5c", "5d")
# connections
test.add_edge("1a", "2c")
test.add_edge("2a", "3c")
test.add_edge("3a", "4c")
test.add_edge("4a", "5c")
test.add_edge("5a", "1c")
# ground truth
ground_truth = {
frozenset(["1a", "1b", "1c", "1d"]),
frozenset(["2a", "2b", "2c", "2d"]),
frozenset(["3a", "3b", "3c", "3d"]),
frozenset(["4a", "4b", "4c", "4d"]),
frozenset(["5a", "5b", "5c", "5d"]),
}
communities = asyn_fluidc(test, 5, seed=9)
result = {frozenset(c) for c in communities}
assert result == ground_truth

View file

@ -0,0 +1,86 @@
"""Unit tests for the :mod:`networkx.algorithms.community.centrality`
module.
"""
from operator import itemgetter
import networkx as nx
from networkx.algorithms.community import girvan_newman
def set_of_sets(iterable):
return set(map(frozenset, iterable))
def validate_communities(result, expected):
assert set_of_sets(result) == set_of_sets(expected)
def validate_possible_communities(result, *expected):
assert any(set_of_sets(result) == set_of_sets(p) for p in expected)
class TestGirvanNewman:
"""Unit tests for the
:func:`networkx.algorithms.community.centrality.girvan_newman`
function.
"""
def test_no_edges(self):
G = nx.empty_graph(3)
communities = list(girvan_newman(G))
assert len(communities) == 1
validate_communities(communities[0], [{0}, {1}, {2}])
def test_undirected(self):
# Start with the graph .-.-.-.
G = nx.path_graph(4)
communities = list(girvan_newman(G))
assert len(communities) == 3
# After one removal, we get the graph .-. .-.
validate_communities(communities[0], [{0, 1}, {2, 3}])
# After the next, we get the graph .-. . ., but there are two
# symmetric possible versions.
validate_possible_communities(
communities[1], [{0}, {1}, {2, 3}], [{0, 1}, {2}, {3}]
)
# After the last removal, we always get the empty graph.
validate_communities(communities[2], [{0}, {1}, {2}, {3}])
def test_directed(self):
G = nx.DiGraph(nx.path_graph(4))
communities = list(girvan_newman(G))
assert len(communities) == 3
validate_communities(communities[0], [{0, 1}, {2, 3}])
validate_possible_communities(
communities[1], [{0}, {1}, {2, 3}], [{0, 1}, {2}, {3}]
)
validate_communities(communities[2], [{0}, {1}, {2}, {3}])
def test_selfloops(self):
G = nx.path_graph(4)
G.add_edge(0, 0)
G.add_edge(2, 2)
communities = list(girvan_newman(G))
assert len(communities) == 3
validate_communities(communities[0], [{0, 1}, {2, 3}])
validate_possible_communities(
communities[1], [{0}, {1}, {2, 3}], [{0, 1}, {2}, {3}]
)
validate_communities(communities[2], [{0}, {1}, {2}, {3}])
def test_most_valuable_edge(self):
G = nx.Graph()
G.add_weighted_edges_from([(0, 1, 3), (1, 2, 2), (2, 3, 1)])
# Let the most valuable edge be the one with the highest weight.
def heaviest(G):
return max(G.edges(data="weight"), key=itemgetter(2))[:2]
communities = list(girvan_newman(G, heaviest))
assert len(communities) == 3
validate_communities(communities[0], [{0}, {1, 2, 3}])
validate_communities(communities[1], [{0}, {1}, {2, 3}])
validate_communities(communities[2], [{0}, {1}, {2}, {3}])

View file

@ -0,0 +1,92 @@
from itertools import combinations
import pytest
import networkx as nx
from networkx.algorithms.community import k_clique_communities
def test_overlapping_K5():
G = nx.Graph()
G.add_edges_from(combinations(range(5), 2)) # Add a five clique
G.add_edges_from(combinations(range(2, 7), 2)) # Add another five clique
c = list(k_clique_communities(G, 4))
assert c == [frozenset(range(7))]
c = set(k_clique_communities(G, 5))
assert c == {frozenset(range(5)), frozenset(range(2, 7))}
def test_isolated_K5():
G = nx.Graph()
G.add_edges_from(combinations(range(0, 5), 2)) # Add a five clique
G.add_edges_from(combinations(range(5, 10), 2)) # Add another five clique
c = set(k_clique_communities(G, 5))
assert c == {frozenset(range(5)), frozenset(range(5, 10))}
class TestZacharyKarateClub:
def setup(self):
self.G = nx.karate_club_graph()
def _check_communities(self, k, expected):
communities = set(k_clique_communities(self.G, k))
assert communities == expected
def test_k2(self):
# clique percolation with k=2 is just connected components
expected = {frozenset(self.G)}
self._check_communities(2, expected)
def test_k3(self):
comm1 = [
0,
1,
2,
3,
7,
8,
12,
13,
14,
15,
17,
18,
19,
20,
21,
22,
23,
26,
27,
28,
29,
30,
31,
32,
33,
]
comm2 = [0, 4, 5, 6, 10, 16]
comm3 = [24, 25, 31]
expected = {frozenset(comm1), frozenset(comm2), frozenset(comm3)}
self._check_communities(3, expected)
def test_k4(self):
expected = {
frozenset([0, 1, 2, 3, 7, 13]),
frozenset([8, 32, 30, 33]),
frozenset([32, 33, 29, 23]),
}
self._check_communities(4, expected)
def test_k5(self):
expected = {frozenset([0, 1, 2, 3, 7, 13])}
self._check_communities(5, expected)
def test_k6(self):
expected = set()
self._check_communities(6, expected)
def test_bad_k():
with pytest.raises(nx.NetworkXError):
list(k_clique_communities(nx.Graph(), 1))

View file

@ -0,0 +1,59 @@
"""Unit tests for the :mod:`networkx.algorithms.community.kernighan_lin`
module.
"""
import pytest
import networkx as nx
from networkx.algorithms.community import kernighan_lin_bisection
from itertools import permutations
def assert_partition_equal(x, y):
assert set(map(frozenset, x)) == set(map(frozenset, y))
def test_partition():
G = nx.barbell_graph(3, 0)
C = kernighan_lin_bisection(G)
assert_partition_equal(C, [{0, 1, 2}, {3, 4, 5}])
def test_partition_argument():
G = nx.barbell_graph(3, 0)
partition = [{0, 1, 2}, {3, 4, 5}]
C = kernighan_lin_bisection(G, partition)
assert_partition_equal(C, partition)
def test_seed_argument():
G = nx.barbell_graph(3, 0)
C = kernighan_lin_bisection(G, seed=1)
assert_partition_equal(C, [{0, 1, 2}, {3, 4, 5}])
def test_non_disjoint_partition():
with pytest.raises(nx.NetworkXError):
G = nx.barbell_graph(3, 0)
partition = ({0, 1, 2}, {2, 3, 4, 5})
kernighan_lin_bisection(G, partition)
def test_too_many_blocks():
with pytest.raises(nx.NetworkXError):
G = nx.barbell_graph(3, 0)
partition = ({0, 1}, {2}, {3, 4, 5})
kernighan_lin_bisection(G, partition)
def test_multigraph():
G = nx.cycle_graph(4)
M = nx.MultiGraph(G.edges())
M.add_edges_from(G.edges())
M.remove_edge(1, 2)
for labels in permutations(range(4)):
mapping = dict(zip(M, labels))
A, B = kernighan_lin_bisection(nx.relabel_nodes(M, mapping), seed=0)
assert_partition_equal(
[A, B], [{mapping[0], mapping[1]}, {mapping[2], mapping[3]}]
)

View file

@ -0,0 +1,154 @@
from itertools import chain
from itertools import combinations
import pytest
import networkx as nx
from networkx.algorithms.community import label_propagation_communities
from networkx.algorithms.community import asyn_lpa_communities
def test_directed_not_supported():
with pytest.raises(nx.NetworkXNotImplemented):
# not supported for directed graphs
test = nx.DiGraph()
test.add_edge("a", "b")
test.add_edge("a", "c")
test.add_edge("b", "d")
result = label_propagation_communities(test)
def test_one_node():
test = nx.Graph()
test.add_node("a")
# The expected communities are:
ground_truth = {frozenset(["a"])}
communities = label_propagation_communities(test)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_unconnected_communities():
test = nx.Graph()
# community 1
test.add_edge("a", "c")
test.add_edge("a", "d")
test.add_edge("d", "c")
# community 2
test.add_edge("b", "e")
test.add_edge("e", "f")
test.add_edge("f", "b")
# The expected communities are:
ground_truth = {frozenset(["a", "c", "d"]), frozenset(["b", "e", "f"])}
communities = label_propagation_communities(test)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_connected_communities():
test = nx.Graph()
# community 1
test.add_edge("a", "b")
test.add_edge("c", "a")
test.add_edge("c", "b")
test.add_edge("d", "a")
test.add_edge("d", "b")
test.add_edge("d", "c")
test.add_edge("e", "a")
test.add_edge("e", "b")
test.add_edge("e", "c")
test.add_edge("e", "d")
# community 2
test.add_edge("1", "2")
test.add_edge("3", "1")
test.add_edge("3", "2")
test.add_edge("4", "1")
test.add_edge("4", "2")
test.add_edge("4", "3")
test.add_edge("5", "1")
test.add_edge("5", "2")
test.add_edge("5", "3")
test.add_edge("5", "4")
# edge between community 1 and 2
test.add_edge("a", "1")
# community 3
test.add_edge("x", "y")
# community 4 with only a single node
test.add_node("z")
# The expected communities are:
ground_truth1 = {
frozenset(["a", "b", "c", "d", "e"]),
frozenset(["1", "2", "3", "4", "5"]),
frozenset(["x", "y"]),
frozenset(["z"]),
}
ground_truth2 = {
frozenset(["a", "b", "c", "d", "e", "1", "2", "3", "4", "5"]),
frozenset(["x", "y"]),
frozenset(["z"]),
}
ground_truth = (ground_truth1, ground_truth2)
communities = label_propagation_communities(test)
result = {frozenset(c) for c in communities}
assert result in ground_truth
def test_termination():
# ensure termination of asyn_lpa_communities in two cases
# that led to an endless loop in a previous version
test1 = nx.karate_club_graph()
test2 = nx.caveman_graph(2, 10)
test2.add_edges_from([(0, 20), (20, 10)])
asyn_lpa_communities(test1)
asyn_lpa_communities(test2)
class TestAsynLpaCommunities:
def _check_communities(self, G, expected):
"""Checks that the communities computed from the given graph ``G``
using the :func:`~networkx.asyn_lpa_communities` function match
the set of nodes given in ``expected``.
``expected`` must be a :class:`set` of :class:`frozenset`
instances, each element of which is a node in the graph.
"""
communities = asyn_lpa_communities(G)
result = {frozenset(c) for c in communities}
assert result == expected
def test_null_graph(self):
G = nx.null_graph()
ground_truth = set()
self._check_communities(G, ground_truth)
def test_single_node(self):
G = nx.empty_graph(1)
ground_truth = {frozenset([0])}
self._check_communities(G, ground_truth)
def test_simple_communities(self):
# This graph is the disjoint union of two triangles.
G = nx.Graph(["ab", "ac", "bc", "de", "df", "fe"])
ground_truth = {frozenset("abc"), frozenset("def")}
self._check_communities(G, ground_truth)
def test_seed_argument(self):
G = nx.Graph(["ab", "ac", "bc", "de", "df", "fe"])
ground_truth = {frozenset("abc"), frozenset("def")}
communities = asyn_lpa_communities(G, seed=1)
result = {frozenset(c) for c in communities}
assert result == ground_truth
def test_several_communities(self):
# This graph is the disjoint union of five triangles.
ground_truth = {frozenset(range(3 * i, 3 * (i + 1))) for i in range(5)}
edges = chain.from_iterable(combinations(c, 2) for c in ground_truth)
G = nx.Graph(edges)
self._check_communities(G, ground_truth)

View file

@ -0,0 +1,154 @@
from itertools import product
import pytest
import networkx as nx
from networkx.algorithms.community import lukes_partitioning
EWL = "e_weight"
NWL = "n_weight"
# first test from the Lukes original paper
def paper_1_case(float_edge_wt=False, explicit_node_wt=True, directed=False):
# problem-specific constants
limit = 3
# configuration
if float_edge_wt:
shift = 0.001
else:
shift = 0
if directed:
example_1 = nx.DiGraph()
else:
example_1 = nx.Graph()
# graph creation
example_1.add_edge(1, 2, **{EWL: 3 + shift})
example_1.add_edge(1, 4, **{EWL: 2 + shift})
example_1.add_edge(2, 3, **{EWL: 4 + shift})
example_1.add_edge(2, 5, **{EWL: 6 + shift})
# node weights
if explicit_node_wt:
nx.set_node_attributes(example_1, 1, NWL)
wtu = NWL
else:
wtu = None
# partitioning
clusters_1 = {
frozenset(x)
for x in lukes_partitioning(example_1, limit, node_weight=wtu, edge_weight=EWL)
}
return clusters_1
# second test from the Lukes original paper
def paper_2_case(explicit_edge_wt=True, directed=False):
# problem specific constants
byte_block_size = 32
# configuration
if directed:
example_2 = nx.DiGraph()
else:
example_2 = nx.Graph()
if explicit_edge_wt:
edic = {EWL: 1}
wtu = EWL
else:
edic = {}
wtu = None
# graph creation
example_2.add_edge("name", "home_address", **edic)
example_2.add_edge("name", "education", **edic)
example_2.add_edge("education", "bs", **edic)
example_2.add_edge("education", "ms", **edic)
example_2.add_edge("education", "phd", **edic)
example_2.add_edge("name", "telephone", **edic)
example_2.add_edge("telephone", "home", **edic)
example_2.add_edge("telephone", "office", **edic)
example_2.add_edge("office", "no1", **edic)
example_2.add_edge("office", "no2", **edic)
example_2.nodes["name"][NWL] = 20
example_2.nodes["education"][NWL] = 10
example_2.nodes["bs"][NWL] = 1
example_2.nodes["ms"][NWL] = 1
example_2.nodes["phd"][NWL] = 1
example_2.nodes["home_address"][NWL] = 8
example_2.nodes["telephone"][NWL] = 8
example_2.nodes["home"][NWL] = 8
example_2.nodes["office"][NWL] = 4
example_2.nodes["no1"][NWL] = 1
example_2.nodes["no2"][NWL] = 1
# partitioning
clusters_2 = {
frozenset(x)
for x in lukes_partitioning(
example_2, byte_block_size, node_weight=NWL, edge_weight=wtu
)
}
return clusters_2
def test_paper_1_case():
ground_truth = {frozenset([1, 4]), frozenset([2, 3, 5])}
tf = (True, False)
for flt, nwt, drc in product(tf, tf, tf):
part = paper_1_case(flt, nwt, drc)
assert part == ground_truth
def test_paper_2_case():
ground_truth = {
frozenset(["education", "bs", "ms", "phd"]),
frozenset(["name", "home_address"]),
frozenset(["telephone", "home", "office", "no1", "no2"]),
}
tf = (True, False)
for ewt, drc in product(tf, tf):
part = paper_2_case(ewt, drc)
assert part == ground_truth
def test_mandatory_tree():
not_a_tree = nx.complete_graph(4)
with pytest.raises(nx.NotATree):
lukes_partitioning(not_a_tree, 5)
def test_mandatory_integrality():
byte_block_size = 32
ex_1_broken = nx.DiGraph()
ex_1_broken.add_edge(1, 2, **{EWL: 3.2})
ex_1_broken.add_edge(1, 4, **{EWL: 2.4})
ex_1_broken.add_edge(2, 3, **{EWL: 4.0})
ex_1_broken.add_edge(2, 5, **{EWL: 6.3})
ex_1_broken.nodes[1][NWL] = 1.2 # !
ex_1_broken.nodes[2][NWL] = 1
ex_1_broken.nodes[3][NWL] = 1
ex_1_broken.nodes[4][NWL] = 1
ex_1_broken.nodes[5][NWL] = 2
with pytest.raises(TypeError):
lukes_partitioning(
ex_1_broken, byte_block_size, node_weight=NWL, edge_weight=EWL
)

View file

@ -0,0 +1,39 @@
import networkx as nx
from networkx.algorithms.community import (
greedy_modularity_communities,
naive_greedy_modularity_communities,
)
class TestCNM:
def setup(self):
self.G = nx.karate_club_graph()
def _check_communities(self, expected):
communities = set(greedy_modularity_communities(self.G))
assert communities == expected
def test_karate_club(self):
john_a = frozenset(
[8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
)
mr_hi = frozenset([0, 4, 5, 6, 10, 11, 16, 19])
overlap = frozenset([1, 2, 3, 7, 9, 12, 13, 17, 21])
self._check_communities({john_a, overlap, mr_hi})
class TestNaive:
def setup(self):
self.G = nx.karate_club_graph()
def _check_communities(self, expected):
communities = set(naive_greedy_modularity_communities(self.G))
assert communities == expected
def test_karate_club(self):
john_a = frozenset(
[8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
)
mr_hi = frozenset([0, 4, 5, 6, 10, 11, 16, 19])
overlap = frozenset([1, 2, 3, 7, 9, 12, 13, 17, 21])
self._check_communities({john_a, overlap, mr_hi})

View file

@ -0,0 +1,84 @@
"""Unit tests for the :mod:`networkx.algorithms.community.quality`
module.
"""
import networkx as nx
from networkx import barbell_graph
from networkx.algorithms.community import coverage
from networkx.algorithms.community import modularity
from networkx.algorithms.community import performance
from networkx.algorithms.community.quality import inter_community_edges
from networkx.testing import almost_equal
class TestPerformance:
"""Unit tests for the :func:`performance` function."""
def test_bad_partition(self):
"""Tests that a poor partition has a low performance measure."""
G = barbell_graph(3, 0)
partition = [{0, 1, 4}, {2, 3, 5}]
assert almost_equal(8 / 15, performance(G, partition))
def test_good_partition(self):
"""Tests that a good partition has a high performance measure.
"""
G = barbell_graph(3, 0)
partition = [{0, 1, 2}, {3, 4, 5}]
assert almost_equal(14 / 15, performance(G, partition))
class TestCoverage:
"""Unit tests for the :func:`coverage` function."""
def test_bad_partition(self):
"""Tests that a poor partition has a low coverage measure."""
G = barbell_graph(3, 0)
partition = [{0, 1, 4}, {2, 3, 5}]
assert almost_equal(3 / 7, coverage(G, partition))
def test_good_partition(self):
"""Tests that a good partition has a high coverage measure."""
G = barbell_graph(3, 0)
partition = [{0, 1, 2}, {3, 4, 5}]
assert almost_equal(6 / 7, coverage(G, partition))
def test_modularity():
G = nx.barbell_graph(3, 0)
C = [{0, 1, 4}, {2, 3, 5}]
assert almost_equal(-16 / (14 ** 2), modularity(G, C))
C = [{0, 1, 2}, {3, 4, 5}]
assert almost_equal((35 * 2) / (14 ** 2), modularity(G, C))
n = 1000
G = nx.erdos_renyi_graph(n, 0.09, seed=42, directed=True)
C = [set(range(n // 2)), set(range(n // 2, n))]
assert almost_equal(0.00017154251389292754, modularity(G, C))
G = nx.margulis_gabber_galil_graph(10)
mid_value = G.number_of_nodes() // 2
nodes = list(G.nodes)
C = [set(nodes[:mid_value]), set(nodes[mid_value:])]
assert almost_equal(0.13, modularity(G, C))
G = nx.DiGraph()
G.add_edges_from([(2, 1), (2, 3), (3, 4)])
C = [{1, 2}, {3, 4}]
assert almost_equal(2 / 9, modularity(G, C))
def test_inter_community_edges_with_digraphs():
G = nx.complete_graph(2, create_using=nx.DiGraph())
partition = [{0}, {1}]
assert inter_community_edges(G, partition) == 2
G = nx.complete_graph(10, create_using=nx.DiGraph())
partition = [{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}]
assert inter_community_edges(G, partition) == 70
G = nx.cycle_graph(4, create_using=nx.DiGraph())
partition = [{0, 1}, {2, 3}]
assert inter_community_edges(G, partition) == 2

View file

@ -0,0 +1,29 @@
"""Unit tests for the :mod:`networkx.algorithms.community.utils` module.
"""
import networkx as nx
from networkx.algorithms.community import is_partition
def test_is_partition():
G = nx.empty_graph(3)
assert is_partition(G, [{0, 1}, {2}])
assert is_partition(G, ({0, 1}, {2}))
assert is_partition(G, ([0, 1], [2]))
assert is_partition(G, [[0, 1], [2]])
def test_not_covering():
G = nx.empty_graph(3)
assert not is_partition(G, [{0}, {1}])
def test_not_disjoint():
G = nx.empty_graph(3)
assert not is_partition(G, [{0, 1}, {1, 2}])
def test_not_node():
G = nx.empty_graph(3)
assert not is_partition(G, [{0, 1}, {3}])