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 )