chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1 @@
|
||||
# TEST package init
|
||||
@@ -0,0 +1,139 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
class TestLPA(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_simple = eg.Graph()
|
||||
self.G_simple.add_edges_from([(0, 1), (1, 2), (3, 4)])
|
||||
|
||||
self.G_weighted = eg.Graph()
|
||||
self.G_weighted.add_edges_from([
|
||||
(0, 1, {"weight": 3}),
|
||||
(1, 2, {"weight": 2}),
|
||||
(2, 0, {"weight": 4}),
|
||||
(3, 4, {"weight": 1}),
|
||||
])
|
||||
|
||||
self.G_disconnected = eg.Graph()
|
||||
self.G_disconnected.add_edges_from([(0, 1), (2, 3), (4, 5)])
|
||||
|
||||
self.G_single = eg.Graph()
|
||||
self.G_single.add_node(42)
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_lpa_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result = cpeg.cpp_LPA(self.G_simple.cpp())
|
||||
self.assertIsInstance(result, dict)
|
||||
|
||||
all_nodes = set()
|
||||
for community in result.values():
|
||||
all_nodes.update(community)
|
||||
self.assertEqual(all_nodes, set(self.G_simple.nodes))
|
||||
|
||||
def test_lpa_weighted(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result = cpeg.cpp_LPA(self.G_weighted.cpp())
|
||||
self.assertIsInstance(result, dict)
|
||||
|
||||
all_nodes = set(self.G_weighted.nodes)
|
||||
result_nodes = set()
|
||||
for community in result.values():
|
||||
result_nodes.update(community)
|
||||
self.assertEqual(all_nodes, result_nodes)
|
||||
|
||||
def test_lpa_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result = cpeg.cpp_LPA(self.G_disconnected.cpp())
|
||||
self.assertIsInstance(result, dict)
|
||||
|
||||
all_nodes = set(self.G_disconnected.nodes)
|
||||
result_nodes = set()
|
||||
for community in result.values():
|
||||
result_nodes.update(community)
|
||||
self.assertEqual(all_nodes, result_nodes)
|
||||
|
||||
def test_lpa_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result = cpeg.cpp_LPA(self.G_single.cpp())
|
||||
self.assertIsInstance(result, dict)
|
||||
self.assertEqual(len(result), 1)
|
||||
for community in result.values():
|
||||
self.assertIn(42, community)
|
||||
|
||||
def test_lpa_empty_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result = cpeg.cpp_LPA(self.G_empty.cpp())
|
||||
self.assertIsInstance(result, dict)
|
||||
self.assertEqual(result, {})
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
result_cpp = cpeg.cpp_LPA(self.G_simple.cpp())
|
||||
result_py = eg.functions.community.LPA(self.G_simple)
|
||||
|
||||
self.assertEqual(len(result_cpp), len(result_py))
|
||||
|
||||
cpp_nodes = set()
|
||||
for community in result_cpp.values():
|
||||
cpp_nodes.update(community)
|
||||
|
||||
py_nodes = set()
|
||||
for community in result_py.values():
|
||||
py_nodes.update(community)
|
||||
|
||||
self.assertEqual(cpp_nodes, py_nodes)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,254 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
"""获取cpp_easygraph模块"""
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
"""将C++ DiGraph转换为C++ Graph无向图"""
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
def _csr_dict_to_graph(csr_dict):
|
||||
import cpp_easygraph
|
||||
|
||||
if not csr_dict or 'nodes' not in csr_dict:
|
||||
return cpp_easygraph.Graph()
|
||||
|
||||
G = cpp_easygraph.Graph()
|
||||
|
||||
nodes = csr_dict['nodes']
|
||||
for node in nodes:
|
||||
G.add_node(node)
|
||||
|
||||
V = csr_dict['V']
|
||||
E = csr_dict['E']
|
||||
W = csr_dict.get('W', [1.0] * len(E))
|
||||
|
||||
for u in range(len(V) - 1):
|
||||
start = V[u]
|
||||
end = V[u + 1]
|
||||
for i in range(start, end):
|
||||
v_idx = E[i]
|
||||
weight = W[i] if i < len(W) else 1.0
|
||||
G.add_edge(nodes[u], nodes[v_idx], weight=weight)
|
||||
|
||||
return G
|
||||
|
||||
|
||||
class TestEgoGraph(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.simple_graph = eg.Graph()
|
||||
self.simple_graph.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4)])
|
||||
|
||||
self.directed_graph = eg.DiGraph()
|
||||
self.directed_graph.add_edges_from([(0, 1), (1, 2), (2, 3)])
|
||||
|
||||
self.weighted_graph = eg.Graph()
|
||||
self.weighted_graph.add_edges_from(
|
||||
[(0, 1, {"weight": 1}), (1, 2, {"weight": 2}), (2, 3, {"weight": 3})]
|
||||
)
|
||||
|
||||
self.disconnected_graph = eg.Graph()
|
||||
self.disconnected_graph.add_edges_from([(0, 1), (2, 3)])
|
||||
|
||||
self.single_node_graph = eg.Graph()
|
||||
self.single_node_graph.add_node(42)
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_ego_graph_simple_radius_1(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 2, radius=1)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(2, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
self.assertIn(3, ego.nodes)
|
||||
|
||||
def test_ego_graph_simple_radius_2(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 2, radius=2)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(0, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
self.assertIn(2, ego.nodes)
|
||||
self.assertIn(3, ego.nodes)
|
||||
self.assertIn(4, ego.nodes)
|
||||
|
||||
def test_ego_graph_directed(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.directed_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 1, radius=1)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(1, ego.nodes)
|
||||
self.assertIn(2, ego.nodes)
|
||||
|
||||
def test_ego_graph_weighted_with_distance(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.weighted_graph.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 0, radius=2, distance="weight")
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(0, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
|
||||
def test_ego_graph_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.disconnected_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 0, radius=1)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(0, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
|
||||
def test_ego_graph_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.single_node_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 42, radius=1)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertIn(42, ego.nodes)
|
||||
|
||||
def test_ego_graph_center_false(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
ego = cpeg.cpp_ego_graph(G_cpp, 2, radius=1, center=False)
|
||||
self.assertIsInstance(ego, type(G_cpp))
|
||||
self.assertNotIn(2, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
self.assertIn(3, ego.nodes)
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
ego_py = eg.functions.community.ego_graph(self.simple_graph, 2, radius=1)
|
||||
ego_cpp = cpeg.cpp_ego_graph(G_cpp, 2, radius=1)
|
||||
|
||||
self.assertEqual(set(ego_py.nodes), set(ego_cpp.nodes))
|
||||
|
||||
|
||||
class TestEgoGraphCSR(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.simple_graph = eg.Graph()
|
||||
self.simple_graph.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 4)])
|
||||
|
||||
self.disconnected_graph = eg.Graph()
|
||||
self.disconnected_graph.add_edges_from([(0, 1), (2, 3)])
|
||||
|
||||
self.single_node_graph = eg.Graph()
|
||||
self.single_node_graph.add_node(42)
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_ego_graph_csr_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
ego_csr_dict = cpeg.cpp_ego_graph_csr(G_cpp, 2, radius=1)
|
||||
|
||||
ego = _csr_dict_to_graph(ego_csr_dict)
|
||||
|
||||
self.assertTrue(hasattr(ego, 'nodes'))
|
||||
self.assertIn(2, ego.nodes)
|
||||
|
||||
def test_ego_graph_csr_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.disconnected_graph.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
ego_csr_dict = cpeg.cpp_ego_graph_csr(G_cpp, 0, radius=1)
|
||||
|
||||
ego = _csr_dict_to_graph(ego_csr_dict)
|
||||
|
||||
self.assertTrue(hasattr(ego, 'nodes'))
|
||||
self.assertIn(0, ego.nodes)
|
||||
self.assertIn(1, ego.nodes)
|
||||
|
||||
def test_ego_graph_csr_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.single_node_graph.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
ego_csr_dict = cpeg.cpp_ego_graph_csr(G_cpp, 42, radius=1)
|
||||
|
||||
ego = _csr_dict_to_graph(ego_csr_dict)
|
||||
|
||||
self.assertTrue(hasattr(ego, 'nodes'))
|
||||
self.assertIn(42, ego.nodes)
|
||||
|
||||
def test_csr_vs_original_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.simple_graph.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
|
||||
ego_original = cpeg.cpp_ego_graph(G_cpp, 2, radius=1, undirected=False)
|
||||
ego_csr_dict = cpeg.cpp_ego_graph_csr(G_cpp, 2, radius=1)
|
||||
|
||||
ego_csr = _csr_dict_to_graph(ego_csr_dict)
|
||||
|
||||
self.assertIn(2, ego_original.nodes)
|
||||
self.assertIn(2, ego_csr.nodes)
|
||||
|
||||
self.assertTrue(set(ego_csr.nodes).issubset(set(ego_original.nodes) | {4}))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,143 @@
|
||||
import random
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
class TestEnumerateSubgraph(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_triangle = eg.Graph()
|
||||
self.G_triangle.add_edges_from([(1, 2), (2, 3), (3, 1)])
|
||||
|
||||
self.G_complex = eg.Graph()
|
||||
self.G_complex.add_edges_from([
|
||||
(1, 3), (2, 3), (3, 4), (4, 5), (3, 5)
|
||||
])
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
self.G_small = eg.Graph()
|
||||
self.G_small.add_edges_from([(1, 2)])
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_enumerate_subgraph_k3(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
motifs = cpeg.cpp_enumerate_subgraph(self.G_complex.cpp(), 3)
|
||||
self.assertIsInstance(motifs, list)
|
||||
for m in motifs:
|
||||
self.assertEqual(len(m), 3)
|
||||
|
||||
def test_enumerate_subgraph_k4(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
motifs = cpeg.cpp_enumerate_subgraph(self.G_complex.cpp(), 4)
|
||||
for m in motifs:
|
||||
self.assertEqual(len(m), 4)
|
||||
|
||||
def test_enumerate_subgraph_empty_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
motifs = cpeg.cpp_enumerate_subgraph(self.G_empty.cpp(), 3)
|
||||
self.assertEqual(motifs, [])
|
||||
|
||||
def test_enumerate_subgraph_k_larger_than_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
motifs = cpeg.cpp_enumerate_subgraph(self.G_small.cpp(), 3)
|
||||
self.assertEqual(motifs, [])
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
motifs_py = eg.enumerate_subgraph(self.G_complex, 3)
|
||||
motifs_py = [frozenset(m) for m in motifs_py]
|
||||
motifs_cpp = cpeg.cpp_enumerate_subgraph(self.G_complex.cpp(), 3)
|
||||
motifs_cpp = [frozenset(m) for m in motifs_cpp]
|
||||
|
||||
self.assertEqual(set(motifs_py), set(motifs_cpp))
|
||||
|
||||
|
||||
class TestRandomEnumerateSubgraph(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_complex = eg.Graph()
|
||||
self.G_complex.add_edges_from([
|
||||
(1, 3), (2, 3), (3, 4), (4, 5), (3, 5)
|
||||
])
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_random_enumerate_valid_cut_prob(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
cut_prob = [1.0, 1.0, 1.0]
|
||||
motifs = cpeg.cpp_random_enumerate_subgraph(self.G_complex.cpp(), 3, cut_prob)
|
||||
self.assertIsInstance(motifs, list)
|
||||
|
||||
def test_random_enumerate_zero_cut_prob(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
cut_prob = [0.0, 0.0, 0.0]
|
||||
motifs = cpeg.cpp_random_enumerate_subgraph(self.G_complex.cpp(), 3, cut_prob)
|
||||
self.assertEqual(motifs, [])
|
||||
|
||||
def test_random_enumerate_different_results(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
cut_prob = [1.0, 1.0, 1.0]
|
||||
motifs1 = cpeg.cpp_random_enumerate_subgraph(self.G_complex.cpp(), 3, cut_prob)
|
||||
motifs2 = cpeg.cpp_random_enumerate_subgraph(self.G_complex.cpp(), 3, cut_prob)
|
||||
|
||||
self.assertIsInstance(motifs1, list)
|
||||
self.assertIsInstance(motifs2, list)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,117 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
class TestGreedyModularity(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_simple = eg.Graph()
|
||||
self.G_simple.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0)])
|
||||
|
||||
self.G_disconnected = eg.Graph()
|
||||
self.G_disconnected.add_edges_from([(0, 1), (2, 3), (4, 5)])
|
||||
|
||||
self.G_weighted = eg.Graph()
|
||||
self.G_weighted.add_edge(0, 1, weight=5)
|
||||
self.G_weighted.add_edge(1, 2, weight=3)
|
||||
self.G_weighted.add_edge(2, 0, weight=2)
|
||||
self.G_weighted.add_edge(3, 4, weight=1)
|
||||
|
||||
self.G_single = eg.Graph()
|
||||
self.G_single.add_node(42)
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_greedy_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_greedy_modularity_communities(self.G_simple.cpp())
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_simple.nodes))
|
||||
|
||||
def test_greedy_weighted(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_greedy_modularity_communities(self.G_weighted.cpp(), weight="weight")
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_weighted.nodes))
|
||||
|
||||
def test_greedy_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_greedy_modularity_communities(self.G_disconnected.cpp())
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_disconnected.nodes))
|
||||
|
||||
def test_greedy_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_greedy_modularity_communities(self.G_single.cpp())
|
||||
self.assertEqual(len(communities), 1)
|
||||
self.assertIn(42, communities[0])
|
||||
|
||||
def test_greedy_empty_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_greedy_modularity_communities(self.G_empty.cpp())
|
||||
self.assertEqual(communities, [])
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities_cpp = cpeg.cpp_greedy_modularity_communities(self.G_simple.cpp())
|
||||
communities_py = eg.functions.community.greedy_modularity_communities(self.G_simple)
|
||||
|
||||
self.assertEqual(len(communities_cpp), len(communities_py))
|
||||
|
||||
flat_cpp = {node for comm in communities_cpp for node in comm}
|
||||
flat_py = {node for comm in communities_py for node in comm}
|
||||
self.assertEqual(flat_cpp, flat_py)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,188 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
class TestLocalsearch(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_simple = eg.Graph()
|
||||
self.G_simple.add_edges_from([(0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5)])
|
||||
|
||||
self.G_disconnected = eg.Graph()
|
||||
self.G_disconnected.add_edges_from([(0, 1), (2, 3), (4, 5)])
|
||||
|
||||
self.G_single = eg.Graph()
|
||||
self.G_single.add_node(42)
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_localsearch_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
all_nodes = set(self.G_simple.nodes)
|
||||
result_nodes = set(y_partition.keys())
|
||||
self.assertEqual(all_nodes, result_nodes)
|
||||
|
||||
def test_localsearch_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_disconnected.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
all_nodes = set(self.G_disconnected.nodes)
|
||||
result_nodes = set(y_partition.keys())
|
||||
self.assertEqual(all_nodes, result_nodes)
|
||||
|
||||
def test_localsearch_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_single.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
self.assertIn(42, y_partition)
|
||||
|
||||
def test_localsearch_empty_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_empty.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
def test_localsearch_maximum_tree_true(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, maximum_tree=True, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
def test_localsearch_maximum_tree_false(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, maximum_tree=False, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
def test_localsearch_auto_choose_centers(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, auto_choose_centers=True, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
def test_localsearch_center_num(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
result = cpeg.cpp_localsearch(G_cpp, center_num=2, seed=163)
|
||||
|
||||
self.assertIsInstance(result, tuple)
|
||||
self.assertEqual(len(result), 6)
|
||||
y_partition = result[3]
|
||||
self.assertIsInstance(y_partition, dict)
|
||||
|
||||
def test_localsearch_with_seed_reproducibility(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
G_cpp = self.G_simple.cpp()
|
||||
G_cpp.generate_linkgraph('weight')
|
||||
|
||||
result1 = cpeg.cpp_localsearch(G_cpp, seed=42)
|
||||
result2 = cpeg.cpp_localsearch(G_cpp, seed=42)
|
||||
|
||||
self.assertIsInstance(result1, tuple)
|
||||
self.assertIsInstance(result2, tuple)
|
||||
y_partition1 = result1[3]
|
||||
y_partition2 = result2[3]
|
||||
self.assertEqual(y_partition1.keys(), y_partition2.keys())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,178 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
class TestLouvainCommunities(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_simple = eg.Graph()
|
||||
self.G_simple.add_edges_from([(0, 1), (1, 2), (3, 4)])
|
||||
|
||||
self.G_weighted = eg.Graph()
|
||||
self.G_weighted.add_edge(0, 1, weight=5)
|
||||
self.G_weighted.add_edge(1, 2, weight=3)
|
||||
self.G_weighted.add_edge(3, 4, weight=2)
|
||||
|
||||
self.G_disconnected = eg.Graph()
|
||||
self.G_disconnected.add_edges_from([(0, 1), (2, 3), (4, 5)])
|
||||
|
||||
self.G_single = eg.Graph()
|
||||
self.G_single.add_node(42)
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_louvain_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities(self.G_simple.cpp())
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_simple.nodes))
|
||||
|
||||
def test_louvain_weighted(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities(self.G_weighted.cpp(), weight="weight")
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_weighted.nodes))
|
||||
|
||||
def test_louvain_disconnected(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities(self.G_disconnected.cpp())
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_disconnected.nodes))
|
||||
|
||||
def test_louvain_single_node(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities(self.G_single.cpp())
|
||||
self.assertEqual(len(communities), 1)
|
||||
self.assertIn(42, communities[0])
|
||||
|
||||
def test_louvain_empty_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities(self.G_empty.cpp())
|
||||
self.assertEqual(communities, [])
|
||||
|
||||
def test_louvain_resolution_parameter(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities1 = cpeg.cpp_louvain_communities(self.G_simple.cpp(), resolution=1.0)
|
||||
communities2 = cpeg.cpp_louvain_communities(self.G_simple.cpp(), resolution=0.5)
|
||||
|
||||
self.assertIsInstance(communities1, list)
|
||||
self.assertIsInstance(communities2, list)
|
||||
|
||||
flat1 = {node for comm in communities1 for node in comm}
|
||||
flat2 = {node for comm in communities2 for node in comm}
|
||||
self.assertEqual(flat1, flat2)
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities_cpp = cpeg.cpp_louvain_communities(self.G_simple.cpp())
|
||||
communities_py = eg.functions.community.louvain_communities(self.G_simple)
|
||||
|
||||
self.assertEqual(len(communities_cpp), len(communities_py))
|
||||
|
||||
flat_cpp = {node for comm in communities_cpp for node in comm}
|
||||
flat_py = {node for comm in communities_py for node in comm}
|
||||
self.assertEqual(flat_cpp, flat_py)
|
||||
|
||||
|
||||
class TestLouvainCommunitiesSerial(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G_simple = eg.Graph()
|
||||
self.G_simple.add_edges_from([(0, 1), (1, 2), (3, 4)])
|
||||
|
||||
self.G_weighted = eg.Graph()
|
||||
self.G_weighted.add_edge(0, 1, weight=5)
|
||||
self.G_weighted.add_edge(1, 2, weight=3)
|
||||
self.G_weighted.add_edge(3, 4, weight=2)
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_louvain_serial_simple(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities_serial(self.G_simple.cpp())
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_simple.nodes))
|
||||
|
||||
def test_louvain_serial_weighted(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = cpeg.cpp_louvain_communities_serial(self.G_weighted.cpp(), weight="weight")
|
||||
self.assertIsInstance(communities, list)
|
||||
flat = {node for comm in communities for node in comm}
|
||||
self.assertSetEqual(flat, set(self.G_weighted.nodes))
|
||||
|
||||
def test_parallel_vs_serial_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities_parallel = cpeg.cpp_louvain_communities(self.G_simple.cpp())
|
||||
communities_serial = cpeg.cpp_louvain_communities_serial(self.G_simple.cpp())
|
||||
|
||||
flat_parallel = {frozenset(comm) for comm in communities_parallel}
|
||||
flat_serial = {frozenset(comm) for comm in communities_serial}
|
||||
|
||||
self.assertEqual(flat_parallel, flat_serial)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,161 @@
|
||||
import unittest
|
||||
|
||||
import easygraph as eg
|
||||
|
||||
|
||||
def _get_cpp_module():
|
||||
"""获取cpp_easygraph模块"""
|
||||
try:
|
||||
import cpp_easygraph
|
||||
return cpp_easygraph
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def _to_undirected_cpp(G_cpp_digraph):
|
||||
"""将C++ DiGraph转换为C++ Graph无向图"""
|
||||
import cpp_easygraph
|
||||
|
||||
G_cpp = cpp_easygraph.Graph()
|
||||
G_cpp.graph.update(G_cpp_digraph.graph)
|
||||
for node, node_attr in G_cpp_digraph.nodes.items():
|
||||
G_cpp.add_node(node, **node_attr)
|
||||
|
||||
seen_edges = set()
|
||||
for u, v, edge_data in G_cpp_digraph.edges:
|
||||
edge = (min(u, v), max(u, v))
|
||||
if edge not in seen_edges:
|
||||
seen_edges.add(edge)
|
||||
G_cpp.add_edge(u, v, **edge_data)
|
||||
|
||||
return G_cpp
|
||||
|
||||
|
||||
def _communities_to_membership(G, communities):
|
||||
|
||||
if not isinstance(communities, list):
|
||||
communities = list(communities)
|
||||
|
||||
N = G.number_of_nodes()
|
||||
membership = [-1] * N
|
||||
node_index = G.node_index
|
||||
|
||||
for comm_id, community in enumerate(communities):
|
||||
for node in community:
|
||||
if node in node_index:
|
||||
node_id = node_index[node]
|
||||
membership[node_id] = comm_id
|
||||
|
||||
return membership
|
||||
|
||||
|
||||
class TestModularity(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.G = eg.Graph()
|
||||
self.G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0)])
|
||||
|
||||
self.DG = eg.DiGraph()
|
||||
self.DG.add_edges_from([(0, 1), (1, 2), (2, 0)])
|
||||
|
||||
self.G_weighted = eg.Graph()
|
||||
self.G_weighted.add_edge(0, 1, weight=2)
|
||||
self.G_weighted.add_edge(1, 2, weight=3)
|
||||
self.G_weighted.add_edge(2, 0, weight=1)
|
||||
|
||||
self.G_selfloop = eg.Graph()
|
||||
self.G_selfloop.add_edges_from([(0, 0), (1, 1), (0, 1)])
|
||||
|
||||
self.G_empty = eg.Graph()
|
||||
|
||||
self.config = type('Config', (), {
|
||||
'is_directed': False
|
||||
})()
|
||||
|
||||
def _get_cpp_module(self):
|
||||
return _get_cpp_module()
|
||||
|
||||
def test_undirected_modularity(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0, 1}, {2, 3}]
|
||||
membership = _communities_to_membership(self.G, communities)
|
||||
q = cpeg.cpp_modularity(self.G.cpp(), membership)
|
||||
self.assertIsInstance(q, float)
|
||||
self.assertGreaterEqual(q, -1.0)
|
||||
self.assertLessEqual(q, 1.0)
|
||||
|
||||
def test_directed_modularity(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0, 1, 2}]
|
||||
membership = _communities_to_membership(self.DG, communities)
|
||||
q = cpeg.cpp_modularity(self.DG.cpp(), membership)
|
||||
self.assertIsInstance(q, float)
|
||||
|
||||
def test_weighted_graph(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0, 1}, {2}]
|
||||
membership = _communities_to_membership(self.G_weighted, communities)
|
||||
q = cpeg.cpp_modularity(self.G_weighted.cpp(), membership, weight="weight")
|
||||
self.assertIsInstance(q, float)
|
||||
|
||||
def test_self_loops(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0, 1}]
|
||||
membership = _communities_to_membership(self.G_selfloop, communities)
|
||||
q = cpeg.cpp_modularity(self.G_selfloop.cpp(), membership)
|
||||
self.assertIsInstance(q, float)
|
||||
|
||||
def test_single_community(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0, 1, 2, 3}]
|
||||
membership = _communities_to_membership(self.G, communities)
|
||||
q = cpeg.cpp_modularity(self.G.cpp(), membership)
|
||||
self.assertIsInstance(q, float)
|
||||
|
||||
def test_each_node_its_own_community(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities = [{0}, {1}, {2}, {3}]
|
||||
membership = _communities_to_membership(self.G, communities)
|
||||
q = cpeg.cpp_modularity(self.G.cpp(), membership)
|
||||
self.assertIsInstance(q, float)
|
||||
|
||||
def test_empty_community_list(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
q = cpeg.cpp_modularity(self.G.cpp(), [])
|
||||
self.assertEqual(q, 0.0)
|
||||
|
||||
def test_python_cpp_consistency(self):
|
||||
cpeg = self._get_cpp_module()
|
||||
if cpeg is None:
|
||||
self.skipTest("cpp_easygraph module not available")
|
||||
|
||||
communities_py = [{0, 1}, {2, 3}]
|
||||
|
||||
q_py = eg.functions.community.modularity(self.G, communities_py)
|
||||
q_cpp = cpeg.cpp_modularity(self.G.cpp(), communities_py)
|
||||
|
||||
self.assertAlmostEqual(q_py, q_cpp, places=5)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,55 @@
|
||||
import unittest
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from cpp_modularity_test import TestModularity
|
||||
from cpp_greedy_modularity_test import TestGreedyModularity
|
||||
from cpp_enumerate_subgraph_test import (
|
||||
TestEnumerateSubgraph,
|
||||
TestRandomEnumerateSubgraph
|
||||
)
|
||||
from cpp_louvain_test import TestLouvainCommunities, TestLouvainCommunitiesSerial
|
||||
from cpp_LPA_test import TestLPA
|
||||
from cpp_ego_graph_test import TestEgoGraph, TestEgoGraphCSR
|
||||
from cpp_localsearch_test import TestLocalsearch
|
||||
|
||||
|
||||
def create_test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestModularity))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestGreedyModularity))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestEnumerateSubgraph))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestRandomEnumerateSubgraph))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLouvainCommunities))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLouvainCommunitiesSerial))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLPA))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestEgoGraph))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestEgoGraphCSR))
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestLocalsearch))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 70)
|
||||
print("Easy-Graph C++ Module Test Suite")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
suite = create_test_suite()
|
||||
runner = unittest.TextTestRunner(verbosity=2)
|
||||
result = runner.run(suite)
|
||||
|
||||
print()
|
||||
print("=" * 70)
|
||||
print("Test Summary")
|
||||
print("=" * 70)
|
||||
print(f"Tests run: {result.testsRun}")
|
||||
print(f"Successes: {result.testsRun - len(result.failures) - len(result.errors)}")
|
||||
print(f"Failures: {len(result.failures)}")
|
||||
print(f"Errors: {len(result.errors)}")
|
||||
print(f"Skipped: {len(result.skipped)}")
|
||||
print("=" * 70)
|
||||
|
||||
sys.exit(0 if result.wasSuccessful() else 1)
|
||||
Reference in New Issue
Block a user