test_graph.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. import unittest
  2. from altgraph import GraphError
  3. from altgraph.Graph import Graph
  4. class TestGraph (unittest.TestCase):
  5. def test_nodes(self):
  6. graph = Graph()
  7. self.assertEqual(graph.node_list(), [])
  8. o1 = object()
  9. o1b = object()
  10. o2 = object()
  11. graph.add_node(1, o1)
  12. graph.add_node(1, o1b)
  13. graph.add_node(2, o2)
  14. graph.add_node(3)
  15. self.assertRaises(TypeError, graph.add_node, [])
  16. self.assertTrue(graph.node_data(1) is o1)
  17. self.assertTrue(graph.node_data(2) is o2)
  18. self.assertTrue(graph.node_data(3) is None)
  19. self.assertTrue(1 in graph)
  20. self.assertTrue(2 in graph)
  21. self.assertTrue(3 in graph)
  22. self.assertEqual(graph.number_of_nodes(), 3)
  23. self.assertEqual(graph.number_of_hidden_nodes(), 0)
  24. self.assertEqual(graph.hidden_node_list(), [])
  25. self.assertEqual(list(sorted(graph)), [1, 2, 3])
  26. graph.hide_node(1)
  27. graph.hide_node(2)
  28. graph.hide_node(3)
  29. self.assertEqual(graph.number_of_nodes(), 0)
  30. self.assertEqual(graph.number_of_hidden_nodes(), 3)
  31. self.assertEqual(list(sorted(graph.hidden_node_list())), [1, 2, 3])
  32. self.assertFalse(1 in graph)
  33. self.assertFalse(2 in graph)
  34. self.assertFalse(3 in graph)
  35. graph.add_node(1)
  36. self.assertFalse(1 in graph)
  37. graph.restore_node(1)
  38. self.assertTrue(1 in graph)
  39. self.assertFalse(2 in graph)
  40. self.assertFalse(3 in graph)
  41. graph.restore_all_nodes()
  42. self.assertTrue(1 in graph)
  43. self.assertTrue(2 in graph)
  44. self.assertTrue(3 in graph)
  45. self.assertEqual(list(sorted(graph.node_list())), [1, 2, 3])
  46. v = graph.describe_node(1)
  47. self.assertEqual(v, (1, o1, [], []))
  48. def test_edges(self):
  49. graph = Graph()
  50. graph.add_node(1)
  51. graph.add_node(2)
  52. graph.add_node(3)
  53. graph.add_node(4)
  54. graph.add_node(5)
  55. self.assertTrue(isinstance(graph.edge_list(), list))
  56. graph.add_edge(1, 2)
  57. graph.add_edge(4, 5, 'a')
  58. self.assertRaises(GraphError, graph.add_edge, 'a', 'b', create_nodes=False)
  59. self.assertEqual(graph.number_of_hidden_edges(), 0)
  60. self.assertEqual(graph.number_of_edges(), 2)
  61. e = graph.edge_by_node(1, 2)
  62. self.assertTrue(isinstance(e, int))
  63. graph.hide_edge(e)
  64. self.assertEqual(graph.number_of_hidden_edges(), 1)
  65. self.assertEqual(graph.number_of_edges(), 1)
  66. e2 = graph.edge_by_node(1, 2)
  67. self.assertTrue(e2 is None)
  68. graph.restore_edge(e)
  69. e2 = graph.edge_by_node(1, 2)
  70. self.assertEqual(e, e2)
  71. self.assertEqual(graph.number_of_hidden_edges(), 0)
  72. self.assertEqual(graph.number_of_edges(), 2)
  73. e1 = graph.edge_by_node(1, 2)
  74. e2 = graph.edge_by_node(4, 5)
  75. graph.hide_edge(e1)
  76. graph.hide_edge(e2)
  77. self.assertEqual(graph.number_of_edges(), 0)
  78. graph.restore_all_edges()
  79. self.assertEqual(graph.number_of_edges(), 2)
  80. self.assertEqual(graph.edge_by_id(e1), (1,2))
  81. self.assertRaises(GraphError, graph.edge_by_id, (e1+1)*(e2+1)+1)
  82. self.assertEqual(list(sorted(graph.edge_list())), [e1, e2])
  83. self.assertEqual(graph.describe_edge(e1), (e1, 1, 1, 2))
  84. self.assertEqual(graph.describe_edge(e2), (e2, 'a', 4, 5))
  85. self.assertEqual(graph.edge_data(e1), 1)
  86. self.assertEqual(graph.edge_data(e2), 'a')
  87. self.assertEqual(graph.head(e2), 4)
  88. self.assertEqual(graph.tail(e2), 5)
  89. graph.add_edge(1, 3)
  90. graph.add_edge(1, 5)
  91. graph.add_edge(4, 1)
  92. self.assertEqual(list(sorted(graph.out_nbrs(1))), [2, 3, 5])
  93. self.assertEqual(list(sorted(graph.inc_nbrs(1))), [4])
  94. self.assertEqual(list(sorted(graph.inc_nbrs(5))), [1, 4])
  95. self.assertEqual(list(sorted(graph.all_nbrs(1))), [2, 3, 4, 5])
  96. graph.add_edge(5, 1)
  97. self.assertEqual(list(sorted(graph.all_nbrs(5))), [1, 4])
  98. self.assertEqual(graph.out_degree(1), 3)
  99. self.assertEqual(graph.inc_degree(2), 1)
  100. self.assertEqual(graph.inc_degree(5), 2)
  101. self.assertEqual(graph.all_degree(5), 3)
  102. v = graph.out_edges(4)
  103. self.assertTrue(isinstance(v, list))
  104. self.assertEqual(graph.edge_by_id(v[0]), (4, 5))
  105. v = graph.out_edges(1)
  106. for e in v:
  107. self.assertEqual(graph.edge_by_id(e)[0], 1)
  108. v = graph.inc_edges(1)
  109. self.assertTrue(isinstance(v, list))
  110. self.assertEqual(graph.edge_by_id(v[0]), (4, 1))
  111. v = graph.inc_edges(5)
  112. for e in v:
  113. self.assertEqual(graph.edge_by_id(e)[1], 5)
  114. v = graph.all_edges(5)
  115. for e in v:
  116. self.assertTrue(graph.edge_by_id(e)[1] == 5 or graph.edge_by_id(e)[0] == 5)
  117. e1 = graph.edge_by_node(1, 2)
  118. self.assertTrue(isinstance(e1, int))
  119. graph.hide_node(1)
  120. self.assertRaises(GraphError, graph.edge_by_node, 1, 2)
  121. graph.restore_node(1)
  122. e2 = graph.edge_by_node(1, 2)
  123. self.assertEqual(e1, e2)
  124. def test_toposort(self):
  125. graph = Graph()
  126. graph.add_node(1)
  127. graph.add_node(2)
  128. graph.add_node(3)
  129. graph.add_node(4)
  130. graph.add_node(5)
  131. graph.add_edge(1, 2)
  132. graph.add_edge(1, 3)
  133. graph.add_edge(2, 4)
  134. graph.add_edge(3, 5)
  135. ok, result = graph.forw_topo_sort()
  136. self.assertTrue(ok)
  137. for idx in range(1, 6):
  138. self.assertTrue(idx in result)
  139. self.assertTrue(result.index(1) < result.index(2))
  140. self.assertTrue(result.index(1) < result.index(3))
  141. self.assertTrue(result.index(2) < result.index(4))
  142. self.assertTrue(result.index(3) < result.index(5))
  143. ok, result = graph.back_topo_sort()
  144. self.assertTrue(ok)
  145. for idx in range(1, 6):
  146. self.assertTrue(idx in result)
  147. self.assertTrue(result.index(2) < result.index(1))
  148. self.assertTrue(result.index(3) < result.index(1))
  149. self.assertTrue(result.index(4) < result.index(2))
  150. self.assertTrue(result.index(5) < result.index(3))
  151. # Same graph as before, but with edges
  152. # reversed, which means we should get
  153. # the same results as before if using
  154. # back_topo_sort rather than forw_topo_sort
  155. # (and v.v.)
  156. graph = Graph()
  157. graph.add_node(1)
  158. graph.add_node(2)
  159. graph.add_node(3)
  160. graph.add_node(4)
  161. graph.add_node(5)
  162. graph.add_edge(2, 1)
  163. graph.add_edge(3, 1)
  164. graph.add_edge(4, 2)
  165. graph.add_edge(5, 3)
  166. ok, result = graph.back_topo_sort()
  167. self.assertTrue(ok)
  168. for idx in range(1, 6):
  169. self.assertTrue(idx in result)
  170. self.assertTrue(result.index(1) < result.index(2))
  171. self.assertTrue(result.index(1) < result.index(3))
  172. self.assertTrue(result.index(2) < result.index(4))
  173. self.assertTrue(result.index(3) < result.index(5))
  174. ok, result = graph.forw_topo_sort()
  175. self.assertTrue(ok)
  176. for idx in range(1, 6):
  177. self.assertTrue(idx in result)
  178. self.assertTrue(result.index(2) < result.index(1))
  179. self.assertTrue(result.index(3) < result.index(1))
  180. self.assertTrue(result.index(4) < result.index(2))
  181. self.assertTrue(result.index(5) < result.index(3))
  182. # Create a cycle
  183. graph.add_edge(1, 5)
  184. ok, result = graph.forw_topo_sort()
  185. self.assertFalse(ok)
  186. ok, result = graph.back_topo_sort()
  187. self.assertFalse(ok)
  188. def test_bfs_subgraph(self):
  189. graph = Graph()
  190. graph.add_edge(1, 2)
  191. graph.add_edge(1, 4)
  192. graph.add_edge(2, 4)
  193. graph.add_edge(4, 8)
  194. graph.add_edge(4, 9)
  195. graph.add_edge(4, 10)
  196. graph.add_edge(8, 10)
  197. subgraph = graph.forw_bfs_subgraph(10)
  198. self.assertTrue(isinstance(subgraph, Graph))
  199. self.assertEqual(subgraph.number_of_nodes(), 1)
  200. self.assertTrue(10 in subgraph)
  201. self.assertEqual(subgraph.number_of_edges(), 0)
  202. subgraph = graph.forw_bfs_subgraph(4)
  203. self.assertTrue(isinstance(subgraph, Graph))
  204. self.assertEqual(subgraph.number_of_nodes(), 4)
  205. self.assertTrue(4 in subgraph)
  206. self.assertTrue(8 in subgraph)
  207. self.assertTrue(9 in subgraph)
  208. self.assertTrue(10 in subgraph)
  209. self.assertEqual(subgraph.number_of_edges(), 4)
  210. e = subgraph.edge_by_node(4, 8)
  211. e = subgraph.edge_by_node(4, 9)
  212. e = subgraph.edge_by_node(4, 10)
  213. e = subgraph.edge_by_node(8, 10)
  214. # same graph as before, but switch around
  215. # edges. This results in the same test results
  216. # but now for back_bfs_subgraph rather than
  217. # forw_bfs_subgraph
  218. graph = Graph()
  219. graph.add_edge(2, 1)
  220. graph.add_edge(4, 1)
  221. graph.add_edge(4, 2)
  222. graph.add_edge(8, 4)
  223. graph.add_edge(9, 4)
  224. graph.add_edge(10, 4)
  225. graph.add_edge(10, 8)
  226. subgraph = graph.back_bfs_subgraph(10)
  227. self.assertTrue(isinstance(subgraph, Graph))
  228. self.assertEqual(subgraph.number_of_nodes(), 1)
  229. self.assertTrue(10 in subgraph)
  230. self.assertEqual(subgraph.number_of_edges(), 0)
  231. subgraph = graph.back_bfs_subgraph(4)
  232. self.assertTrue(isinstance(subgraph, Graph))
  233. self.assertEqual(subgraph.number_of_nodes(), 4)
  234. self.assertTrue(4 in subgraph)
  235. self.assertTrue(8 in subgraph)
  236. self.assertTrue(9 in subgraph)
  237. self.assertTrue(10 in subgraph)
  238. self.assertEqual(subgraph.number_of_edges(), 4)
  239. e = subgraph.edge_by_node(4, 8)
  240. e = subgraph.edge_by_node(4, 9)
  241. e = subgraph.edge_by_node(4, 10)
  242. e = subgraph.edge_by_node(8, 10)
  243. def test_iterdfs(self):
  244. graph = Graph()
  245. graph.add_edge("1", "1.1")
  246. graph.add_edge("1", "1.2")
  247. graph.add_edge("1", "1.3")
  248. graph.add_edge("1.1", "1.1.1")
  249. graph.add_edge("1.1", "1.1.2")
  250. graph.add_edge("1.2", "1.2.1")
  251. graph.add_edge("1.2", "1.2.2")
  252. graph.add_edge("1.2.2", "1.2.2.1")
  253. graph.add_edge("1.2.2", "1.2.2.2")
  254. graph.add_edge("1.2.2", "1.2.2.3")
  255. result = list(graph.iterdfs("1"))
  256. self.assertEqual(result, [
  257. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  258. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  259. ])
  260. result = list(graph.iterdfs("1", "1.2.1"))
  261. self.assertEqual(result, [
  262. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  263. '1.2.2.1', '1.2.1'
  264. ])
  265. result = graph.forw_dfs("1")
  266. self.assertEqual(result, [
  267. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  268. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  269. ])
  270. result = graph.forw_dfs("1", "1.2.1")
  271. self.assertEqual(result, [
  272. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  273. '1.2.2.1', '1.2.1'
  274. ])
  275. graph = Graph()
  276. graph.add_edge("1.1", "1")
  277. graph.add_edge("1.2", "1")
  278. graph.add_edge("1.3", "1")
  279. graph.add_edge("1.1.1", "1.1")
  280. graph.add_edge("1.1.2", "1.1")
  281. graph.add_edge("1.2.1", "1.2")
  282. graph.add_edge("1.2.2", "1.2")
  283. graph.add_edge("1.2.2.1", "1.2.2")
  284. graph.add_edge("1.2.2.2", "1.2.2")
  285. graph.add_edge("1.2.2.3", "1.2.2")
  286. result = list(graph.iterdfs("1", forward=False))
  287. self.assertEqual(result, [
  288. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  289. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  290. ])
  291. result = list(graph.iterdfs("1", "1.2.1", forward=False))
  292. self.assertEqual(result, [
  293. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  294. '1.2.2.1', '1.2.1'
  295. ])
  296. result = graph.back_dfs("1")
  297. self.assertEqual(result, [
  298. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  299. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  300. ])
  301. result = graph.back_dfs("1", "1.2.1")
  302. self.assertEqual(result, [
  303. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  304. '1.2.2.1', '1.2.1'
  305. ])
  306. # Introduce cyle:
  307. graph.add_edge("1", "1.2")
  308. result = list(graph.iterdfs("1", forward=False))
  309. self.assertEqual(result, [
  310. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  311. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  312. ])
  313. result = graph.back_dfs("1")
  314. self.assertEqual(result, [
  315. '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
  316. '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
  317. ])
  318. def test_iterdata(self):
  319. graph = Graph()
  320. graph.add_node("1", "I")
  321. graph.add_node("1.1", "I.I")
  322. graph.add_node("1.2", "I.II")
  323. graph.add_node("1.3", "I.III")
  324. graph.add_node("1.1.1", "I.I.I")
  325. graph.add_node("1.1.2", "I.I.II")
  326. graph.add_node("1.2.1", "I.II.I")
  327. graph.add_node("1.2.2", "I.II.II")
  328. graph.add_node("1.2.2.1", "I.II.II.I")
  329. graph.add_node("1.2.2.2", "I.II.II.II")
  330. graph.add_node("1.2.2.3", "I.II.II.III")
  331. graph.add_edge("1", "1.1")
  332. graph.add_edge("1", "1.2")
  333. graph.add_edge("1", "1.3")
  334. graph.add_edge("1.1", "1.1.1")
  335. graph.add_edge("1.1", "1.1.2")
  336. graph.add_edge("1.2", "1.2.1")
  337. graph.add_edge("1.2", "1.2.2")
  338. graph.add_edge("1.2.2", "1.2.2.1")
  339. graph.add_edge("1.2.2", "1.2.2.2")
  340. graph.add_edge("1.2.2", "1.2.2.3")
  341. result = list(graph.iterdata("1", forward=True))
  342. self.assertEqual(result, [
  343. 'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
  344. 'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
  345. ])
  346. result = list(graph.iterdata("1", end="1.2.1", forward=True))
  347. self.assertEqual(result, [
  348. 'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
  349. 'I.II.II.I', 'I.II.I'
  350. ])
  351. result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=True))
  352. self.assertEqual(result, [
  353. 'I', 'I.III', 'I.II',
  354. 'I.I', 'I.I.I'
  355. ])
  356. # And the revese option:
  357. graph = Graph()
  358. graph.add_node("1", "I")
  359. graph.add_node("1.1", "I.I")
  360. graph.add_node("1.2", "I.II")
  361. graph.add_node("1.3", "I.III")
  362. graph.add_node("1.1.1", "I.I.I")
  363. graph.add_node("1.1.2", "I.I.II")
  364. graph.add_node("1.2.1", "I.II.I")
  365. graph.add_node("1.2.2", "I.II.II")
  366. graph.add_node("1.2.2.1", "I.II.II.I")
  367. graph.add_node("1.2.2.2", "I.II.II.II")
  368. graph.add_node("1.2.2.3", "I.II.II.III")
  369. graph.add_edge("1.1", "1")
  370. graph.add_edge("1.2", "1")
  371. graph.add_edge("1.3", "1")
  372. graph.add_edge("1.1.1", "1.1")
  373. graph.add_edge("1.1.2", "1.1")
  374. graph.add_edge("1.2.1", "1.2")
  375. graph.add_edge("1.2.2", "1.2")
  376. graph.add_edge("1.2.2.1", "1.2.2")
  377. graph.add_edge("1.2.2.2", "1.2.2")
  378. graph.add_edge("1.2.2.3", "1.2.2")
  379. result = list(graph.iterdata("1", forward=False))
  380. self.assertEqual(result, [
  381. 'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
  382. 'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
  383. ])
  384. result = list(graph.iterdata("1", end="1.2.1", forward=False))
  385. self.assertEqual(result, [
  386. 'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
  387. 'I.II.II.I', 'I.II.I'
  388. ])
  389. result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=False))
  390. self.assertEqual(result, [
  391. 'I', 'I.III', 'I.II',
  392. 'I.I', 'I.I.I'
  393. ])
  394. def test_bfs(self):
  395. graph = Graph()
  396. graph.add_edge("1", "1.1")
  397. graph.add_edge("1.1", "1.1.1")
  398. graph.add_edge("1.1", "1.1.2")
  399. graph.add_edge("1.1.2", "1.1.2.1")
  400. graph.add_edge("1.1.2", "1.1.2.2")
  401. graph.add_edge("1", "1.2")
  402. graph.add_edge("1", "1.3")
  403. graph.add_edge("1.2", "1.2.1")
  404. self.assertEqual(graph.forw_bfs("1"),
  405. ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
  406. self.assertEqual(graph.forw_bfs("1", "1.1.1"),
  407. ['1', '1.1', '1.2', '1.3', '1.1.1'])
  408. # And the "reverse" graph
  409. graph = Graph()
  410. graph.add_edge("1.1", "1")
  411. graph.add_edge("1.1.1", "1.1")
  412. graph.add_edge("1.1.2", "1.1")
  413. graph.add_edge("1.1.2.1", "1.1.2")
  414. graph.add_edge("1.1.2.2", "1.1.2")
  415. graph.add_edge("1.2", "1")
  416. graph.add_edge("1.3", "1")
  417. graph.add_edge("1.2.1", "1.2")
  418. self.assertEqual(graph.back_bfs("1"),
  419. ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
  420. self.assertEqual(graph.back_bfs("1", "1.1.1"),
  421. ['1', '1.1', '1.2', '1.3', '1.1.1'])
  422. # check cycle handling
  423. graph.add_edge("1", "1.2.1")
  424. self.assertEqual(graph.back_bfs("1"),
  425. ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
  426. def test_connected(self):
  427. graph = Graph()
  428. graph.add_node(1)
  429. graph.add_node(2)
  430. graph.add_node(3)
  431. graph.add_node(4)
  432. self.assertFalse(graph.connected())
  433. graph.add_edge(1, 2)
  434. graph.add_edge(3, 4)
  435. self.assertFalse(graph.connected())
  436. graph.add_edge(2, 3)
  437. graph.add_edge(4, 1)
  438. self.assertTrue(graph.connected())
  439. def test_edges_complex(self):
  440. g = Graph()
  441. g.add_edge(1, 2)
  442. e = g.edge_by_node(1,2)
  443. g.hide_edge(e)
  444. g.hide_node(2)
  445. self.assertRaises(GraphError, g.restore_edge, e)
  446. g.restore_all_edges()
  447. self.assertRaises(GraphError, g.edge_by_id, e)
  448. def test_clust_coef(self):
  449. g = Graph()
  450. g.add_edge(1, 2)
  451. g.add_edge(1, 3)
  452. g.add_edge(1, 4)
  453. self.assertEqual(g.clust_coef(1), 0)
  454. g.add_edge(2, 5)
  455. g.add_edge(3, 5)
  456. g.add_edge(4, 5)
  457. self.assertEqual(g.clust_coef(1), 0)
  458. g.add_edge(2, 3)
  459. self.assertEqual(g.clust_coef(1), 1./6)
  460. g.add_edge(2, 4)
  461. self.assertEqual(g.clust_coef(1), 2./6)
  462. g.add_edge(4, 2)
  463. self.assertEqual(g.clust_coef(1), 3./6)
  464. g.add_edge(2, 3)
  465. g.add_edge(2, 4)
  466. g.add_edge(3, 4)
  467. g.add_edge(3, 2)
  468. g.add_edge(4, 2)
  469. g.add_edge(4, 3)
  470. self.assertEqual(g.clust_coef(1), 1)
  471. def test_get_hops(self):
  472. graph = Graph()
  473. graph.add_edge(1, 2)
  474. graph.add_edge(1, 3)
  475. graph.add_edge(2, 4)
  476. graph.add_edge(4, 5)
  477. graph.add_edge(5, 7)
  478. graph.add_edge(7, 8)
  479. self.assertEqual(graph.get_hops(1),
  480. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
  481. self.assertEqual(graph.get_hops(1, 5),
  482. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
  483. graph.add_edge(5, 1)
  484. graph.add_edge(7, 1)
  485. graph.add_edge(7, 4)
  486. self.assertEqual(graph.get_hops(1),
  487. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
  488. # And the reverse graph
  489. graph = Graph()
  490. graph.add_edge(2, 1)
  491. graph.add_edge(3, 1)
  492. graph.add_edge(4, 2)
  493. graph.add_edge(5, 4)
  494. graph.add_edge(7, 5)
  495. graph.add_edge(8, 7)
  496. self.assertEqual(graph.get_hops(1, forward=False),
  497. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
  498. self.assertEqual(graph.get_hops(1, 5, forward=False),
  499. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
  500. graph.add_edge(1, 5)
  501. graph.add_edge(1, 7)
  502. graph.add_edge(4, 7)
  503. self.assertEqual(graph.get_hops(1, forward=False),
  504. [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
  505. def test_constructor(self):
  506. graph = Graph(iter([
  507. (1, 2),
  508. (2, 3, 'a'),
  509. (1, 3),
  510. (3, 4),
  511. ]))
  512. self.assertEqual(graph.number_of_nodes(), 4)
  513. self.assertEqual(graph.number_of_edges(), 4)
  514. try:
  515. graph.edge_by_node(1,2)
  516. graph.edge_by_node(2,3)
  517. graph.edge_by_node(1,3)
  518. graph.edge_by_node(3,4)
  519. except GraphError:
  520. self.fail("Incorrect graph")
  521. self.assertEqual(graph.edge_data(graph.edge_by_node(2, 3)), 'a')
  522. self.assertRaises(GraphError, Graph, [(1,2,3,4)])
  523. if __name__ == "__main__": # pragma: no cover
  524. unittest.main()