okstra 0.114.0 → 0.115.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/docs/kr/architecture.md +2 -2
  2. package/docs/kr/follow-ups/2026-07-10-final-report-option-3.md +51 -0
  3. package/package.json +1 -1
  4. package/runtime/BUILD.json +2 -2
  5. package/runtime/agents/workers/report-writer-worker.md +1 -0
  6. package/runtime/prompts/lead/okstra-lead-contract.md +1 -1
  7. package/runtime/python/okstra_ctl/implementation_stage.py +46 -39
  8. package/runtime/python/okstra_ctl/report_views.py +151 -12
  9. package/runtime/python/okstra_ctl/run.py +24 -24
  10. package/runtime/python/okstra_ctl/worktree.py +1 -1
  11. package/runtime/python/okstra_token_usage/claude.py +58 -19
  12. package/runtime/python/okstra_token_usage/collect.py +3 -1
  13. package/runtime/python/okstra_vendor/__init__.py +3 -0
  14. package/runtime/schemas/final-report-v1.0.schema.json +20 -0
  15. package/runtime/templates/reports/final-report.template.md +14 -0
  16. package/runtime/templates/reports/i18n/en.json +23 -12
  17. package/runtime/templates/reports/i18n/ko.json +23 -12
  18. package/runtime/templates/reports/report.css +55 -0
  19. package/runtime/templates/reports/report.js +53 -1
  20. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/__init__.py +0 -0
  21. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_approx_clust_coeff.py +0 -41
  22. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_clique.py +0 -112
  23. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_connectivity.py +0 -199
  24. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_density.py +0 -146
  25. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_distance_measures.py +0 -59
  26. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_dominating_set.py +0 -78
  27. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_kcomponents.py +0 -303
  28. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_matching.py +0 -8
  29. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_maxcut.py +0 -94
  30. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_ramsey.py +0 -31
  31. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_steinertree.py +0 -306
  32. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_traveling_salesman.py +0 -1014
  33. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_treewidth.py +0 -274
  34. package/runtime/python/okstra_vendor/networkx/algorithms/approximation/tests/test_vertex_cover.py +0 -68
  35. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/__init__.py +0 -0
  36. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/base_test.py +0 -81
  37. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_connectivity.py +0 -143
  38. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_correlation.py +0 -122
  39. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_mixing.py +0 -174
  40. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_neighbor_degree.py +0 -107
  41. package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/tests/test_pairs.py +0 -87
  42. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/__init__.py +0 -0
  43. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_basic.py +0 -125
  44. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_centrality.py +0 -192
  45. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_cluster.py +0 -84
  46. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_covering.py +0 -33
  47. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_edgelist.py +0 -240
  48. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_extendability.py +0 -334
  49. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_generators.py +0 -407
  50. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_link_analysis.py +0 -218
  51. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matching.py +0 -327
  52. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_matrix.py +0 -138
  53. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_project.py +0 -409
  54. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_redundancy.py +0 -35
  55. package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/tests/test_spectral_bipartivity.py +0 -80
  56. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/__init__.py +0 -0
  57. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality.py +0 -923
  58. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_betweenness_centrality_subset.py +0 -354
  59. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_closeness_centrality.py +0 -274
  60. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality.py +0 -259
  61. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_betweenness_centrality_subset.py +0 -147
  62. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_current_flow_closeness.py +0 -43
  63. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_degree_centrality.py +0 -144
  64. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_dispersion.py +0 -73
  65. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_eigenvector_centrality.py +0 -186
  66. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_group.py +0 -277
  67. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_harmonic_centrality.py +0 -122
  68. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_katz_centrality.py +0 -345
  69. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_laplacian_centrality.py +0 -220
  70. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_load_centrality.py +0 -344
  71. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_percolation_centrality.py +0 -87
  72. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_reaching.py +0 -140
  73. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_second_order_centrality.py +0 -82
  74. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_subgraph.py +0 -110
  75. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_trophic.py +0 -302
  76. package/runtime/python/okstra_vendor/networkx/algorithms/centrality/tests/test_voterank.py +0 -64
  77. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/__init__.py +0 -0
  78. package/runtime/python/okstra_vendor/networkx/algorithms/coloring/tests/test_coloring.py +0 -863
  79. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/__init__.py +0 -0
  80. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_asyn_fluid.py +0 -147
  81. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_bipartitions.py +0 -157
  82. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_centrality.py +0 -85
  83. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_divisive.py +0 -106
  84. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_kclique.py +0 -91
  85. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_label_propagation.py +0 -241
  86. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_leiden.py +0 -138
  87. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_local.py +0 -76
  88. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_louvain.py +0 -264
  89. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_lukes.py +0 -152
  90. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_modularity_max.py +0 -340
  91. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_quality.py +0 -139
  92. package/runtime/python/okstra_vendor/networkx/algorithms/community/tests/test_utils.py +0 -26
  93. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/__init__.py +0 -0
  94. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_attracting.py +0 -70
  95. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_biconnected.py +0 -248
  96. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_connected.py +0 -138
  97. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_semiconnected.py +0 -55
  98. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_strongly_connected.py +0 -193
  99. package/runtime/python/okstra_vendor/networkx/algorithms/components/tests/test_weakly_connected.py +0 -96
  100. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/__init__.py +0 -0
  101. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_connectivity.py +0 -421
  102. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_cuts.py +0 -309
  103. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_disjoint_paths.py +0 -249
  104. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_augmentation.py +0 -502
  105. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_edge_kcomponents.py +0 -488
  106. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcomponents.py +0 -323
  107. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_kcutsets.py +0 -280
  108. package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/tests/test_stoer_wagner.py +0 -102
  109. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/__init__.py +0 -0
  110. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gl1.gpickle.bz2 +0 -0
  111. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/gw1.gpickle.bz2 +0 -0
  112. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/netgen-2.gpickle.bz2 +0 -0
  113. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_gomory_hu.py +0 -128
  114. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow.py +0 -573
  115. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_maxflow_large_graph.py +0 -155
  116. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_mincost.py +0 -475
  117. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/test_networksimplex.py +0 -481
  118. package/runtime/python/okstra_vendor/networkx/algorithms/flow/tests/wlm3.gpickle.bz2 +0 -0
  119. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/__init__.py +0 -0
  120. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.A99 +0 -0
  121. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/iso_r01_s80.B99 +0 -0
  122. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.A99 +0 -0
  123. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/si2_b06_m200.B99 +0 -0
  124. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_ismags.py +0 -719
  125. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphism.py +0 -103
  126. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_isomorphvf2.py +0 -490
  127. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_match_helpers.py +0 -64
  128. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_temporalisomorphvf2.py +0 -212
  129. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_tree_isomorphism.py +0 -202
  130. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp.py +0 -1655
  131. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2pp_helpers.py +0 -3118
  132. package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tests/test_vf2userfunc.py +0 -196
  133. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/__init__.py +0 -0
  134. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_hits.py +0 -77
  135. package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/tests/test_pagerank.py +0 -213
  136. package/runtime/python/okstra_vendor/networkx/algorithms/minors/tests/test_contraction.py +0 -544
  137. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/__init__.py +0 -0
  138. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_all.py +0 -328
  139. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_binary.py +0 -451
  140. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_product.py +0 -491
  141. package/runtime/python/okstra_vendor/networkx/algorithms/operators/tests/test_unary.py +0 -55
  142. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/__init__.py +0 -0
  143. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_astar.py +0 -254
  144. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense.py +0 -212
  145. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_dense_numpy.py +0 -88
  146. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_generic.py +0 -511
  147. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_unweighted.py +0 -149
  148. package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/tests/test_weighted.py +0 -983
  149. package/runtime/python/okstra_vendor/networkx/algorithms/tests/__init__.py +0 -0
  150. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_asteroidal.py +0 -23
  151. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_boundary.py +0 -154
  152. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_bridges.py +0 -144
  153. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_broadcasting.py +0 -109
  154. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chains.py +0 -136
  155. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_chordal.py +0 -129
  156. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_clique.py +0 -300
  157. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cluster.py +0 -678
  158. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_communicability.py +0 -80
  159. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_core.py +0 -266
  160. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_covering.py +0 -85
  161. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cuts.py +0 -171
  162. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_cycles.py +0 -984
  163. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_d_separation.py +0 -340
  164. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dag.py +0 -835
  165. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_measures.py +0 -831
  166. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_distance_regular.py +0 -85
  167. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominance.py +0 -299
  168. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_dominating.py +0 -115
  169. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_efficiency.py +0 -58
  170. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_euler.py +0 -314
  171. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graph_hashing.py +0 -872
  172. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_graphical.py +0 -163
  173. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hierarchy.py +0 -46
  174. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_hybrid.py +0 -24
  175. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_isolate.py +0 -26
  176. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_link_prediction.py +0 -615
  177. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_lowest_common_ancestors.py +0 -459
  178. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_matching.py +0 -556
  179. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_max_weight_clique.py +0 -179
  180. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_mis.py +0 -62
  181. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_moral.py +0 -15
  182. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_node_classification.py +0 -140
  183. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_non_randomness.py +0 -60
  184. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_perfect_graph.py +0 -27
  185. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planar_drawing.py +0 -274
  186. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_planarity.py +0 -556
  187. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_polynomials.py +0 -57
  188. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_reciprocity.py +0 -37
  189. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_regular.py +0 -88
  190. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_richclub.py +0 -149
  191. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_similarity.py +0 -1158
  192. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_simple_paths.py +0 -803
  193. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smallworld.py +0 -76
  194. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_smetric.py +0 -8
  195. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_sparsifiers.py +0 -138
  196. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_structuralholes.py +0 -191
  197. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_summarization.py +0 -642
  198. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_swap.py +0 -179
  199. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_threshold.py +0 -270
  200. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_time_dependent.py +0 -431
  201. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_tournament.py +0 -161
  202. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_triads.py +0 -248
  203. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_vitality.py +0 -41
  204. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_voronoi.py +0 -103
  205. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_walks.py +0 -54
  206. package/runtime/python/okstra_vendor/networkx/algorithms/tests/test_wiener.py +0 -157
  207. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/__init__.py +0 -0
  208. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_beamsearch.py +0 -25
  209. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_bfs.py +0 -203
  210. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_dfs.py +0 -307
  211. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgebfs.py +0 -147
  212. package/runtime/python/okstra_vendor/networkx/algorithms/traversal/tests/test_edgedfs.py +0 -131
  213. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/__init__.py +0 -0
  214. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_branchings.py +0 -624
  215. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_coding.py +0 -114
  216. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_decomposition.py +0 -79
  217. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_distance_measures.py +0 -99
  218. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_mst.py +0 -934
  219. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_operations.py +0 -53
  220. package/runtime/python/okstra_vendor/networkx/algorithms/tree/tests/test_recognition.py +0 -174
  221. package/runtime/python/okstra_vendor/networkx/classes/tests/__init__.py +0 -0
  222. package/runtime/python/okstra_vendor/networkx/classes/tests/dispatch_interface.py +0 -192
  223. package/runtime/python/okstra_vendor/networkx/classes/tests/historical_tests.py +0 -476
  224. package/runtime/python/okstra_vendor/networkx/classes/tests/test_coreviews.py +0 -362
  225. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph.py +0 -331
  226. package/runtime/python/okstra_vendor/networkx/classes/tests/test_digraph_historical.py +0 -110
  227. package/runtime/python/okstra_vendor/networkx/classes/tests/test_filters.py +0 -177
  228. package/runtime/python/okstra_vendor/networkx/classes/tests/test_function.py +0 -1045
  229. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph.py +0 -950
  230. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graph_historical.py +0 -12
  231. package/runtime/python/okstra_vendor/networkx/classes/tests/test_graphviews.py +0 -349
  232. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multidigraph.py +0 -459
  233. package/runtime/python/okstra_vendor/networkx/classes/tests/test_multigraph.py +0 -528
  234. package/runtime/python/okstra_vendor/networkx/classes/tests/test_reportviews.py +0 -1421
  235. package/runtime/python/okstra_vendor/networkx/classes/tests/test_special.py +0 -131
  236. package/runtime/python/okstra_vendor/networkx/classes/tests/test_subgraphviews.py +0 -371
  237. package/runtime/python/okstra_vendor/networkx/conftest.py +0 -261
  238. package/runtime/python/okstra_vendor/networkx/drawing/tests/__init__.py +0 -0
  239. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_complex.png +0 -0
  240. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_empty_graph.png +0 -0
  241. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_house_with_colors.png +0 -0
  242. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_labels_and_colors.png +0 -0
  243. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_display_shortest_path.png +0 -0
  244. package/runtime/python/okstra_vendor/networkx/drawing/tests/baseline/test_house_with_colors.png +0 -0
  245. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_agraph.py +0 -237
  246. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_image_comparison_pylab_mpl.py +0 -229
  247. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_latex.py +0 -285
  248. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_layout.py +0 -631
  249. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pydot.py +0 -146
  250. package/runtime/python/okstra_vendor/networkx/drawing/tests/test_pylab.py +0 -1582
  251. package/runtime/python/okstra_vendor/networkx/generators/tests/__init__.py +0 -0
  252. package/runtime/python/okstra_vendor/networkx/generators/tests/test_atlas.py +0 -75
  253. package/runtime/python/okstra_vendor/networkx/generators/tests/test_classic.py +0 -642
  254. package/runtime/python/okstra_vendor/networkx/generators/tests/test_cographs.py +0 -20
  255. package/runtime/python/okstra_vendor/networkx/generators/tests/test_community.py +0 -362
  256. package/runtime/python/okstra_vendor/networkx/generators/tests/test_degree_seq.py +0 -224
  257. package/runtime/python/okstra_vendor/networkx/generators/tests/test_directed.py +0 -189
  258. package/runtime/python/okstra_vendor/networkx/generators/tests/test_duplication.py +0 -103
  259. package/runtime/python/okstra_vendor/networkx/generators/tests/test_ego.py +0 -39
  260. package/runtime/python/okstra_vendor/networkx/generators/tests/test_expanders.py +0 -182
  261. package/runtime/python/okstra_vendor/networkx/generators/tests/test_geometric.py +0 -488
  262. package/runtime/python/okstra_vendor/networkx/generators/tests/test_harary_graph.py +0 -133
  263. package/runtime/python/okstra_vendor/networkx/generators/tests/test_internet_as_graphs.py +0 -221
  264. package/runtime/python/okstra_vendor/networkx/generators/tests/test_intersection.py +0 -28
  265. package/runtime/python/okstra_vendor/networkx/generators/tests/test_interval_graph.py +0 -144
  266. package/runtime/python/okstra_vendor/networkx/generators/tests/test_joint_degree_seq.py +0 -125
  267. package/runtime/python/okstra_vendor/networkx/generators/tests/test_lattice.py +0 -264
  268. package/runtime/python/okstra_vendor/networkx/generators/tests/test_line.py +0 -316
  269. package/runtime/python/okstra_vendor/networkx/generators/tests/test_mycielski.py +0 -30
  270. package/runtime/python/okstra_vendor/networkx/generators/tests/test_nonisomorphic_trees.py +0 -82
  271. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_clustered.py +0 -33
  272. package/runtime/python/okstra_vendor/networkx/generators/tests/test_random_graphs.py +0 -495
  273. package/runtime/python/okstra_vendor/networkx/generators/tests/test_small.py +0 -220
  274. package/runtime/python/okstra_vendor/networkx/generators/tests/test_spectral_graph_forge.py +0 -49
  275. package/runtime/python/okstra_vendor/networkx/generators/tests/test_stochastic.py +0 -72
  276. package/runtime/python/okstra_vendor/networkx/generators/tests/test_sudoku.py +0 -92
  277. package/runtime/python/okstra_vendor/networkx/generators/tests/test_time_series.py +0 -64
  278. package/runtime/python/okstra_vendor/networkx/generators/tests/test_trees.py +0 -195
  279. package/runtime/python/okstra_vendor/networkx/generators/tests/test_triads.py +0 -15
  280. package/runtime/python/okstra_vendor/networkx/linalg/tests/__init__.py +0 -0
  281. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_algebraic_connectivity.py +0 -400
  282. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_attrmatrix.py +0 -108
  283. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_bethehessian.py +0 -40
  284. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_graphmatrix.py +0 -275
  285. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_laplacian.py +0 -334
  286. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_modularity.py +0 -86
  287. package/runtime/python/okstra_vendor/networkx/linalg/tests/test_spectrum.py +0 -70
  288. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/__init__.py +0 -0
  289. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_adjacency.py +0 -78
  290. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_cytoscape.py +0 -78
  291. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_node_link.py +0 -109
  292. package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tests/test_tree.py +0 -48
  293. package/runtime/python/okstra_vendor/networkx/readwrite/tests/__init__.py +0 -0
  294. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_adjlist.py +0 -354
  295. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_edgelist.py +0 -318
  296. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gexf.py +0 -612
  297. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_gml.py +0 -744
  298. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graph6.py +0 -181
  299. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_graphml.py +0 -1531
  300. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_leda.py +0 -30
  301. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_p2g.py +0 -63
  302. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_pajek.py +0 -128
  303. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_sparse6.py +0 -166
  304. package/runtime/python/okstra_vendor/networkx/readwrite/tests/test_text.py +0 -1742
  305. package/runtime/python/okstra_vendor/networkx/tests/__init__.py +0 -0
  306. package/runtime/python/okstra_vendor/networkx/tests/test_all_random_functions.py +0 -248
  307. package/runtime/python/okstra_vendor/networkx/tests/test_convert.py +0 -321
  308. package/runtime/python/okstra_vendor/networkx/tests/test_convert_numpy.py +0 -531
  309. package/runtime/python/okstra_vendor/networkx/tests/test_convert_pandas.py +0 -349
  310. package/runtime/python/okstra_vendor/networkx/tests/test_convert_scipy.py +0 -281
  311. package/runtime/python/okstra_vendor/networkx/tests/test_exceptions.py +0 -40
  312. package/runtime/python/okstra_vendor/networkx/tests/test_import.py +0 -11
  313. package/runtime/python/okstra_vendor/networkx/tests/test_lazy_imports.py +0 -96
  314. package/runtime/python/okstra_vendor/networkx/tests/test_relabel.py +0 -349
  315. package/runtime/python/okstra_vendor/networkx/tests/test_removed_functions_exception_messages.py +0 -8
  316. package/runtime/python/okstra_vendor/networkx/utils/tests/__init__.py +0 -0
  317. package/runtime/python/okstra_vendor/networkx/utils/tests/test__init.py +0 -11
  318. package/runtime/python/okstra_vendor/networkx/utils/tests/test_backends.py +0 -225
  319. package/runtime/python/okstra_vendor/networkx/utils/tests/test_config.py +0 -263
  320. package/runtime/python/okstra_vendor/networkx/utils/tests/test_decorators.py +0 -510
  321. package/runtime/python/okstra_vendor/networkx/utils/tests/test_heaps.py +0 -131
  322. package/runtime/python/okstra_vendor/networkx/utils/tests/test_mapped_queue.py +0 -268
  323. package/runtime/python/okstra_vendor/networkx/utils/tests/test_misc.py +0 -393
  324. package/runtime/python/okstra_vendor/networkx/utils/tests/test_random_sequence.py +0 -53
  325. package/runtime/python/okstra_vendor/networkx/utils/tests/test_rcm.py +0 -63
  326. package/runtime/python/okstra_vendor/networkx/utils/tests/test_unionfind.py +0 -55
@@ -1,923 +0,0 @@
1
- import math
2
-
3
- import pytest
4
-
5
- import networkx as nx
6
-
7
-
8
- def weighted_G():
9
- G = nx.Graph()
10
- G.add_edge(0, 1, weight=3)
11
- G.add_edge(0, 2, weight=2)
12
- G.add_edge(0, 3, weight=6)
13
- G.add_edge(0, 4, weight=4)
14
- G.add_edge(1, 3, weight=5)
15
- G.add_edge(1, 5, weight=5)
16
- G.add_edge(2, 4, weight=1)
17
- G.add_edge(3, 4, weight=2)
18
- G.add_edge(3, 5, weight=1)
19
- G.add_edge(4, 5, weight=4)
20
- return G
21
-
22
-
23
- class TestBetweennessCentrality:
24
- def test_K5(self):
25
- """Betweenness centrality: K5"""
26
- G = nx.complete_graph(5)
27
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
28
- b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
29
- for n in sorted(G):
30
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
31
-
32
- def test_K5_endpoints(self):
33
- """Betweenness centrality: K5 endpoints"""
34
- G = nx.complete_graph(5)
35
- b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
36
- b_answer = {0: 4.0, 1: 4.0, 2: 4.0, 3: 4.0, 4: 4.0}
37
- for n in sorted(G):
38
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
39
- # normalized = True case
40
- b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
41
- b_answer = {0: 0.4, 1: 0.4, 2: 0.4, 3: 0.4, 4: 0.4}
42
- for n in sorted(G):
43
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
44
-
45
- def test_P3_normalized(self):
46
- """Betweenness centrality: P3 normalized"""
47
- G = nx.path_graph(3)
48
- b = nx.betweenness_centrality(G, weight=None, normalized=True)
49
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
50
- for n in sorted(G):
51
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
52
-
53
- def test_P3(self):
54
- """Betweenness centrality: P3"""
55
- G = nx.path_graph(3)
56
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
57
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
58
- for n in sorted(G):
59
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
60
-
61
- def test_sample_from_P3(self):
62
- """Betweenness centrality: P3 sample"""
63
- G = nx.path_graph(3)
64
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
65
- b = nx.betweenness_centrality(G, k=3, weight=None, normalized=False, seed=1)
66
- for n in sorted(G):
67
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
68
- b = nx.betweenness_centrality(G, k=2, weight=None, normalized=False, seed=1)
69
- # python versions give different results with same seed
70
- b_approx1 = {0: 0.0, 1: 1.0, 2: 0.0}
71
- b_approx2 = {0: 0.0, 1: 0.5, 2: 0.0}
72
- for n in sorted(G):
73
- assert b[n] in (b_approx1[n], b_approx2[n])
74
-
75
- def test_P3_endpoints(self):
76
- """Betweenness centrality: P3 endpoints"""
77
- G = nx.path_graph(3)
78
- b_answer = {0: 2.0, 1: 3.0, 2: 2.0}
79
- b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
80
- for n in sorted(G):
81
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
82
- # normalized = True case
83
- b_answer = {0: 2 / 3, 1: 1.0, 2: 2 / 3}
84
- b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
85
- for n in sorted(G):
86
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
87
-
88
- def test_krackhardt_kite_graph(self):
89
- """Betweenness centrality: Krackhardt kite graph"""
90
- G = nx.krackhardt_kite_graph()
91
- b_answer = {
92
- 0: 1.667,
93
- 1: 1.667,
94
- 2: 0.000,
95
- 3: 7.333,
96
- 4: 0.000,
97
- 5: 16.667,
98
- 6: 16.667,
99
- 7: 28.000,
100
- 8: 16.000,
101
- 9: 0.000,
102
- }
103
- for b in b_answer:
104
- b_answer[b] /= 2
105
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
106
- for n in sorted(G):
107
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
108
-
109
- def test_krackhardt_kite_graph_normalized(self):
110
- """Betweenness centrality: Krackhardt kite graph normalized"""
111
- G = nx.krackhardt_kite_graph()
112
- b_answer = {
113
- 0: 0.023,
114
- 1: 0.023,
115
- 2: 0.000,
116
- 3: 0.102,
117
- 4: 0.000,
118
- 5: 0.231,
119
- 6: 0.231,
120
- 7: 0.389,
121
- 8: 0.222,
122
- 9: 0.000,
123
- }
124
- b = nx.betweenness_centrality(G, weight=None, normalized=True)
125
- for n in sorted(G):
126
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
127
-
128
- def test_florentine_families_graph(self):
129
- """Betweenness centrality: Florentine families graph"""
130
- G = nx.florentine_families_graph()
131
- b_answer = {
132
- "Acciaiuoli": 0.000,
133
- "Albizzi": 0.212,
134
- "Barbadori": 0.093,
135
- "Bischeri": 0.104,
136
- "Castellani": 0.055,
137
- "Ginori": 0.000,
138
- "Guadagni": 0.255,
139
- "Lamberteschi": 0.000,
140
- "Medici": 0.522,
141
- "Pazzi": 0.000,
142
- "Peruzzi": 0.022,
143
- "Ridolfi": 0.114,
144
- "Salviati": 0.143,
145
- "Strozzi": 0.103,
146
- "Tornabuoni": 0.092,
147
- }
148
-
149
- b = nx.betweenness_centrality(G, weight=None, normalized=True)
150
- for n in sorted(G):
151
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
152
-
153
- def test_les_miserables_graph(self):
154
- """Betweenness centrality: Les Miserables graph"""
155
- G = nx.les_miserables_graph()
156
- b_answer = {
157
- "Napoleon": 0.000,
158
- "Myriel": 0.177,
159
- "MlleBaptistine": 0.000,
160
- "MmeMagloire": 0.000,
161
- "CountessDeLo": 0.000,
162
- "Geborand": 0.000,
163
- "Champtercier": 0.000,
164
- "Cravatte": 0.000,
165
- "Count": 0.000,
166
- "OldMan": 0.000,
167
- "Valjean": 0.570,
168
- "Labarre": 0.000,
169
- "Marguerite": 0.000,
170
- "MmeDeR": 0.000,
171
- "Isabeau": 0.000,
172
- "Gervais": 0.000,
173
- "Listolier": 0.000,
174
- "Tholomyes": 0.041,
175
- "Fameuil": 0.000,
176
- "Blacheville": 0.000,
177
- "Favourite": 0.000,
178
- "Dahlia": 0.000,
179
- "Zephine": 0.000,
180
- "Fantine": 0.130,
181
- "MmeThenardier": 0.029,
182
- "Thenardier": 0.075,
183
- "Cosette": 0.024,
184
- "Javert": 0.054,
185
- "Fauchelevent": 0.026,
186
- "Bamatabois": 0.008,
187
- "Perpetue": 0.000,
188
- "Simplice": 0.009,
189
- "Scaufflaire": 0.000,
190
- "Woman1": 0.000,
191
- "Judge": 0.000,
192
- "Champmathieu": 0.000,
193
- "Brevet": 0.000,
194
- "Chenildieu": 0.000,
195
- "Cochepaille": 0.000,
196
- "Pontmercy": 0.007,
197
- "Boulatruelle": 0.000,
198
- "Eponine": 0.011,
199
- "Anzelma": 0.000,
200
- "Woman2": 0.000,
201
- "MotherInnocent": 0.000,
202
- "Gribier": 0.000,
203
- "MmeBurgon": 0.026,
204
- "Jondrette": 0.000,
205
- "Gavroche": 0.165,
206
- "Gillenormand": 0.020,
207
- "Magnon": 0.000,
208
- "MlleGillenormand": 0.048,
209
- "MmePontmercy": 0.000,
210
- "MlleVaubois": 0.000,
211
- "LtGillenormand": 0.000,
212
- "Marius": 0.132,
213
- "BaronessT": 0.000,
214
- "Mabeuf": 0.028,
215
- "Enjolras": 0.043,
216
- "Combeferre": 0.001,
217
- "Prouvaire": 0.000,
218
- "Feuilly": 0.001,
219
- "Courfeyrac": 0.005,
220
- "Bahorel": 0.002,
221
- "Bossuet": 0.031,
222
- "Joly": 0.002,
223
- "Grantaire": 0.000,
224
- "MotherPlutarch": 0.000,
225
- "Gueulemer": 0.005,
226
- "Babet": 0.005,
227
- "Claquesous": 0.005,
228
- "Montparnasse": 0.004,
229
- "Toussaint": 0.000,
230
- "Child1": 0.000,
231
- "Child2": 0.000,
232
- "Brujon": 0.000,
233
- "MmeHucheloup": 0.000,
234
- }
235
-
236
- b = nx.betweenness_centrality(G, weight=None, normalized=True)
237
- for n in sorted(G):
238
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
239
-
240
- def test_ladder_graph(self):
241
- """Betweenness centrality: Ladder graph"""
242
- G = nx.Graph() # ladder_graph(3)
243
- G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
244
- b_answer = {0: 1.667, 1: 1.667, 2: 6.667, 3: 6.667, 4: 1.667, 5: 1.667}
245
- for b in b_answer:
246
- b_answer[b] /= 2
247
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
248
- for n in sorted(G):
249
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
250
-
251
- def test_disconnected_path(self):
252
- """Betweenness centrality: disconnected path"""
253
- G = nx.Graph()
254
- nx.add_path(G, [0, 1, 2])
255
- nx.add_path(G, [3, 4, 5, 6])
256
- b_answer = {0: 0, 1: 1, 2: 0, 3: 0, 4: 2, 5: 2, 6: 0}
257
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
258
- for n in sorted(G):
259
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
260
-
261
- def test_disconnected_path_endpoints(self):
262
- """Betweenness centrality: disconnected path endpoints"""
263
- G = nx.Graph()
264
- nx.add_path(G, [0, 1, 2])
265
- nx.add_path(G, [3, 4, 5, 6])
266
- b_answer = {0: 2, 1: 3, 2: 2, 3: 3, 4: 5, 5: 5, 6: 3}
267
- b = nx.betweenness_centrality(G, weight=None, normalized=False, endpoints=True)
268
- for n in sorted(G):
269
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
270
- # normalized = True case
271
- b = nx.betweenness_centrality(G, weight=None, normalized=True, endpoints=True)
272
- for n in sorted(G):
273
- assert b[n] == pytest.approx(b_answer[n] / 21, abs=1e-7)
274
-
275
- def test_directed_path(self):
276
- """Betweenness centrality: directed path"""
277
- G = nx.DiGraph()
278
- nx.add_path(G, [0, 1, 2])
279
- b = nx.betweenness_centrality(G, weight=None, normalized=False)
280
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
281
- for n in sorted(G):
282
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
283
-
284
- def test_directed_path_normalized(self):
285
- """Betweenness centrality: directed path normalized"""
286
- G = nx.DiGraph()
287
- nx.add_path(G, [0, 1, 2])
288
- b = nx.betweenness_centrality(G, weight=None, normalized=True)
289
- b_answer = {0: 0.0, 1: 0.5, 2: 0.0}
290
- for n in sorted(G):
291
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
292
-
293
- @pytest.mark.parametrize(
294
- ("normalized", "endpoints", "is_directed", "k", "expected"),
295
- [
296
- (True, True, True, None, {0: 1.0, 1: 0.4, 2: 0.4, 3: 0.4, 4: 0.4}),
297
- (True, True, True, 1, {0: 1.0, 1: 1.0, 2: 0.25, 3: 0.25, 4: 0.25}),
298
- (True, True, False, None, {0: 1.0, 1: 0.4, 2: 0.4, 3: 0.4, 4: 0.4}),
299
- (True, True, False, 1, {0: 1.0, 1: 1.0, 2: 0.25, 3: 0.25, 4: 0.25}),
300
- (True, False, True, None, {0: 1.0, 1: 0, 2: 0.0, 3: 0.0, 4: 0.0}),
301
- (True, False, True, 1, {0: 1.0, 1: math.nan, 2: 0.0, 3: 0.0, 4: 0.0}),
302
- (True, False, False, None, {0: 1.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}),
303
- (True, False, False, 1, {0: 1.0, 1: math.nan, 2: 0.0, 3: 0.0, 4: 0.0}),
304
- (False, True, True, None, {0: 20.0, 1: 8.0, 2: 8.0, 3: 8.0, 4: 8.0}),
305
- (False, True, True, 1, {0: 20.0, 1: 20.0, 2: 5.0, 3: 5.0, 4: 5.0}),
306
- (False, True, False, None, {0: 10.0, 1: 4.0, 2: 4.0, 3: 4.0, 4: 4.0}),
307
- (False, True, False, 1, {0: 10.0, 1: 10.0, 2: 2.5, 3: 2.5, 4: 2.5}),
308
- (False, False, True, None, {0: 12.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}),
309
- (False, False, True, 1, {0: 12.0, 1: math.nan, 2: 0.0, 3: 0.0, 4: 0.0}),
310
- (False, False, False, None, {0: 6.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}),
311
- (False, False, False, 1, {0: 6.0, 1: math.nan, 2: 0.0, 3: 0.0, 4: 0.0}),
312
- ],
313
- )
314
- def test_scale_with_k_on_star_graph(
315
- self, normalized, endpoints, is_directed, k, expected
316
- ):
317
- # seed=1 selects node 1 as the initial node when using k=1.
318
- # Recall node 0 is the center of the star graph.
319
- G = nx.star_graph(4)
320
- if is_directed:
321
- G = G.to_directed()
322
- b = nx.betweenness_centrality(
323
- G, k=k, seed=1, endpoints=endpoints, normalized=normalized
324
- )
325
- assert b == pytest.approx(expected, nan_ok=True)
326
-
327
- @pytest.mark.parametrize(
328
- ("normalized", "endpoints", "is_directed", "k", "expected"),
329
- [
330
- (
331
- *(True, True, True, None), # Use *() splatting for better autoformat
332
- {0: 14 / 20, 1: 14 / 20, 2: 14 / 20, 3: 14 / 20, 4: 14 / 20},
333
- ),
334
- (
335
- *(True, True, True, 3),
336
- {0: 9 / 12, 1: 11 / 12, 2: 9 / 12, 3: 6 / 12, 4: 7 / 12},
337
- ),
338
- (
339
- *(True, True, False, None),
340
- {0: 10 / 20, 1: 10 / 20, 2: 10 / 20, 3: 10 / 20, 4: 10 / 20},
341
- ),
342
- (
343
- *(True, True, False, 3),
344
- {0: 8 / 12, 1: 7 / 12, 2: 4 / 12, 3: 4 / 12, 4: 7 / 12},
345
- ),
346
- (
347
- *(True, False, True, None),
348
- {0: 6 / 12, 1: 6 / 12, 2: 6 / 12, 3: 6 / 12, 4: 6 / 12},
349
- ),
350
- (
351
- *(True, False, True, 3),
352
- # Use 6 instead of 9 for denominator for source nodes 0, 1, and 4
353
- {0: 3 / 6, 1: 5 / 6, 2: 6 / 9, 3: 3 / 9, 4: 1 / 6},
354
- ),
355
- (
356
- *(True, False, False, None),
357
- {0: 2 / 12, 1: 2 / 12, 2: 2 / 12, 3: 2 / 12, 4: 2 / 12},
358
- ),
359
- (
360
- *(True, False, False, 3),
361
- # Use 6 instead of 9 for denominator for source nodes 0, 1, and 4
362
- {0: 2 / 6, 1: 1 / 6, 2: 1 / 9, 3: 1 / 9, 4: 1 / 6},
363
- ),
364
- (False, True, True, None, {0: 14, 1: 14, 2: 14, 3: 14, 4: 14}),
365
- (
366
- *(False, True, True, 3),
367
- {0: 9 * 5 / 3, 1: 11 * 5 / 3, 2: 9 * 5 / 3, 3: 6 * 5 / 3, 4: 7 * 5 / 3},
368
- ),
369
- (False, True, False, None, {0: 5, 1: 5, 2: 5, 3: 5, 4: 5}),
370
- (
371
- *(False, True, False, 3),
372
- {0: 8 * 5 / 6, 1: 7 * 5 / 6, 2: 4 * 5 / 6, 3: 4 * 5 / 6, 4: 7 * 5 / 6},
373
- ),
374
- (False, False, True, None, {0: 6, 1: 6, 2: 6, 3: 6, 4: 6}),
375
- (
376
- *(False, False, True, 3),
377
- # Use 2 instead of 3 for denominator for source nodes 0, 1, and 4
378
- {0: 3 * 4 / 2, 1: 5 * 4 / 2, 2: 6 * 4 / 3, 3: 3 * 4 / 3, 4: 1 * 4 / 2},
379
- ),
380
- (False, False, False, None, {0: 1, 1: 1, 2: 1, 3: 1, 4: 1}),
381
- (
382
- *(False, False, False, 3),
383
- # Use 4 instead of 6 for denominator for source nodes 0, 1, and 4
384
- {0: 2 * 4 / 4, 1: 1 * 4 / 4, 2: 1 * 4 / 6, 3: 1 * 4 / 6, 4: 1 * 4 / 4},
385
- ),
386
- ],
387
- )
388
- def test_scale_with_k_on_cycle_graph(
389
- self, normalized, endpoints, is_directed, k, expected
390
- ):
391
- # seed=1 selects nodes 0, 1, and 4 as the initial nodes when using k=3.
392
- G = nx.cycle_graph(5, create_using=nx.DiGraph if is_directed else nx.Graph)
393
- b = nx.betweenness_centrality(
394
- G, k=k, seed=1, endpoints=endpoints, normalized=normalized
395
- )
396
- assert b == pytest.approx(expected)
397
-
398
- def test_k_out_of_bounds_raises(self):
399
- G = nx.cycle_graph(4)
400
- with pytest.raises(ValueError, match="larger"):
401
- nx.betweenness_centrality(G, k=5)
402
- with pytest.raises(ValueError, match="negative"):
403
- nx.betweenness_centrality(G, k=-1)
404
- with pytest.raises(ZeroDivisionError):
405
- nx.betweenness_centrality(G, k=0)
406
- with pytest.raises(ZeroDivisionError):
407
- nx.betweenness_centrality(G, k=0, normalized=False)
408
- # Test edge case: use full population when k == len(G)
409
- # Should we warn or raise instead?
410
- b1 = nx.betweenness_centrality(G, k=4, endpoints=False)
411
- b2 = nx.betweenness_centrality(G, endpoints=False)
412
- assert b1 == b2
413
-
414
-
415
- class TestWeightedBetweennessCentrality:
416
- def test_K5(self):
417
- """Weighted betweenness centrality: K5"""
418
- G = nx.complete_graph(5)
419
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
420
- b_answer = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0}
421
- for n in sorted(G):
422
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
423
-
424
- def test_P3_normalized(self):
425
- """Weighted betweenness centrality: P3 normalized"""
426
- G = nx.path_graph(3)
427
- b = nx.betweenness_centrality(G, weight="weight", normalized=True)
428
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
429
- for n in sorted(G):
430
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
431
-
432
- def test_P3(self):
433
- """Weighted betweenness centrality: P3"""
434
- G = nx.path_graph(3)
435
- b_answer = {0: 0.0, 1: 1.0, 2: 0.0}
436
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
437
- for n in sorted(G):
438
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
439
-
440
- def test_krackhardt_kite_graph(self):
441
- """Weighted betweenness centrality: Krackhardt kite graph"""
442
- G = nx.krackhardt_kite_graph()
443
- b_answer = {
444
- 0: 1.667,
445
- 1: 1.667,
446
- 2: 0.000,
447
- 3: 7.333,
448
- 4: 0.000,
449
- 5: 16.667,
450
- 6: 16.667,
451
- 7: 28.000,
452
- 8: 16.000,
453
- 9: 0.000,
454
- }
455
- for b in b_answer:
456
- b_answer[b] /= 2
457
-
458
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
459
-
460
- for n in sorted(G):
461
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
462
-
463
- def test_krackhardt_kite_graph_normalized(self):
464
- """Weighted betweenness centrality:
465
- Krackhardt kite graph normalized
466
- """
467
- G = nx.krackhardt_kite_graph()
468
- b_answer = {
469
- 0: 0.023,
470
- 1: 0.023,
471
- 2: 0.000,
472
- 3: 0.102,
473
- 4: 0.000,
474
- 5: 0.231,
475
- 6: 0.231,
476
- 7: 0.389,
477
- 8: 0.222,
478
- 9: 0.000,
479
- }
480
- b = nx.betweenness_centrality(G, weight="weight", normalized=True)
481
-
482
- for n in sorted(G):
483
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
484
-
485
- def test_florentine_families_graph(self):
486
- """Weighted betweenness centrality:
487
- Florentine families graph"""
488
- G = nx.florentine_families_graph()
489
- b_answer = {
490
- "Acciaiuoli": 0.000,
491
- "Albizzi": 0.212,
492
- "Barbadori": 0.093,
493
- "Bischeri": 0.104,
494
- "Castellani": 0.055,
495
- "Ginori": 0.000,
496
- "Guadagni": 0.255,
497
- "Lamberteschi": 0.000,
498
- "Medici": 0.522,
499
- "Pazzi": 0.000,
500
- "Peruzzi": 0.022,
501
- "Ridolfi": 0.114,
502
- "Salviati": 0.143,
503
- "Strozzi": 0.103,
504
- "Tornabuoni": 0.092,
505
- }
506
-
507
- b = nx.betweenness_centrality(G, weight="weight", normalized=True)
508
- for n in sorted(G):
509
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
510
-
511
- def test_les_miserables_graph(self):
512
- """Weighted betweenness centrality: Les Miserables graph"""
513
- G = nx.les_miserables_graph()
514
- b_answer = {
515
- "Napoleon": 0.000,
516
- "Myriel": 0.177,
517
- "MlleBaptistine": 0.000,
518
- "MmeMagloire": 0.000,
519
- "CountessDeLo": 0.000,
520
- "Geborand": 0.000,
521
- "Champtercier": 0.000,
522
- "Cravatte": 0.000,
523
- "Count": 0.000,
524
- "OldMan": 0.000,
525
- "Valjean": 0.454,
526
- "Labarre": 0.000,
527
- "Marguerite": 0.009,
528
- "MmeDeR": 0.000,
529
- "Isabeau": 0.000,
530
- "Gervais": 0.000,
531
- "Listolier": 0.000,
532
- "Tholomyes": 0.066,
533
- "Fameuil": 0.000,
534
- "Blacheville": 0.000,
535
- "Favourite": 0.000,
536
- "Dahlia": 0.000,
537
- "Zephine": 0.000,
538
- "Fantine": 0.114,
539
- "MmeThenardier": 0.046,
540
- "Thenardier": 0.129,
541
- "Cosette": 0.075,
542
- "Javert": 0.193,
543
- "Fauchelevent": 0.026,
544
- "Bamatabois": 0.080,
545
- "Perpetue": 0.000,
546
- "Simplice": 0.001,
547
- "Scaufflaire": 0.000,
548
- "Woman1": 0.000,
549
- "Judge": 0.000,
550
- "Champmathieu": 0.000,
551
- "Brevet": 0.000,
552
- "Chenildieu": 0.000,
553
- "Cochepaille": 0.000,
554
- "Pontmercy": 0.023,
555
- "Boulatruelle": 0.000,
556
- "Eponine": 0.023,
557
- "Anzelma": 0.000,
558
- "Woman2": 0.000,
559
- "MotherInnocent": 0.000,
560
- "Gribier": 0.000,
561
- "MmeBurgon": 0.026,
562
- "Jondrette": 0.000,
563
- "Gavroche": 0.285,
564
- "Gillenormand": 0.024,
565
- "Magnon": 0.005,
566
- "MlleGillenormand": 0.036,
567
- "MmePontmercy": 0.005,
568
- "MlleVaubois": 0.000,
569
- "LtGillenormand": 0.015,
570
- "Marius": 0.072,
571
- "BaronessT": 0.004,
572
- "Mabeuf": 0.089,
573
- "Enjolras": 0.003,
574
- "Combeferre": 0.000,
575
- "Prouvaire": 0.000,
576
- "Feuilly": 0.004,
577
- "Courfeyrac": 0.001,
578
- "Bahorel": 0.007,
579
- "Bossuet": 0.028,
580
- "Joly": 0.000,
581
- "Grantaire": 0.036,
582
- "MotherPlutarch": 0.000,
583
- "Gueulemer": 0.025,
584
- "Babet": 0.015,
585
- "Claquesous": 0.042,
586
- "Montparnasse": 0.050,
587
- "Toussaint": 0.011,
588
- "Child1": 0.000,
589
- "Child2": 0.000,
590
- "Brujon": 0.002,
591
- "MmeHucheloup": 0.034,
592
- }
593
-
594
- b = nx.betweenness_centrality(G, weight="weight", normalized=True)
595
- for n in sorted(G):
596
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
597
-
598
- def test_ladder_graph(self):
599
- """Weighted betweenness centrality: Ladder graph"""
600
- G = nx.Graph() # ladder_graph(3)
601
- G.add_edges_from([(0, 1), (0, 2), (1, 3), (2, 3), (2, 4), (4, 5), (3, 5)])
602
- b_answer = {0: 1.667, 1: 1.667, 2: 6.667, 3: 6.667, 4: 1.667, 5: 1.667}
603
- for b in b_answer:
604
- b_answer[b] /= 2
605
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
606
- for n in sorted(G):
607
- assert b[n] == pytest.approx(b_answer[n], abs=1e-3)
608
-
609
- def test_G(self):
610
- """Weighted betweenness centrality: G"""
611
- G = weighted_G()
612
- b_answer = {0: 2.0, 1: 0.0, 2: 4.0, 3: 3.0, 4: 4.0, 5: 0.0}
613
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
614
- for n in sorted(G):
615
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
616
-
617
- def test_G2(self):
618
- """Weighted betweenness centrality: G2"""
619
- G = nx.DiGraph()
620
- G.add_weighted_edges_from(
621
- [
622
- ("s", "u", 10),
623
- ("s", "x", 5),
624
- ("u", "v", 1),
625
- ("u", "x", 2),
626
- ("v", "y", 1),
627
- ("x", "u", 3),
628
- ("x", "v", 5),
629
- ("x", "y", 2),
630
- ("y", "s", 7),
631
- ("y", "v", 6),
632
- ]
633
- )
634
-
635
- b_answer = {"y": 5.0, "x": 5.0, "s": 4.0, "u": 2.0, "v": 2.0}
636
-
637
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
638
- for n in sorted(G):
639
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
640
-
641
- def test_G3(self):
642
- """Weighted betweenness centrality: G3"""
643
- G = nx.MultiGraph(weighted_G())
644
- es = list(G.edges(data=True))[::2] # duplicate every other edge
645
- G.add_edges_from(es)
646
- b_answer = {0: 2.0, 1: 0.0, 2: 4.0, 3: 3.0, 4: 4.0, 5: 0.0}
647
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
648
- for n in sorted(G):
649
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
650
-
651
- def test_G4(self):
652
- """Weighted betweenness centrality: G4"""
653
- G = nx.MultiDiGraph()
654
- G.add_weighted_edges_from(
655
- [
656
- ("s", "u", 10),
657
- ("s", "x", 5),
658
- ("s", "x", 6),
659
- ("u", "v", 1),
660
- ("u", "x", 2),
661
- ("v", "y", 1),
662
- ("v", "y", 1),
663
- ("x", "u", 3),
664
- ("x", "v", 5),
665
- ("x", "y", 2),
666
- ("x", "y", 3),
667
- ("y", "s", 7),
668
- ("y", "v", 6),
669
- ("y", "v", 6),
670
- ]
671
- )
672
-
673
- b_answer = {"y": 5.0, "x": 5.0, "s": 4.0, "u": 2.0, "v": 2.0}
674
-
675
- b = nx.betweenness_centrality(G, weight="weight", normalized=False)
676
- for n in sorted(G):
677
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
678
-
679
-
680
- class TestEdgeBetweennessCentrality:
681
- def test_K5(self):
682
- """Edge betweenness centrality: K5"""
683
- G = nx.complete_graph(5)
684
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
685
- b_answer = dict.fromkeys(G.edges(), 1)
686
- for n in sorted(G.edges()):
687
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
688
-
689
- def test_normalized_K5(self):
690
- """Edge betweenness centrality: K5"""
691
- G = nx.complete_graph(5)
692
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
693
- b_answer = dict.fromkeys(G.edges(), 1 / 10)
694
- for n in sorted(G.edges()):
695
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
696
-
697
- def test_C4(self):
698
- """Edge betweenness centrality: C4"""
699
- G = nx.cycle_graph(4)
700
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
701
- b_answer = {(0, 1): 2, (0, 3): 2, (1, 2): 2, (2, 3): 2}
702
- for n in sorted(G.edges()):
703
- assert b[n] == pytest.approx(b_answer[n] / 6, abs=1e-7)
704
-
705
- def test_P4(self):
706
- """Edge betweenness centrality: P4"""
707
- G = nx.path_graph(4)
708
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
709
- b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
710
- for n in sorted(G.edges()):
711
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
712
-
713
- def test_normalized_P4(self):
714
- """Edge betweenness centrality: P4"""
715
- G = nx.path_graph(4)
716
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=True)
717
- b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
718
- for n in sorted(G.edges()):
719
- assert b[n] == pytest.approx(b_answer[n] / 6, abs=1e-7)
720
-
721
- def test_balanced_tree(self):
722
- """Edge betweenness centrality: balanced tree"""
723
- G = nx.balanced_tree(r=2, h=2)
724
- b = nx.edge_betweenness_centrality(G, weight=None, normalized=False)
725
- b_answer = {(0, 1): 12, (0, 2): 12, (1, 3): 6, (1, 4): 6, (2, 5): 6, (2, 6): 6}
726
- for n in sorted(G.edges()):
727
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
728
-
729
- def test_edge_betweenness_k(self):
730
- """Ensure setting `k` properly limits the number of source nodes."""
731
- G = nx.path_graph(3)
732
- # This choice of `k` and `seed` selects nodes 0 and 2.
733
- # There is only one shortest path between any two pairs of nodes.
734
- # With source nodes 0 and 2, this means that both edges are part of
735
- # three shortest paths:
736
- # For (0, 1): sp(0, 1), sp(0, 2), sp(2, 0).
737
- # For (1, 2): sp(0, 2), sp(2, 0), sp(2, 1).
738
- # We normalize by 2 because the graph is undirected, and by
739
- # `k / n = 2 / 3` because we are only considering a subset of source
740
- # nodes.
741
- # This means the final eb centralities should be 3 / 2 / (2 / 3) = 9 / 4.
742
- eb = nx.edge_betweenness_centrality(G, k=2, seed=42, normalized=False)
743
- assert eb == {(0, 1): 9 / 4, (1, 2): 9 / 4}
744
- # When normalization is `True`, we instead divide by the number of total
745
- # `(s, t)` pairs, i.e. `k * (n - 1) = 4`, meaning we get an eb of `3 / 4`.
746
- eb = nx.edge_betweenness_centrality(G, k=2, seed=42, normalized=True)
747
- assert eb == {(0, 1): 3 / 4, (1, 2): 3 / 4}
748
-
749
-
750
- class TestWeightedEdgeBetweennessCentrality:
751
- def test_K5(self):
752
- """Edge betweenness centrality: K5"""
753
- G = nx.complete_graph(5)
754
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
755
- b_answer = dict.fromkeys(G.edges(), 1)
756
- for n in sorted(G.edges()):
757
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
758
-
759
- def test_C4(self):
760
- """Edge betweenness centrality: C4"""
761
- G = nx.cycle_graph(4)
762
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
763
- b_answer = {(0, 1): 2, (0, 3): 2, (1, 2): 2, (2, 3): 2}
764
- for n in sorted(G.edges()):
765
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
766
-
767
- def test_P4(self):
768
- """Edge betweenness centrality: P4"""
769
- G = nx.path_graph(4)
770
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
771
- b_answer = {(0, 1): 3, (1, 2): 4, (2, 3): 3}
772
- for n in sorted(G.edges()):
773
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
774
-
775
- def test_balanced_tree(self):
776
- """Edge betweenness centrality: balanced tree"""
777
- G = nx.balanced_tree(r=2, h=2)
778
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
779
- b_answer = {(0, 1): 12, (0, 2): 12, (1, 3): 6, (1, 4): 6, (2, 5): 6, (2, 6): 6}
780
- for n in sorted(G.edges()):
781
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
782
-
783
- def test_weighted_graph(self):
784
- """Edge betweenness centrality: weighted"""
785
- eList = [
786
- (0, 1, 5),
787
- (0, 2, 4),
788
- (0, 3, 3),
789
- (0, 4, 2),
790
- (1, 2, 4),
791
- (1, 3, 1),
792
- (1, 4, 3),
793
- (2, 4, 5),
794
- (3, 4, 4),
795
- ]
796
- G = nx.Graph()
797
- G.add_weighted_edges_from(eList)
798
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
799
- b_answer = {
800
- (0, 1): 0.0,
801
- (0, 2): 1.0,
802
- (0, 3): 2.0,
803
- (0, 4): 1.0,
804
- (1, 2): 2.0,
805
- (1, 3): 3.5,
806
- (1, 4): 1.5,
807
- (2, 4): 1.0,
808
- (3, 4): 0.5,
809
- }
810
- for n in sorted(G.edges()):
811
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
812
-
813
- def test_normalized_weighted_graph(self):
814
- """Edge betweenness centrality: normalized weighted"""
815
- eList = [
816
- (0, 1, 5),
817
- (0, 2, 4),
818
- (0, 3, 3),
819
- (0, 4, 2),
820
- (1, 2, 4),
821
- (1, 3, 1),
822
- (1, 4, 3),
823
- (2, 4, 5),
824
- (3, 4, 4),
825
- ]
826
- G = nx.Graph()
827
- G.add_weighted_edges_from(eList)
828
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=True)
829
- b_answer = {
830
- (0, 1): 0.0,
831
- (0, 2): 1.0,
832
- (0, 3): 2.0,
833
- (0, 4): 1.0,
834
- (1, 2): 2.0,
835
- (1, 3): 3.5,
836
- (1, 4): 1.5,
837
- (2, 4): 1.0,
838
- (3, 4): 0.5,
839
- }
840
- norm = len(G) * (len(G) - 1) / 2
841
- for n in sorted(G.edges()):
842
- assert b[n] == pytest.approx(b_answer[n] / norm, abs=1e-7)
843
-
844
- def test_weighted_multigraph(self):
845
- """Edge betweenness centrality: weighted multigraph"""
846
- eList = [
847
- (0, 1, 5),
848
- (0, 1, 4),
849
- (0, 2, 4),
850
- (0, 3, 3),
851
- (0, 3, 3),
852
- (0, 4, 2),
853
- (1, 2, 4),
854
- (1, 3, 1),
855
- (1, 3, 2),
856
- (1, 4, 3),
857
- (1, 4, 4),
858
- (2, 4, 5),
859
- (3, 4, 4),
860
- (3, 4, 4),
861
- ]
862
- G = nx.MultiGraph()
863
- G.add_weighted_edges_from(eList)
864
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=False)
865
- b_answer = {
866
- (0, 1, 0): 0.0,
867
- (0, 1, 1): 0.5,
868
- (0, 2, 0): 1.0,
869
- (0, 3, 0): 0.75,
870
- (0, 3, 1): 0.75,
871
- (0, 4, 0): 1.0,
872
- (1, 2, 0): 2.0,
873
- (1, 3, 0): 3.0,
874
- (1, 3, 1): 0.0,
875
- (1, 4, 0): 1.5,
876
- (1, 4, 1): 0.0,
877
- (2, 4, 0): 1.0,
878
- (3, 4, 0): 0.25,
879
- (3, 4, 1): 0.25,
880
- }
881
- for n in sorted(G.edges(keys=True)):
882
- assert b[n] == pytest.approx(b_answer[n], abs=1e-7)
883
-
884
- def test_normalized_weighted_multigraph(self):
885
- """Edge betweenness centrality: normalized weighted multigraph"""
886
- eList = [
887
- (0, 1, 5),
888
- (0, 1, 4),
889
- (0, 2, 4),
890
- (0, 3, 3),
891
- (0, 3, 3),
892
- (0, 4, 2),
893
- (1, 2, 4),
894
- (1, 3, 1),
895
- (1, 3, 2),
896
- (1, 4, 3),
897
- (1, 4, 4),
898
- (2, 4, 5),
899
- (3, 4, 4),
900
- (3, 4, 4),
901
- ]
902
- G = nx.MultiGraph()
903
- G.add_weighted_edges_from(eList)
904
- b = nx.edge_betweenness_centrality(G, weight="weight", normalized=True)
905
- b_answer = {
906
- (0, 1, 0): 0.0,
907
- (0, 1, 1): 0.5,
908
- (0, 2, 0): 1.0,
909
- (0, 3, 0): 0.75,
910
- (0, 3, 1): 0.75,
911
- (0, 4, 0): 1.0,
912
- (1, 2, 0): 2.0,
913
- (1, 3, 0): 3.0,
914
- (1, 3, 1): 0.0,
915
- (1, 4, 0): 1.5,
916
- (1, 4, 1): 0.0,
917
- (2, 4, 0): 1.0,
918
- (3, 4, 0): 0.25,
919
- (3, 4, 1): 0.25,
920
- }
921
- norm = len(G) * (len(G) - 1) / 2
922
- for n in sorted(G.edges(keys=True)):
923
- assert b[n] == pytest.approx(b_answer[n] / norm, abs=1e-7)