test_link_prediction.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. import math
  2. from functools import partial
  3. import pytest
  4. import networkx as nx
  5. def _test_func(G, ebunch, expected, predict_func, **kwargs):
  6. result = predict_func(G, ebunch, **kwargs)
  7. exp_dict = {tuple(sorted([u, v])): score for u, v, score in expected}
  8. res_dict = {tuple(sorted([u, v])): score for u, v, score in result}
  9. assert len(exp_dict) == len(res_dict)
  10. for p in exp_dict:
  11. assert exp_dict[p] == pytest.approx(res_dict[p], abs=1e-7)
  12. class TestResourceAllocationIndex:
  13. @classmethod
  14. def setup_class(cls):
  15. cls.func = staticmethod(nx.resource_allocation_index)
  16. cls.test = partial(_test_func, predict_func=cls.func)
  17. def test_K5(self):
  18. G = nx.complete_graph(5)
  19. self.test(G, [(0, 1)], [(0, 1, 0.75)])
  20. def test_P3(self):
  21. G = nx.path_graph(3)
  22. self.test(G, [(0, 2)], [(0, 2, 0.5)])
  23. def test_S4(self):
  24. G = nx.star_graph(4)
  25. self.test(G, [(1, 2)], [(1, 2, 0.25)])
  26. def test_notimplemented(self):
  27. assert pytest.raises(
  28. nx.NetworkXNotImplemented, self.func, nx.DiGraph([(0, 1), (1, 2)]), [(0, 2)]
  29. )
  30. assert pytest.raises(
  31. nx.NetworkXNotImplemented,
  32. self.func,
  33. nx.MultiGraph([(0, 1), (1, 2)]),
  34. [(0, 2)],
  35. )
  36. assert pytest.raises(
  37. nx.NetworkXNotImplemented,
  38. self.func,
  39. nx.MultiDiGraph([(0, 1), (1, 2)]),
  40. [(0, 2)],
  41. )
  42. def test_no_common_neighbor(self):
  43. G = nx.Graph()
  44. G.add_nodes_from([0, 1])
  45. self.test(G, [(0, 1)], [(0, 1, 0)])
  46. def test_equal_nodes(self):
  47. G = nx.complete_graph(4)
  48. self.test(G, [(0, 0)], [(0, 0, 1)])
  49. def test_all_nonexistent_edges(self):
  50. G = nx.Graph()
  51. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  52. self.test(G, None, [(0, 3, 0.5), (1, 2, 0.5), (1, 3, 0)])
  53. class TestJaccardCoefficient:
  54. @classmethod
  55. def setup_class(cls):
  56. cls.func = staticmethod(nx.jaccard_coefficient)
  57. cls.test = partial(_test_func, predict_func=cls.func)
  58. def test_K5(self):
  59. G = nx.complete_graph(5)
  60. self.test(G, [(0, 1)], [(0, 1, 0.6)])
  61. def test_P4(self):
  62. G = nx.path_graph(4)
  63. self.test(G, [(0, 2)], [(0, 2, 0.5)])
  64. def test_notimplemented(self):
  65. assert pytest.raises(
  66. nx.NetworkXNotImplemented, self.func, nx.DiGraph([(0, 1), (1, 2)]), [(0, 2)]
  67. )
  68. assert pytest.raises(
  69. nx.NetworkXNotImplemented,
  70. self.func,
  71. nx.MultiGraph([(0, 1), (1, 2)]),
  72. [(0, 2)],
  73. )
  74. assert pytest.raises(
  75. nx.NetworkXNotImplemented,
  76. self.func,
  77. nx.MultiDiGraph([(0, 1), (1, 2)]),
  78. [(0, 2)],
  79. )
  80. def test_no_common_neighbor(self):
  81. G = nx.Graph()
  82. G.add_edges_from([(0, 1), (2, 3)])
  83. self.test(G, [(0, 2)], [(0, 2, 0)])
  84. def test_isolated_nodes(self):
  85. G = nx.Graph()
  86. G.add_nodes_from([0, 1])
  87. self.test(G, [(0, 1)], [(0, 1, 0)])
  88. def test_all_nonexistent_edges(self):
  89. G = nx.Graph()
  90. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  91. self.test(G, None, [(0, 3, 0.5), (1, 2, 0.5), (1, 3, 0)])
  92. class TestAdamicAdarIndex:
  93. @classmethod
  94. def setup_class(cls):
  95. cls.func = staticmethod(nx.adamic_adar_index)
  96. cls.test = partial(_test_func, predict_func=cls.func)
  97. def test_K5(self):
  98. G = nx.complete_graph(5)
  99. self.test(G, [(0, 1)], [(0, 1, 3 / math.log(4))])
  100. def test_P3(self):
  101. G = nx.path_graph(3)
  102. self.test(G, [(0, 2)], [(0, 2, 1 / math.log(2))])
  103. def test_S4(self):
  104. G = nx.star_graph(4)
  105. self.test(G, [(1, 2)], [(1, 2, 1 / math.log(4))])
  106. def test_notimplemented(self):
  107. assert pytest.raises(
  108. nx.NetworkXNotImplemented, self.func, nx.DiGraph([(0, 1), (1, 2)]), [(0, 2)]
  109. )
  110. assert pytest.raises(
  111. nx.NetworkXNotImplemented,
  112. self.func,
  113. nx.MultiGraph([(0, 1), (1, 2)]),
  114. [(0, 2)],
  115. )
  116. assert pytest.raises(
  117. nx.NetworkXNotImplemented,
  118. self.func,
  119. nx.MultiDiGraph([(0, 1), (1, 2)]),
  120. [(0, 2)],
  121. )
  122. def test_no_common_neighbor(self):
  123. G = nx.Graph()
  124. G.add_nodes_from([0, 1])
  125. self.test(G, [(0, 1)], [(0, 1, 0)])
  126. def test_equal_nodes(self):
  127. G = nx.complete_graph(4)
  128. self.test(G, [(0, 0)], [(0, 0, 3 / math.log(3))])
  129. def test_all_nonexistent_edges(self):
  130. G = nx.Graph()
  131. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  132. self.test(
  133. G, None, [(0, 3, 1 / math.log(2)), (1, 2, 1 / math.log(2)), (1, 3, 0)]
  134. )
  135. class TestCommonNeighborCentrality:
  136. @classmethod
  137. def setup_class(cls):
  138. cls.func = staticmethod(nx.common_neighbor_centrality)
  139. cls.test = partial(_test_func, predict_func=cls.func)
  140. def test_K5(self):
  141. G = nx.complete_graph(5)
  142. self.test(G, [(0, 1)], [(0, 1, 3.0)], alpha=1)
  143. self.test(G, [(0, 1)], [(0, 1, 5.0)], alpha=0)
  144. def test_P3(self):
  145. G = nx.path_graph(3)
  146. self.test(G, [(0, 2)], [(0, 2, 1.25)], alpha=0.5)
  147. def test_S4(self):
  148. G = nx.star_graph(4)
  149. self.test(G, [(1, 2)], [(1, 2, 1.75)], alpha=0.5)
  150. @pytest.mark.parametrize("graph_type", (nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph))
  151. def test_notimplemented(self, graph_type):
  152. assert pytest.raises(
  153. nx.NetworkXNotImplemented, self.func, graph_type([(0, 1), (1, 2)]), [(0, 2)]
  154. )
  155. def test_no_common_neighbor(self):
  156. G = nx.Graph()
  157. G.add_nodes_from([0, 1])
  158. self.test(G, [(0, 1)], [(0, 1, 0)])
  159. def test_equal_nodes(self):
  160. G = nx.complete_graph(4)
  161. assert pytest.raises(nx.NetworkXAlgorithmError, self.test, G, [(0, 0)], [])
  162. def test_all_nonexistent_edges(self):
  163. G = nx.Graph()
  164. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  165. self.test(G, None, [(0, 3, 1.5), (1, 2, 1.5), (1, 3, 2 / 3)], alpha=0.5)
  166. class TestPreferentialAttachment:
  167. @classmethod
  168. def setup_class(cls):
  169. cls.func = staticmethod(nx.preferential_attachment)
  170. cls.test = partial(_test_func, predict_func=cls.func)
  171. def test_K5(self):
  172. G = nx.complete_graph(5)
  173. self.test(G, [(0, 1)], [(0, 1, 16)])
  174. def test_P3(self):
  175. G = nx.path_graph(3)
  176. self.test(G, [(0, 1)], [(0, 1, 2)])
  177. def test_S4(self):
  178. G = nx.star_graph(4)
  179. self.test(G, [(0, 2)], [(0, 2, 4)])
  180. def test_notimplemented(self):
  181. assert pytest.raises(
  182. nx.NetworkXNotImplemented, self.func, nx.DiGraph([(0, 1), (1, 2)]), [(0, 2)]
  183. )
  184. assert pytest.raises(
  185. nx.NetworkXNotImplemented,
  186. self.func,
  187. nx.MultiGraph([(0, 1), (1, 2)]),
  188. [(0, 2)],
  189. )
  190. assert pytest.raises(
  191. nx.NetworkXNotImplemented,
  192. self.func,
  193. nx.MultiDiGraph([(0, 1), (1, 2)]),
  194. [(0, 2)],
  195. )
  196. def test_zero_degrees(self):
  197. G = nx.Graph()
  198. G.add_nodes_from([0, 1])
  199. self.test(G, [(0, 1)], [(0, 1, 0)])
  200. def test_all_nonexistent_edges(self):
  201. G = nx.Graph()
  202. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  203. self.test(G, None, [(0, 3, 2), (1, 2, 2), (1, 3, 1)])
  204. class TestCNSoundarajanHopcroft:
  205. @classmethod
  206. def setup_class(cls):
  207. cls.func = staticmethod(nx.cn_soundarajan_hopcroft)
  208. cls.test = partial(_test_func, predict_func=cls.func, community="community")
  209. def test_K5(self):
  210. G = nx.complete_graph(5)
  211. G.nodes[0]["community"] = 0
  212. G.nodes[1]["community"] = 0
  213. G.nodes[2]["community"] = 0
  214. G.nodes[3]["community"] = 0
  215. G.nodes[4]["community"] = 1
  216. self.test(G, [(0, 1)], [(0, 1, 5)])
  217. def test_P3(self):
  218. G = nx.path_graph(3)
  219. G.nodes[0]["community"] = 0
  220. G.nodes[1]["community"] = 1
  221. G.nodes[2]["community"] = 0
  222. self.test(G, [(0, 2)], [(0, 2, 1)])
  223. def test_S4(self):
  224. G = nx.star_graph(4)
  225. G.nodes[0]["community"] = 1
  226. G.nodes[1]["community"] = 1
  227. G.nodes[2]["community"] = 1
  228. G.nodes[3]["community"] = 0
  229. G.nodes[4]["community"] = 0
  230. self.test(G, [(1, 2)], [(1, 2, 2)])
  231. def test_notimplemented(self):
  232. G = nx.DiGraph([(0, 1), (1, 2)])
  233. G.add_nodes_from([0, 1, 2], community=0)
  234. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  235. G = nx.MultiGraph([(0, 1), (1, 2)])
  236. G.add_nodes_from([0, 1, 2], community=0)
  237. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  238. G = nx.MultiDiGraph([(0, 1), (1, 2)])
  239. G.add_nodes_from([0, 1, 2], community=0)
  240. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  241. def test_no_common_neighbor(self):
  242. G = nx.Graph()
  243. G.add_nodes_from([0, 1])
  244. G.nodes[0]["community"] = 0
  245. G.nodes[1]["community"] = 0
  246. self.test(G, [(0, 1)], [(0, 1, 0)])
  247. def test_equal_nodes(self):
  248. G = nx.complete_graph(3)
  249. G.nodes[0]["community"] = 0
  250. G.nodes[1]["community"] = 0
  251. G.nodes[2]["community"] = 0
  252. self.test(G, [(0, 0)], [(0, 0, 4)])
  253. def test_different_community(self):
  254. G = nx.Graph()
  255. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  256. G.nodes[0]["community"] = 0
  257. G.nodes[1]["community"] = 0
  258. G.nodes[2]["community"] = 0
  259. G.nodes[3]["community"] = 1
  260. self.test(G, [(0, 3)], [(0, 3, 2)])
  261. def test_no_community_information(self):
  262. G = nx.complete_graph(5)
  263. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 1)]))
  264. def test_insufficient_community_information(self):
  265. G = nx.Graph()
  266. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  267. G.nodes[0]["community"] = 0
  268. G.nodes[1]["community"] = 0
  269. G.nodes[3]["community"] = 0
  270. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 3)]))
  271. def test_sufficient_community_information(self):
  272. G = nx.Graph()
  273. G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)])
  274. G.nodes[1]["community"] = 0
  275. G.nodes[2]["community"] = 0
  276. G.nodes[3]["community"] = 0
  277. G.nodes[4]["community"] = 0
  278. self.test(G, [(1, 4)], [(1, 4, 4)])
  279. def test_custom_community_attribute_name(self):
  280. G = nx.Graph()
  281. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  282. G.nodes[0]["cmty"] = 0
  283. G.nodes[1]["cmty"] = 0
  284. G.nodes[2]["cmty"] = 0
  285. G.nodes[3]["cmty"] = 1
  286. self.test(G, [(0, 3)], [(0, 3, 2)], community="cmty")
  287. def test_all_nonexistent_edges(self):
  288. G = nx.Graph()
  289. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  290. G.nodes[0]["community"] = 0
  291. G.nodes[1]["community"] = 1
  292. G.nodes[2]["community"] = 0
  293. G.nodes[3]["community"] = 0
  294. self.test(G, None, [(0, 3, 2), (1, 2, 1), (1, 3, 0)])
  295. class TestRAIndexSoundarajanHopcroft:
  296. @classmethod
  297. def setup_class(cls):
  298. cls.func = staticmethod(nx.ra_index_soundarajan_hopcroft)
  299. cls.test = partial(_test_func, predict_func=cls.func, community="community")
  300. def test_K5(self):
  301. G = nx.complete_graph(5)
  302. G.nodes[0]["community"] = 0
  303. G.nodes[1]["community"] = 0
  304. G.nodes[2]["community"] = 0
  305. G.nodes[3]["community"] = 0
  306. G.nodes[4]["community"] = 1
  307. self.test(G, [(0, 1)], [(0, 1, 0.5)])
  308. def test_P3(self):
  309. G = nx.path_graph(3)
  310. G.nodes[0]["community"] = 0
  311. G.nodes[1]["community"] = 1
  312. G.nodes[2]["community"] = 0
  313. self.test(G, [(0, 2)], [(0, 2, 0)])
  314. def test_S4(self):
  315. G = nx.star_graph(4)
  316. G.nodes[0]["community"] = 1
  317. G.nodes[1]["community"] = 1
  318. G.nodes[2]["community"] = 1
  319. G.nodes[3]["community"] = 0
  320. G.nodes[4]["community"] = 0
  321. self.test(G, [(1, 2)], [(1, 2, 0.25)])
  322. def test_notimplemented(self):
  323. G = nx.DiGraph([(0, 1), (1, 2)])
  324. G.add_nodes_from([0, 1, 2], community=0)
  325. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  326. G = nx.MultiGraph([(0, 1), (1, 2)])
  327. G.add_nodes_from([0, 1, 2], community=0)
  328. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  329. G = nx.MultiDiGraph([(0, 1), (1, 2)])
  330. G.add_nodes_from([0, 1, 2], community=0)
  331. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  332. def test_no_common_neighbor(self):
  333. G = nx.Graph()
  334. G.add_nodes_from([0, 1])
  335. G.nodes[0]["community"] = 0
  336. G.nodes[1]["community"] = 0
  337. self.test(G, [(0, 1)], [(0, 1, 0)])
  338. def test_equal_nodes(self):
  339. G = nx.complete_graph(3)
  340. G.nodes[0]["community"] = 0
  341. G.nodes[1]["community"] = 0
  342. G.nodes[2]["community"] = 0
  343. self.test(G, [(0, 0)], [(0, 0, 1)])
  344. def test_different_community(self):
  345. G = nx.Graph()
  346. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  347. G.nodes[0]["community"] = 0
  348. G.nodes[1]["community"] = 0
  349. G.nodes[2]["community"] = 0
  350. G.nodes[3]["community"] = 1
  351. self.test(G, [(0, 3)], [(0, 3, 0)])
  352. def test_no_community_information(self):
  353. G = nx.complete_graph(5)
  354. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 1)]))
  355. def test_insufficient_community_information(self):
  356. G = nx.Graph()
  357. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  358. G.nodes[0]["community"] = 0
  359. G.nodes[1]["community"] = 0
  360. G.nodes[3]["community"] = 0
  361. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 3)]))
  362. def test_sufficient_community_information(self):
  363. G = nx.Graph()
  364. G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)])
  365. G.nodes[1]["community"] = 0
  366. G.nodes[2]["community"] = 0
  367. G.nodes[3]["community"] = 0
  368. G.nodes[4]["community"] = 0
  369. self.test(G, [(1, 4)], [(1, 4, 1)])
  370. def test_custom_community_attribute_name(self):
  371. G = nx.Graph()
  372. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  373. G.nodes[0]["cmty"] = 0
  374. G.nodes[1]["cmty"] = 0
  375. G.nodes[2]["cmty"] = 0
  376. G.nodes[3]["cmty"] = 1
  377. self.test(G, [(0, 3)], [(0, 3, 0)], community="cmty")
  378. def test_all_nonexistent_edges(self):
  379. G = nx.Graph()
  380. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  381. G.nodes[0]["community"] = 0
  382. G.nodes[1]["community"] = 1
  383. G.nodes[2]["community"] = 0
  384. G.nodes[3]["community"] = 0
  385. self.test(G, None, [(0, 3, 0.5), (1, 2, 0), (1, 3, 0)])
  386. class TestWithinInterCluster:
  387. @classmethod
  388. def setup_class(cls):
  389. cls.delta = 0.001
  390. cls.func = staticmethod(nx.within_inter_cluster)
  391. cls.test = partial(
  392. _test_func, predict_func=cls.func, delta=cls.delta, community="community"
  393. )
  394. def test_K5(self):
  395. G = nx.complete_graph(5)
  396. G.nodes[0]["community"] = 0
  397. G.nodes[1]["community"] = 0
  398. G.nodes[2]["community"] = 0
  399. G.nodes[3]["community"] = 0
  400. G.nodes[4]["community"] = 1
  401. self.test(G, [(0, 1)], [(0, 1, 2 / (1 + self.delta))])
  402. def test_P3(self):
  403. G = nx.path_graph(3)
  404. G.nodes[0]["community"] = 0
  405. G.nodes[1]["community"] = 1
  406. G.nodes[2]["community"] = 0
  407. self.test(G, [(0, 2)], [(0, 2, 0)])
  408. def test_S4(self):
  409. G = nx.star_graph(4)
  410. G.nodes[0]["community"] = 1
  411. G.nodes[1]["community"] = 1
  412. G.nodes[2]["community"] = 1
  413. G.nodes[3]["community"] = 0
  414. G.nodes[4]["community"] = 0
  415. self.test(G, [(1, 2)], [(1, 2, 1 / self.delta)])
  416. def test_notimplemented(self):
  417. G = nx.DiGraph([(0, 1), (1, 2)])
  418. G.add_nodes_from([0, 1, 2], community=0)
  419. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  420. G = nx.MultiGraph([(0, 1), (1, 2)])
  421. G.add_nodes_from([0, 1, 2], community=0)
  422. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  423. G = nx.MultiDiGraph([(0, 1), (1, 2)])
  424. G.add_nodes_from([0, 1, 2], community=0)
  425. assert pytest.raises(nx.NetworkXNotImplemented, self.func, G, [(0, 2)])
  426. def test_no_common_neighbor(self):
  427. G = nx.Graph()
  428. G.add_nodes_from([0, 1])
  429. G.nodes[0]["community"] = 0
  430. G.nodes[1]["community"] = 0
  431. self.test(G, [(0, 1)], [(0, 1, 0)])
  432. def test_equal_nodes(self):
  433. G = nx.complete_graph(3)
  434. G.nodes[0]["community"] = 0
  435. G.nodes[1]["community"] = 0
  436. G.nodes[2]["community"] = 0
  437. self.test(G, [(0, 0)], [(0, 0, 2 / self.delta)])
  438. def test_different_community(self):
  439. G = nx.Graph()
  440. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  441. G.nodes[0]["community"] = 0
  442. G.nodes[1]["community"] = 0
  443. G.nodes[2]["community"] = 0
  444. G.nodes[3]["community"] = 1
  445. self.test(G, [(0, 3)], [(0, 3, 0)])
  446. def test_no_inter_cluster_common_neighbor(self):
  447. G = nx.complete_graph(4)
  448. G.nodes[0]["community"] = 0
  449. G.nodes[1]["community"] = 0
  450. G.nodes[2]["community"] = 0
  451. G.nodes[3]["community"] = 0
  452. self.test(G, [(0, 3)], [(0, 3, 2 / self.delta)])
  453. def test_no_community_information(self):
  454. G = nx.complete_graph(5)
  455. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 1)]))
  456. def test_insufficient_community_information(self):
  457. G = nx.Graph()
  458. G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3)])
  459. G.nodes[0]["community"] = 0
  460. G.nodes[1]["community"] = 0
  461. G.nodes[3]["community"] = 0
  462. assert pytest.raises(nx.NetworkXAlgorithmError, list, self.func(G, [(0, 3)]))
  463. def test_sufficient_community_information(self):
  464. G = nx.Graph()
  465. G.add_edges_from([(0, 1), (1, 2), (1, 3), (2, 4), (3, 4), (4, 5)])
  466. G.nodes[1]["community"] = 0
  467. G.nodes[2]["community"] = 0
  468. G.nodes[3]["community"] = 0
  469. G.nodes[4]["community"] = 0
  470. self.test(G, [(1, 4)], [(1, 4, 2 / self.delta)])
  471. def test_invalid_delta(self):
  472. G = nx.complete_graph(3)
  473. G.add_nodes_from([0, 1, 2], community=0)
  474. assert pytest.raises(nx.NetworkXAlgorithmError, self.func, G, [(0, 1)], 0)
  475. assert pytest.raises(nx.NetworkXAlgorithmError, self.func, G, [(0, 1)], -0.5)
  476. def test_custom_community_attribute_name(self):
  477. G = nx.complete_graph(4)
  478. G.nodes[0]["cmty"] = 0
  479. G.nodes[1]["cmty"] = 0
  480. G.nodes[2]["cmty"] = 0
  481. G.nodes[3]["cmty"] = 0
  482. self.test(G, [(0, 3)], [(0, 3, 2 / self.delta)], community="cmty")
  483. def test_all_nonexistent_edges(self):
  484. G = nx.Graph()
  485. G.add_edges_from([(0, 1), (0, 2), (2, 3)])
  486. G.nodes[0]["community"] = 0
  487. G.nodes[1]["community"] = 1
  488. G.nodes[2]["community"] = 0
  489. G.nodes[3]["community"] = 0
  490. self.test(G, None, [(0, 3, 1 / self.delta), (1, 2, 0), (1, 3, 0)])