test_community.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. import pytest
  2. import networkx as nx
  3. def test_random_partition_graph():
  4. G = nx.random_partition_graph([3, 3, 3], 1, 0, seed=42)
  5. C = G.graph["partition"]
  6. assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
  7. assert len(G) == 9
  8. assert len(list(G.edges())) == 9
  9. G = nx.random_partition_graph([3, 3, 3], 0, 1)
  10. C = G.graph["partition"]
  11. assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
  12. assert len(G) == 9
  13. assert len(list(G.edges())) == 27
  14. G = nx.random_partition_graph([3, 3, 3], 1, 0, directed=True)
  15. C = G.graph["partition"]
  16. assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
  17. assert len(G) == 9
  18. assert len(list(G.edges())) == 18
  19. G = nx.random_partition_graph([3, 3, 3], 0, 1, directed=True)
  20. C = G.graph["partition"]
  21. assert C == [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}]
  22. assert len(G) == 9
  23. assert len(list(G.edges())) == 54
  24. G = nx.random_partition_graph([1, 2, 3, 4, 5], 0.5, 0.1)
  25. C = G.graph["partition"]
  26. assert C == [{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}, {10, 11, 12, 13, 14}]
  27. assert len(G) == 15
  28. rpg = nx.random_partition_graph
  29. pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 1.1, 0.1)
  30. pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], -0.1, 0.1)
  31. pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 0.1, 1.1)
  32. pytest.raises(nx.NetworkXError, rpg, [1, 2, 3], 0.1, -0.1)
  33. def test_planted_partition_graph():
  34. G = nx.planted_partition_graph(4, 3, 1, 0, seed=42)
  35. C = G.graph["partition"]
  36. assert len(C) == 4
  37. assert len(G) == 12
  38. assert len(list(G.edges())) == 12
  39. G = nx.planted_partition_graph(4, 3, 0, 1)
  40. C = G.graph["partition"]
  41. assert len(C) == 4
  42. assert len(G) == 12
  43. assert len(list(G.edges())) == 54
  44. G = nx.planted_partition_graph(10, 4, 0.5, 0.1, seed=42)
  45. C = G.graph["partition"]
  46. assert len(C) == 10
  47. assert len(G) == 40
  48. G = nx.planted_partition_graph(4, 3, 1, 0, directed=True)
  49. C = G.graph["partition"]
  50. assert len(C) == 4
  51. assert len(G) == 12
  52. assert len(list(G.edges())) == 24
  53. G = nx.planted_partition_graph(4, 3, 0, 1, directed=True)
  54. C = G.graph["partition"]
  55. assert len(C) == 4
  56. assert len(G) == 12
  57. assert len(list(G.edges())) == 108
  58. G = nx.planted_partition_graph(10, 4, 0.5, 0.1, seed=42, directed=True)
  59. C = G.graph["partition"]
  60. assert len(C) == 10
  61. assert len(G) == 40
  62. ppg = nx.planted_partition_graph
  63. pytest.raises(nx.NetworkXError, ppg, 3, 3, 1.1, 0.1)
  64. pytest.raises(nx.NetworkXError, ppg, 3, 3, -0.1, 0.1)
  65. pytest.raises(nx.NetworkXError, ppg, 3, 3, 0.1, 1.1)
  66. pytest.raises(nx.NetworkXError, ppg, 3, 3, 0.1, -0.1)
  67. def test_relaxed_caveman_graph():
  68. G = nx.relaxed_caveman_graph(4, 3, 0)
  69. assert len(G) == 12
  70. G = nx.relaxed_caveman_graph(4, 3, 1)
  71. assert len(G) == 12
  72. G = nx.relaxed_caveman_graph(4, 3, 0.5)
  73. assert len(G) == 12
  74. G = nx.relaxed_caveman_graph(4, 3, 0.5, seed=42)
  75. assert len(G) == 12
  76. def test_connected_caveman_graph():
  77. G = nx.connected_caveman_graph(4, 3)
  78. assert len(G) == 12
  79. G = nx.connected_caveman_graph(1, 5)
  80. K5 = nx.complete_graph(5)
  81. K5.remove_edge(3, 4)
  82. assert nx.is_isomorphic(G, K5)
  83. # need at least 2 nodes in each clique
  84. pytest.raises(nx.NetworkXError, nx.connected_caveman_graph, 4, 1)
  85. def test_caveman_graph():
  86. G = nx.caveman_graph(4, 3)
  87. assert len(G) == 12
  88. G = nx.caveman_graph(5, 1)
  89. E5 = nx.empty_graph(5)
  90. assert nx.is_isomorphic(G, E5)
  91. G = nx.caveman_graph(1, 5)
  92. K5 = nx.complete_graph(5)
  93. assert nx.is_isomorphic(G, K5)
  94. def test_gaussian_random_partition_graph():
  95. G = nx.gaussian_random_partition_graph(100, 10, 10, 0.3, 0.01)
  96. assert len(G) == 100
  97. G = nx.gaussian_random_partition_graph(100, 10, 10, 0.3, 0.01, directed=True)
  98. assert len(G) == 100
  99. G = nx.gaussian_random_partition_graph(
  100. 100, 10, 10, 0.3, 0.01, directed=False, seed=42
  101. )
  102. assert len(G) == 100
  103. assert not isinstance(G, nx.DiGraph)
  104. G = nx.gaussian_random_partition_graph(
  105. 100, 10, 10, 0.3, 0.01, directed=True, seed=42
  106. )
  107. assert len(G) == 100
  108. assert isinstance(G, nx.DiGraph)
  109. pytest.raises(
  110. nx.NetworkXError, nx.gaussian_random_partition_graph, 100, 101, 10, 1, 0
  111. )
  112. # Test when clusters are likely less than 1
  113. G = nx.gaussian_random_partition_graph(10, 0.5, 0.5, 0.5, 0.5, seed=1)
  114. assert len(G) == 10
  115. def test_ring_of_cliques():
  116. for i in range(2, 20, 3):
  117. for j in range(2, 20, 3):
  118. G = nx.ring_of_cliques(i, j)
  119. assert G.number_of_nodes() == i * j
  120. if i != 2 or j != 1:
  121. expected_num_edges = i * (((j * (j - 1)) // 2) + 1)
  122. else:
  123. # the edge that already exists cannot be duplicated
  124. expected_num_edges = i * (((j * (j - 1)) // 2) + 1) - 1
  125. assert G.number_of_edges() == expected_num_edges
  126. with pytest.raises(
  127. nx.NetworkXError, match="A ring of cliques must have at least two cliques"
  128. ):
  129. nx.ring_of_cliques(1, 5)
  130. with pytest.raises(
  131. nx.NetworkXError, match="The cliques must have at least two nodes"
  132. ):
  133. nx.ring_of_cliques(3, 0)
  134. def test_windmill_graph():
  135. for n in range(2, 20, 3):
  136. for k in range(2, 20, 3):
  137. G = nx.windmill_graph(n, k)
  138. assert G.number_of_nodes() == (k - 1) * n + 1
  139. assert G.number_of_edges() == n * k * (k - 1) / 2
  140. assert G.degree(0) == G.number_of_nodes() - 1
  141. for i in range(1, G.number_of_nodes()):
  142. assert G.degree(i) == k - 1
  143. with pytest.raises(
  144. nx.NetworkXError, match="A windmill graph must have at least two cliques"
  145. ):
  146. nx.windmill_graph(1, 3)
  147. with pytest.raises(
  148. nx.NetworkXError, match="The cliques must have at least two nodes"
  149. ):
  150. nx.windmill_graph(3, 0)
  151. def test_stochastic_block_model():
  152. sizes = [75, 75, 300]
  153. probs = [[0.25, 0.05, 0.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]]
  154. G = nx.stochastic_block_model(sizes, probs, seed=0)
  155. C = G.graph["partition"]
  156. assert len(C) == 3
  157. assert len(G) == 450
  158. assert G.size() == 22160
  159. GG = nx.stochastic_block_model(sizes, probs, range(450), seed=0)
  160. assert G.nodes == GG.nodes
  161. # Test Exceptions
  162. sbm = nx.stochastic_block_model
  163. badnodelist = list(range(400)) # not enough nodes to match sizes
  164. badprobs1 = [[0.25, 0.05, 1.02], [0.05, 0.35, 0.07], [0.02, 0.07, 0.40]]
  165. badprobs2 = [[0.25, 0.05, 0.02], [0.05, -0.35, 0.07], [0.02, 0.07, 0.40]]
  166. probs_rect1 = [[0.25, 0.05, 0.02], [0.05, -0.35, 0.07]]
  167. probs_rect2 = [[0.25, 0.05], [0.05, -0.35], [0.02, 0.07]]
  168. asymprobs = [[0.25, 0.05, 0.01], [0.05, -0.35, 0.07], [0.02, 0.07, 0.40]]
  169. pytest.raises(nx.NetworkXException, sbm, sizes, badprobs1)
  170. pytest.raises(nx.NetworkXException, sbm, sizes, badprobs2)
  171. pytest.raises(nx.NetworkXException, sbm, sizes, probs_rect1, directed=True)
  172. pytest.raises(nx.NetworkXException, sbm, sizes, probs_rect2, directed=True)
  173. pytest.raises(nx.NetworkXException, sbm, sizes, asymprobs, directed=False)
  174. pytest.raises(nx.NetworkXException, sbm, sizes, probs, badnodelist)
  175. nodelist = [0] + list(range(449)) # repeated node name in nodelist
  176. pytest.raises(nx.NetworkXException, sbm, sizes, probs, nodelist)
  177. # Extra keyword arguments test
  178. GG = nx.stochastic_block_model(sizes, probs, seed=0, selfloops=True)
  179. assert G.nodes == GG.nodes
  180. GG = nx.stochastic_block_model(sizes, probs, selfloops=True, directed=True)
  181. assert G.nodes == GG.nodes
  182. GG = nx.stochastic_block_model(sizes, probs, seed=0, sparse=False)
  183. assert G.nodes == GG.nodes
  184. def test_generator():
  185. n = 250
  186. tau1 = 3
  187. tau2 = 1.5
  188. mu = 0.1
  189. G = nx.LFR_benchmark_graph(
  190. n, tau1, tau2, mu, average_degree=5, min_community=20, seed=10
  191. )
  192. assert len(G) == 250
  193. C = {frozenset(G.nodes[v]["community"]) for v in G}
  194. assert nx.community.is_partition(G.nodes(), C)
  195. def test_invalid_tau1():
  196. with pytest.raises(nx.NetworkXError, match="tau2 must be greater than one"):
  197. n = 100
  198. tau1 = 2
  199. tau2 = 1
  200. mu = 0.1
  201. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
  202. def test_invalid_tau2():
  203. with pytest.raises(nx.NetworkXError, match="tau1 must be greater than one"):
  204. n = 100
  205. tau1 = 1
  206. tau2 = 2
  207. mu = 0.1
  208. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
  209. def test_mu_too_large():
  210. with pytest.raises(nx.NetworkXError, match="mu must be in the interval \\[0, 1\\]"):
  211. n = 100
  212. tau1 = 2
  213. tau2 = 2
  214. mu = 1.1
  215. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
  216. def test_mu_too_small():
  217. with pytest.raises(nx.NetworkXError, match="mu must be in the interval \\[0, 1\\]"):
  218. n = 100
  219. tau1 = 2
  220. tau2 = 2
  221. mu = -1
  222. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2)
  223. def test_both_degrees_none():
  224. with pytest.raises(
  225. nx.NetworkXError,
  226. match="Must assign exactly one of min_degree and average_degree",
  227. ):
  228. n = 100
  229. tau1 = 2
  230. tau2 = 2
  231. mu = 1
  232. nx.LFR_benchmark_graph(n, tau1, tau2, mu)
  233. def test_neither_degrees_none():
  234. with pytest.raises(
  235. nx.NetworkXError,
  236. match="Must assign exactly one of min_degree and average_degree",
  237. ):
  238. n = 100
  239. tau1 = 2
  240. tau2 = 2
  241. mu = 1
  242. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2, average_degree=5)
  243. def test_max_iters_exeded():
  244. with pytest.raises(
  245. nx.ExceededMaxIterations,
  246. match="Could not assign communities; try increasing min_community",
  247. ):
  248. n = 10
  249. tau1 = 2
  250. tau2 = 2
  251. mu = 0.1
  252. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2, max_iters=10, seed=1)
  253. def test_max_deg_out_of_range():
  254. with pytest.raises(
  255. nx.NetworkXError, match="max_degree must be in the interval \\(0, n\\]"
  256. ):
  257. n = 10
  258. tau1 = 2
  259. tau2 = 2
  260. mu = 0.1
  261. nx.LFR_benchmark_graph(
  262. n, tau1, tau2, mu, max_degree=n + 1, max_iters=10, seed=1
  263. )
  264. def test_max_community():
  265. n = 250
  266. tau1 = 3
  267. tau2 = 1.5
  268. mu = 0.1
  269. G = nx.LFR_benchmark_graph(
  270. n,
  271. tau1,
  272. tau2,
  273. mu,
  274. average_degree=5,
  275. max_degree=100,
  276. min_community=50,
  277. max_community=200,
  278. seed=10,
  279. )
  280. assert len(G) == 250
  281. C = {frozenset(G.nodes[v]["community"]) for v in G}
  282. assert nx.community.is_partition(G.nodes(), C)
  283. def test_powerlaw_iterations_exceeded():
  284. with pytest.raises(
  285. nx.ExceededMaxIterations, match="Could not create power law sequence"
  286. ):
  287. n = 100
  288. tau1 = 2
  289. tau2 = 2
  290. mu = 1
  291. nx.LFR_benchmark_graph(n, tau1, tau2, mu, min_degree=2, max_iters=0)
  292. def test_no_scipy_zeta():
  293. zeta2 = 1.6449340668482264
  294. assert abs(zeta2 - nx.generators.community._hurwitz_zeta(2, 1, 0.0001)) < 0.01
  295. def test_generate_min_degree_itr():
  296. with pytest.raises(
  297. nx.ExceededMaxIterations, match="Could not match average_degree"
  298. ):
  299. nx.generators.community._generate_min_degree(2, 2, 1, 0.01, 0)