okstra 0.130.4 → 0.131.1
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.
- package/README.md +0 -1
- package/docs/architecture.md +2 -2
- package/docs/cli.md +1 -1
- package/docs/for-ai/README.md +0 -2
- package/docs/for-ai/skills/okstra-run.md +13 -2
- package/docs/for-ai/skills/okstra-setup.md +4 -1
- package/docs/project-structure-overview.md +5 -4
- package/docs/task-process/implementation-planning.md +13 -0
- package/docs/task-process/implementation.md +17 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/report-writer-worker.md +7 -0
- package/runtime/bin/lib/okstra/usage.sh +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/plan-body-verification.md +26 -5
- package/runtime/prompts/lead/report-writer.md +6 -2
- package/runtime/prompts/profiles/_common-contract.md +2 -1
- package/runtime/prompts/profiles/_implementation-deliverable.md +6 -1
- package/runtime/prompts/profiles/_implementation-executor.md +2 -2
- package/runtime/prompts/profiles/_implementation-verifier.md +33 -10
- package/runtime/prompts/profiles/final-verification.md +21 -6
- package/runtime/prompts/profiles/implementation-planning.md +16 -4
- package/runtime/python/okstra_ctl/codex_dispatch.py +31 -0
- package/runtime/python/okstra_ctl/conformance.py +49 -11
- package/runtime/python/okstra_ctl/report_finalize.py +52 -1
- package/runtime/python/okstra_ctl/run.py +15 -3
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +14 -6
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +19 -1
- package/runtime/python/okstra_vendor/__init__.py +0 -44
- package/runtime/schemas/final-report-v1.0.schema.json +99 -5
- package/runtime/skills/okstra-run/SKILL.md +11 -4
- package/runtime/skills/okstra-setup/SKILL.md +3 -2
- package/runtime/skills/okstra-setup/references/project-config.md +16 -7
- package/runtime/templates/reports/final-report.template.md +15 -9
- package/runtime/templates/reports/i18n/en.json +1 -0
- package/runtime/templates/reports/i18n/ko.json +1 -0
- package/runtime/validators/lib/fixtures.sh +6 -0
- package/runtime/validators/validate-run.py +2019 -96
- package/src/cli-registry.mjs +0 -7
- package/src/commands/lifecycle/doctor.mjs +0 -9
- package/src/lib/skill-catalog.mjs +0 -1
- package/docs/for-ai/skills/okstra-graphify.md +0 -64
- package/runtime/python/okstra_ctl/graphify_cmd.py +0 -225
- package/runtime/python/okstra_vendor/graphify/.vendored-version +0 -1
- package/runtime/python/okstra_vendor/graphify/__init__.py +0 -28
- package/runtime/python/okstra_vendor/graphify/__main__.py +0 -1371
- package/runtime/python/okstra_vendor/graphify/analyze.py +0 -540
- package/runtime/python/okstra_vendor/graphify/benchmark.py +0 -129
- package/runtime/python/okstra_vendor/graphify/build.py +0 -107
- package/runtime/python/okstra_vendor/graphify/cache.py +0 -169
- package/runtime/python/okstra_vendor/graphify/cluster.py +0 -137
- package/runtime/python/okstra_vendor/graphify/detect.py +0 -510
- package/runtime/python/okstra_vendor/graphify/export.py +0 -1014
- package/runtime/python/okstra_vendor/graphify/extract.py +0 -3277
- package/runtime/python/okstra_vendor/graphify/hooks.py +0 -220
- package/runtime/python/okstra_vendor/graphify/ingest.py +0 -297
- package/runtime/python/okstra_vendor/graphify/manifest.py +0 -4
- package/runtime/python/okstra_vendor/graphify/report.py +0 -175
- package/runtime/python/okstra_vendor/graphify/security.py +0 -203
- package/runtime/python/okstra_vendor/graphify/serve.py +0 -373
- package/runtime/python/okstra_vendor/graphify/skill-aider.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-claw.md +0 -1184
- package/runtime/python/okstra_vendor/graphify/skill-codex.md +0 -1242
- package/runtime/python/okstra_vendor/graphify/skill-copilot.md +0 -1268
- package/runtime/python/okstra_vendor/graphify/skill-droid.md +0 -1239
- package/runtime/python/okstra_vendor/graphify/skill-kiro.md +0 -1183
- package/runtime/python/okstra_vendor/graphify/skill-opencode.md +0 -1238
- package/runtime/python/okstra_vendor/graphify/skill-trae.md +0 -1208
- package/runtime/python/okstra_vendor/graphify/skill-vscode.md +0 -253
- package/runtime/python/okstra_vendor/graphify/skill-windows.md +0 -1245
- package/runtime/python/okstra_vendor/graphify/skill.md +0 -1319
- package/runtime/python/okstra_vendor/graphify/transcribe.py +0 -182
- package/runtime/python/okstra_vendor/graphify/validate.py +0 -72
- package/runtime/python/okstra_vendor/graphify/watch.py +0 -188
- package/runtime/python/okstra_vendor/graphify/wiki.py +0 -214
- package/runtime/python/okstra_vendor/networkx/__init__.py +0 -62
- package/runtime/python/okstra_vendor/networkx/algorithms/__init__.py +0 -134
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/__init__.py +0 -26
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clique.py +0 -259
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/clustering_coefficient.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/connectivity.py +0 -412
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/density.py +0 -396
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/distance_measures.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/dominating_set.py +0 -149
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/kcomponents.py +0 -369
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/matching.py +0 -44
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/maxcut.py +0 -143
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/ramsey.py +0 -53
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/steinertree.py +0 -265
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/traveling_salesman.py +0 -1508
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/treewidth.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/approximation/vertex_cover.py +0 -83
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/connectivity.py +0 -122
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/correlation.py +0 -302
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/mixing.py +0 -255
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/neighbor_degree.py +0 -160
- package/runtime/python/okstra_vendor/networkx/algorithms/assortativity/pairs.py +0 -127
- package/runtime/python/okstra_vendor/networkx/algorithms/asteroidal.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/__init__.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/basic.py +0 -322
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/centrality.py +0 -290
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/cluster.py +0 -289
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/covering.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/edgelist.py +0 -360
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/extendability.py +0 -105
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/generators.py +0 -603
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/link_analysis.py +0 -316
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matching.py +0 -590
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/matrix.py +0 -232
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/projection.py +0 -526
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/redundancy.py +0 -112
- package/runtime/python/okstra_vendor/networkx/algorithms/bipartite/spectral.py +0 -69
- package/runtime/python/okstra_vendor/networkx/algorithms/boundary.py +0 -168
- package/runtime/python/okstra_vendor/networkx/algorithms/bridges.py +0 -205
- package/runtime/python/okstra_vendor/networkx/algorithms/broadcasting.py +0 -164
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/__init__.py +0 -20
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness.py +0 -591
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/betweenness_subset.py +0 -236
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/closeness.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness.py +0 -364
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_betweenness_subset.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/current_flow_closeness.py +0 -96
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/degree_alg.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/dispersion.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/eigenvector.py +0 -357
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/flow_matrix.py +0 -130
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/group.py +0 -787
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/harmonic.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/katz.py +0 -331
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/laplacian.py +0 -150
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/load.py +0 -200
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/percolation.py +0 -128
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/reaching.py +0 -209
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/second_order.py +0 -141
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/subgraph_alg.py +0 -361
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/trophic.py +0 -181
- package/runtime/python/okstra_vendor/networkx/algorithms/centrality/voterank_alg.py +0 -95
- package/runtime/python/okstra_vendor/networkx/algorithms/chains.py +0 -172
- package/runtime/python/okstra_vendor/networkx/algorithms/chordal.py +0 -443
- package/runtime/python/okstra_vendor/networkx/algorithms/clique.py +0 -818
- package/runtime/python/okstra_vendor/networkx/algorithms/cluster.py +0 -732
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/equitable_coloring.py +0 -505
- package/runtime/python/okstra_vendor/networkx/algorithms/coloring/greedy_coloring.py +0 -565
- package/runtime/python/okstra_vendor/networkx/algorithms/communicability_alg.py +0 -163
- package/runtime/python/okstra_vendor/networkx/algorithms/community/__init__.py +0 -28
- package/runtime/python/okstra_vendor/networkx/algorithms/community/asyn_fluid.py +0 -153
- package/runtime/python/okstra_vendor/networkx/algorithms/community/bipartitions.py +0 -354
- package/runtime/python/okstra_vendor/networkx/algorithms/community/centrality.py +0 -171
- package/runtime/python/okstra_vendor/networkx/algorithms/community/community_utils.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/community/divisive.py +0 -216
- package/runtime/python/okstra_vendor/networkx/algorithms/community/kclique.py +0 -79
- package/runtime/python/okstra_vendor/networkx/algorithms/community/label_propagation.py +0 -338
- package/runtime/python/okstra_vendor/networkx/algorithms/community/leiden.py +0 -162
- package/runtime/python/okstra_vendor/networkx/algorithms/community/local.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/community/louvain.py +0 -384
- package/runtime/python/okstra_vendor/networkx/algorithms/community/lukes.py +0 -227
- package/runtime/python/okstra_vendor/networkx/algorithms/community/modularity_max.py +0 -452
- package/runtime/python/okstra_vendor/networkx/algorithms/community/quality.py +0 -347
- package/runtime/python/okstra_vendor/networkx/algorithms/components/__init__.py +0 -6
- package/runtime/python/okstra_vendor/networkx/algorithms/components/attracting.py +0 -115
- package/runtime/python/okstra_vendor/networkx/algorithms/components/biconnected.py +0 -394
- package/runtime/python/okstra_vendor/networkx/algorithms/components/connected.py +0 -282
- package/runtime/python/okstra_vendor/networkx/algorithms/components/semiconnected.py +0 -71
- package/runtime/python/okstra_vendor/networkx/algorithms/components/strongly_connected.py +0 -359
- package/runtime/python/okstra_vendor/networkx/algorithms/components/weakly_connected.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/connectivity.py +0 -811
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/cuts.py +0 -616
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/disjoint_paths.py +0 -408
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_augmentation.py +0 -1270
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/edge_kcomponents.py +0 -592
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcomponents.py +0 -220
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/kcutsets.py +0 -235
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/stoerwagner.py +0 -152
- package/runtime/python/okstra_vendor/networkx/algorithms/connectivity/utils.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/core.py +0 -588
- package/runtime/python/okstra_vendor/networkx/algorithms/covering.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/cuts.py +0 -416
- package/runtime/python/okstra_vendor/networkx/algorithms/cycles.py +0 -1234
- package/runtime/python/okstra_vendor/networkx/algorithms/d_separation.py +0 -677
- package/runtime/python/okstra_vendor/networkx/algorithms/dag.py +0 -1392
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_measures.py +0 -1095
- package/runtime/python/okstra_vendor/networkx/algorithms/distance_regular.py +0 -272
- package/runtime/python/okstra_vendor/networkx/algorithms/dominance.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/dominating.py +0 -268
- package/runtime/python/okstra_vendor/networkx/algorithms/efficiency_measures.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/euler.py +0 -470
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/__init__.py +0 -11
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/boykovkolmogorov.py +0 -370
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/capacityscaling.py +0 -407
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/dinitz_alg.py +0 -238
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/edmondskarp.py +0 -241
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/gomory_hu.py +0 -178
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/maxflow.py +0 -611
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/mincost.py +0 -356
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/networksimplex.py +0 -662
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/preflowpush.py +0 -425
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/shortestaugmentingpath.py +0 -300
- package/runtime/python/okstra_vendor/networkx/algorithms/flow/utils.py +0 -194
- package/runtime/python/okstra_vendor/networkx/algorithms/graph_hashing.py +0 -435
- package/runtime/python/okstra_vendor/networkx/algorithms/graphical.py +0 -483
- package/runtime/python/okstra_vendor/networkx/algorithms/hierarchy.py +0 -57
- package/runtime/python/okstra_vendor/networkx/algorithms/hybrid.py +0 -196
- package/runtime/python/okstra_vendor/networkx/algorithms/isolate.py +0 -107
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/ismags.py +0 -1306
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorph.py +0 -336
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/isomorphvf2.py +0 -1262
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/matchhelpers.py +0 -352
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/temporalisomorphvf2.py +0 -308
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/tree_isomorphism.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2pp.py +0 -1102
- package/runtime/python/okstra_vendor/networkx/algorithms/isomorphism/vf2userfunc.py +0 -192
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/__init__.py +0 -2
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/hits_alg.py +0 -337
- package/runtime/python/okstra_vendor/networkx/algorithms/link_analysis/pagerank_alg.py +0 -498
- package/runtime/python/okstra_vendor/networkx/algorithms/link_prediction.py +0 -687
- package/runtime/python/okstra_vendor/networkx/algorithms/lowest_common_ancestors.py +0 -280
- package/runtime/python/okstra_vendor/networkx/algorithms/matching.py +0 -1148
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/__init__.py +0 -27
- package/runtime/python/okstra_vendor/networkx/algorithms/minors/contraction.py +0 -738
- package/runtime/python/okstra_vendor/networkx/algorithms/mis.py +0 -78
- package/runtime/python/okstra_vendor/networkx/algorithms/moral.py +0 -59
- package/runtime/python/okstra_vendor/networkx/algorithms/node_classification.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/non_randomness.py +0 -155
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/__init__.py +0 -4
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/all.py +0 -324
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/binary.py +0 -468
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/product.py +0 -633
- package/runtime/python/okstra_vendor/networkx/algorithms/operators/unary.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/perfect_graph.py +0 -73
- package/runtime/python/okstra_vendor/networkx/algorithms/planar_drawing.py +0 -464
- package/runtime/python/okstra_vendor/networkx/algorithms/planarity.py +0 -1463
- package/runtime/python/okstra_vendor/networkx/algorithms/polynomials.py +0 -306
- package/runtime/python/okstra_vendor/networkx/algorithms/reciprocity.py +0 -98
- package/runtime/python/okstra_vendor/networkx/algorithms/regular.py +0 -167
- package/runtime/python/okstra_vendor/networkx/algorithms/richclub.py +0 -138
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/astar.py +0 -239
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/dense.py +0 -264
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/generic.py +0 -716
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/unweighted.py +0 -625
- package/runtime/python/okstra_vendor/networkx/algorithms/shortest_paths/weighted.py +0 -2542
- package/runtime/python/okstra_vendor/networkx/algorithms/similarity.py +0 -2107
- package/runtime/python/okstra_vendor/networkx/algorithms/simple_paths.py +0 -966
- package/runtime/python/okstra_vendor/networkx/algorithms/smallworld.py +0 -404
- package/runtime/python/okstra_vendor/networkx/algorithms/smetric.py +0 -30
- package/runtime/python/okstra_vendor/networkx/algorithms/sparsifiers.py +0 -296
- package/runtime/python/okstra_vendor/networkx/algorithms/structuralholes.py +0 -374
- package/runtime/python/okstra_vendor/networkx/algorithms/summarization.py +0 -564
- package/runtime/python/okstra_vendor/networkx/algorithms/swap.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/threshold.py +0 -981
- package/runtime/python/okstra_vendor/networkx/algorithms/time_dependent.py +0 -142
- package/runtime/python/okstra_vendor/networkx/algorithms/tournament.py +0 -406
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/__init__.py +0 -5
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/beamsearch.py +0 -90
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/breadth_first_search.py +0 -576
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/depth_first_search.py +0 -529
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgebfs.py +0 -185
- package/runtime/python/okstra_vendor/networkx/algorithms/traversal/edgedfs.py +0 -182
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/branchings.py +0 -1042
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/coding.py +0 -413
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/decomposition.py +0 -88
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/distance_measures.py +0 -219
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/mst.py +0 -1281
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/operations.py +0 -106
- package/runtime/python/okstra_vendor/networkx/algorithms/tree/recognition.py +0 -273
- package/runtime/python/okstra_vendor/networkx/algorithms/triads.py +0 -500
- package/runtime/python/okstra_vendor/networkx/algorithms/vitality.py +0 -76
- package/runtime/python/okstra_vendor/networkx/algorithms/voronoi.py +0 -86
- package/runtime/python/okstra_vendor/networkx/algorithms/walks.py +0 -77
- package/runtime/python/okstra_vendor/networkx/algorithms/wiener.py +0 -278
- package/runtime/python/okstra_vendor/networkx/classes/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/classes/coreviews.py +0 -435
- package/runtime/python/okstra_vendor/networkx/classes/digraph.py +0 -1363
- package/runtime/python/okstra_vendor/networkx/classes/filters.py +0 -95
- package/runtime/python/okstra_vendor/networkx/classes/function.py +0 -1549
- package/runtime/python/okstra_vendor/networkx/classes/graph.py +0 -2082
- package/runtime/python/okstra_vendor/networkx/classes/graphviews.py +0 -269
- package/runtime/python/okstra_vendor/networkx/classes/multidigraph.py +0 -977
- package/runtime/python/okstra_vendor/networkx/classes/multigraph.py +0 -1294
- package/runtime/python/okstra_vendor/networkx/classes/reportviews.py +0 -1447
- package/runtime/python/okstra_vendor/networkx/convert.py +0 -502
- package/runtime/python/okstra_vendor/networkx/convert_matrix.py +0 -1314
- package/runtime/python/okstra_vendor/networkx/drawing/__init__.py +0 -7
- package/runtime/python/okstra_vendor/networkx/drawing/layout.py +0 -2036
- package/runtime/python/okstra_vendor/networkx/drawing/nx_agraph.py +0 -470
- package/runtime/python/okstra_vendor/networkx/drawing/nx_latex.py +0 -570
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pydot.py +0 -361
- package/runtime/python/okstra_vendor/networkx/drawing/nx_pylab.py +0 -2978
- package/runtime/python/okstra_vendor/networkx/exception.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/__init__.py +0 -34
- package/runtime/python/okstra_vendor/networkx/generators/atlas.dat.gz +0 -0
- package/runtime/python/okstra_vendor/networkx/generators/atlas.py +0 -227
- package/runtime/python/okstra_vendor/networkx/generators/classic.py +0 -1091
- package/runtime/python/okstra_vendor/networkx/generators/cographs.py +0 -68
- package/runtime/python/okstra_vendor/networkx/generators/community.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/degree_seq.py +0 -886
- package/runtime/python/okstra_vendor/networkx/generators/directed.py +0 -572
- package/runtime/python/okstra_vendor/networkx/generators/duplication.py +0 -174
- package/runtime/python/okstra_vendor/networkx/generators/ego.py +0 -66
- package/runtime/python/okstra_vendor/networkx/generators/expanders.py +0 -499
- package/runtime/python/okstra_vendor/networkx/generators/geometric.py +0 -1037
- package/runtime/python/okstra_vendor/networkx/generators/harary_graph.py +0 -163
- package/runtime/python/okstra_vendor/networkx/generators/internet_as_graphs.py +0 -443
- package/runtime/python/okstra_vendor/networkx/generators/intersection.py +0 -125
- package/runtime/python/okstra_vendor/networkx/generators/interval_graph.py +0 -70
- package/runtime/python/okstra_vendor/networkx/generators/joint_degree_seq.py +0 -664
- package/runtime/python/okstra_vendor/networkx/generators/lattice.py +0 -405
- package/runtime/python/okstra_vendor/networkx/generators/line.py +0 -501
- package/runtime/python/okstra_vendor/networkx/generators/mycielski.py +0 -110
- package/runtime/python/okstra_vendor/networkx/generators/nonisomorphic_trees.py +0 -259
- package/runtime/python/okstra_vendor/networkx/generators/random_clustered.py +0 -117
- package/runtime/python/okstra_vendor/networkx/generators/random_graphs.py +0 -1416
- package/runtime/python/okstra_vendor/networkx/generators/small.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/social.py +0 -554
- package/runtime/python/okstra_vendor/networkx/generators/spectral_graph_forge.py +0 -120
- package/runtime/python/okstra_vendor/networkx/generators/stochastic.py +0 -54
- package/runtime/python/okstra_vendor/networkx/generators/sudoku.py +0 -131
- package/runtime/python/okstra_vendor/networkx/generators/time_series.py +0 -74
- package/runtime/python/okstra_vendor/networkx/generators/trees.py +0 -1070
- package/runtime/python/okstra_vendor/networkx/generators/triads.py +0 -94
- package/runtime/python/okstra_vendor/networkx/lazy_imports.py +0 -188
- package/runtime/python/okstra_vendor/networkx/linalg/__init__.py +0 -13
- package/runtime/python/okstra_vendor/networkx/linalg/algebraicconnectivity.py +0 -650
- package/runtime/python/okstra_vendor/networkx/linalg/attrmatrix.py +0 -466
- package/runtime/python/okstra_vendor/networkx/linalg/bethehessianmatrix.py +0 -77
- package/runtime/python/okstra_vendor/networkx/linalg/graphmatrix.py +0 -168
- package/runtime/python/okstra_vendor/networkx/linalg/laplacianmatrix.py +0 -512
- package/runtime/python/okstra_vendor/networkx/linalg/modularitymatrix.py +0 -166
- package/runtime/python/okstra_vendor/networkx/linalg/spectrum.py +0 -186
- package/runtime/python/okstra_vendor/networkx/readwrite/__init__.py +0 -17
- package/runtime/python/okstra_vendor/networkx/readwrite/adjlist.py +0 -330
- package/runtime/python/okstra_vendor/networkx/readwrite/edgelist.py +0 -489
- package/runtime/python/okstra_vendor/networkx/readwrite/gexf.py +0 -1084
- package/runtime/python/okstra_vendor/networkx/readwrite/gml.py +0 -879
- package/runtime/python/okstra_vendor/networkx/readwrite/graph6.py +0 -427
- package/runtime/python/okstra_vendor/networkx/readwrite/graphml.py +0 -1053
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/__init__.py +0 -19
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/adjacency.py +0 -156
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/cytoscape.py +0 -190
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/node_link.py +0 -261
- package/runtime/python/okstra_vendor/networkx/readwrite/json_graph/tree.py +0 -137
- package/runtime/python/okstra_vendor/networkx/readwrite/leda.py +0 -108
- package/runtime/python/okstra_vendor/networkx/readwrite/multiline_adjlist.py +0 -393
- package/runtime/python/okstra_vendor/networkx/readwrite/p2g.py +0 -113
- package/runtime/python/okstra_vendor/networkx/readwrite/pajek.py +0 -286
- package/runtime/python/okstra_vendor/networkx/readwrite/sparse6.py +0 -379
- package/runtime/python/okstra_vendor/networkx/readwrite/text.py +0 -851
- package/runtime/python/okstra_vendor/networkx/relabel.py +0 -285
- package/runtime/python/okstra_vendor/networkx/utils/__init__.py +0 -8
- package/runtime/python/okstra_vendor/networkx/utils/backends.py +0 -2171
- package/runtime/python/okstra_vendor/networkx/utils/configs.py +0 -396
- package/runtime/python/okstra_vendor/networkx/utils/decorators.py +0 -1233
- package/runtime/python/okstra_vendor/networkx/utils/heaps.py +0 -338
- package/runtime/python/okstra_vendor/networkx/utils/mapped_queue.py +0 -297
- package/runtime/python/okstra_vendor/networkx/utils/misc.py +0 -703
- package/runtime/python/okstra_vendor/networkx/utils/random_sequence.py +0 -198
- package/runtime/python/okstra_vendor/networkx/utils/rcm.py +0 -159
- package/runtime/python/okstra_vendor/networkx/utils/union_find.py +0 -106
- package/runtime/skills/okstra-graphify/SKILL.md +0 -169
- package/src/commands/graphify.mjs +0 -32
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
"""Functions for computing communities based on centrality notions."""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = ["girvan_newman"]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@nx._dispatchable(preserve_edge_attrs="most_valuable_edge")
|
|
9
|
-
def girvan_newman(G, most_valuable_edge=None):
|
|
10
|
-
"""Finds communities in a graph using the Girvan–Newman method.
|
|
11
|
-
|
|
12
|
-
Parameters
|
|
13
|
-
----------
|
|
14
|
-
G : NetworkX graph
|
|
15
|
-
|
|
16
|
-
most_valuable_edge : function
|
|
17
|
-
Function that takes a graph as input and outputs an edge. The
|
|
18
|
-
edge returned by this function will be recomputed and removed at
|
|
19
|
-
each iteration of the algorithm.
|
|
20
|
-
|
|
21
|
-
If not specified, the edge with the highest
|
|
22
|
-
:func:`networkx.edge_betweenness_centrality` will be used.
|
|
23
|
-
|
|
24
|
-
Returns
|
|
25
|
-
-------
|
|
26
|
-
iterator
|
|
27
|
-
Iterator over tuples of sets of nodes in `G`. Each set of node
|
|
28
|
-
is a community, each tuple is a sequence of communities at a
|
|
29
|
-
particular level of the algorithm.
|
|
30
|
-
|
|
31
|
-
Examples
|
|
32
|
-
--------
|
|
33
|
-
To get the first pair of communities::
|
|
34
|
-
|
|
35
|
-
>>> G = nx.path_graph(10)
|
|
36
|
-
>>> comp = nx.community.girvan_newman(G)
|
|
37
|
-
>>> tuple(sorted(c) for c in next(comp))
|
|
38
|
-
([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
|
|
39
|
-
|
|
40
|
-
To get only the first *k* tuples of communities, use
|
|
41
|
-
:func:`itertools.islice`::
|
|
42
|
-
|
|
43
|
-
>>> import itertools
|
|
44
|
-
>>> G = nx.path_graph(8)
|
|
45
|
-
>>> k = 2
|
|
46
|
-
>>> comp = nx.community.girvan_newman(G)
|
|
47
|
-
>>> for communities in itertools.islice(comp, k):
|
|
48
|
-
... print(tuple(sorted(c) for c in communities))
|
|
49
|
-
...
|
|
50
|
-
([0, 1, 2, 3], [4, 5, 6, 7])
|
|
51
|
-
([0, 1], [2, 3], [4, 5, 6, 7])
|
|
52
|
-
|
|
53
|
-
To stop getting tuples of communities once the number of communities
|
|
54
|
-
is greater than *k*, use :func:`itertools.takewhile`::
|
|
55
|
-
|
|
56
|
-
>>> import itertools
|
|
57
|
-
>>> G = nx.path_graph(8)
|
|
58
|
-
>>> k = 4
|
|
59
|
-
>>> comp = nx.community.girvan_newman(G)
|
|
60
|
-
>>> limited = itertools.takewhile(lambda c: len(c) <= k, comp)
|
|
61
|
-
>>> for communities in limited:
|
|
62
|
-
... print(tuple(sorted(c) for c in communities))
|
|
63
|
-
...
|
|
64
|
-
([0, 1, 2, 3], [4, 5, 6, 7])
|
|
65
|
-
([0, 1], [2, 3], [4, 5, 6, 7])
|
|
66
|
-
([0, 1], [2, 3], [4, 5], [6, 7])
|
|
67
|
-
|
|
68
|
-
To just choose an edge to remove based on the weight::
|
|
69
|
-
|
|
70
|
-
>>> from operator import itemgetter
|
|
71
|
-
>>> G = nx.path_graph(10)
|
|
72
|
-
>>> edges = G.edges()
|
|
73
|
-
>>> nx.set_edge_attributes(G, {(u, v): v for u, v in edges}, "weight")
|
|
74
|
-
>>> def heaviest(G):
|
|
75
|
-
... u, v, w = max(G.edges(data="weight"), key=itemgetter(2))
|
|
76
|
-
... return (u, v)
|
|
77
|
-
...
|
|
78
|
-
>>> comp = nx.community.girvan_newman(G, most_valuable_edge=heaviest)
|
|
79
|
-
>>> tuple(sorted(c) for c in next(comp))
|
|
80
|
-
([0, 1, 2, 3, 4, 5, 6, 7, 8], [9])
|
|
81
|
-
|
|
82
|
-
To utilize edge weights when choosing an edge with, for example, the
|
|
83
|
-
highest betweenness centrality::
|
|
84
|
-
|
|
85
|
-
>>> from networkx import edge_betweenness_centrality as betweenness
|
|
86
|
-
>>> def most_central_edge(G):
|
|
87
|
-
... centrality = betweenness(G, weight="weight")
|
|
88
|
-
... return max(centrality, key=centrality.get)
|
|
89
|
-
...
|
|
90
|
-
>>> G = nx.path_graph(10)
|
|
91
|
-
>>> comp = nx.community.girvan_newman(G, most_valuable_edge=most_central_edge)
|
|
92
|
-
>>> tuple(sorted(c) for c in next(comp))
|
|
93
|
-
([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
|
|
94
|
-
|
|
95
|
-
To specify a different ranking algorithm for edges, use the
|
|
96
|
-
`most_valuable_edge` keyword argument::
|
|
97
|
-
|
|
98
|
-
>>> from networkx import edge_betweenness_centrality
|
|
99
|
-
>>> from random import random
|
|
100
|
-
>>> def most_central_edge(G):
|
|
101
|
-
... centrality = edge_betweenness_centrality(G)
|
|
102
|
-
... max_cent = max(centrality.values())
|
|
103
|
-
... # Scale the centrality values so they are between 0 and 1,
|
|
104
|
-
... # and add some random noise.
|
|
105
|
-
... centrality = {e: c / max_cent for e, c in centrality.items()}
|
|
106
|
-
... # Add some random noise.
|
|
107
|
-
... centrality = {e: c + random() for e, c in centrality.items()}
|
|
108
|
-
... return max(centrality, key=centrality.get)
|
|
109
|
-
...
|
|
110
|
-
>>> G = nx.path_graph(10)
|
|
111
|
-
>>> comp = nx.community.girvan_newman(G, most_valuable_edge=most_central_edge)
|
|
112
|
-
|
|
113
|
-
Notes
|
|
114
|
-
-----
|
|
115
|
-
The Girvan–Newman algorithm detects communities by progressively
|
|
116
|
-
removing edges from the original graph. The algorithm removes the
|
|
117
|
-
"most valuable" edge, traditionally the edge with the highest
|
|
118
|
-
betweenness centrality, at each step. As the graph breaks down into
|
|
119
|
-
pieces, the tightly knit community structure is exposed and the
|
|
120
|
-
result can be depicted as a dendrogram.
|
|
121
|
-
|
|
122
|
-
"""
|
|
123
|
-
# If the graph is already empty, simply return its connected
|
|
124
|
-
# components.
|
|
125
|
-
if G.number_of_edges() == 0:
|
|
126
|
-
yield tuple(nx.connected_components(G))
|
|
127
|
-
return
|
|
128
|
-
# If no function is provided for computing the most valuable edge,
|
|
129
|
-
# use the edge betweenness centrality.
|
|
130
|
-
if most_valuable_edge is None:
|
|
131
|
-
|
|
132
|
-
def most_valuable_edge(G):
|
|
133
|
-
"""Returns the edge with the highest betweenness centrality
|
|
134
|
-
in the graph `G`.
|
|
135
|
-
|
|
136
|
-
"""
|
|
137
|
-
# We have guaranteed that the graph is non-empty, so this
|
|
138
|
-
# dictionary will never be empty.
|
|
139
|
-
betweenness = nx.edge_betweenness_centrality(G)
|
|
140
|
-
return max(betweenness, key=betweenness.get)
|
|
141
|
-
|
|
142
|
-
# The copy of G here must include the edge weight data.
|
|
143
|
-
g = G.copy().to_undirected()
|
|
144
|
-
# Self-loops must be removed because their removal has no effect on
|
|
145
|
-
# the connected components of the graph.
|
|
146
|
-
g.remove_edges_from(nx.selfloop_edges(g))
|
|
147
|
-
while g.number_of_edges() > 0:
|
|
148
|
-
yield _without_most_central_edges(g, most_valuable_edge)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def _without_most_central_edges(G, most_valuable_edge):
|
|
152
|
-
"""Returns the connected components of the graph that results from
|
|
153
|
-
repeatedly removing the most "valuable" edge in the graph.
|
|
154
|
-
|
|
155
|
-
`G` must be a non-empty graph. This function modifies the graph `G`
|
|
156
|
-
in-place; that is, it removes edges on the graph `G`.
|
|
157
|
-
|
|
158
|
-
`most_valuable_edge` is a function that takes the graph `G` as input
|
|
159
|
-
(or a subgraph with one or more edges of `G` removed) and returns an
|
|
160
|
-
edge. That edge will be removed and this process will be repeated
|
|
161
|
-
until the number of connected components in the graph increases.
|
|
162
|
-
|
|
163
|
-
"""
|
|
164
|
-
original_num_components = nx.number_connected_components(G)
|
|
165
|
-
num_new_components = original_num_components
|
|
166
|
-
while num_new_components <= original_num_components:
|
|
167
|
-
edge = most_valuable_edge(G)
|
|
168
|
-
G.remove_edge(*edge)
|
|
169
|
-
new_components = tuple(nx.connected_components(G))
|
|
170
|
-
num_new_components = len(new_components)
|
|
171
|
-
return new_components
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"""Helper functions for community-finding algorithms."""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = ["is_partition"]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@nx._dispatchable
|
|
9
|
-
def is_partition(G, communities):
|
|
10
|
-
"""Returns *True* if `communities` is a partition of the nodes of `G`.
|
|
11
|
-
|
|
12
|
-
A partition of a universe set is a family of pairwise disjoint sets
|
|
13
|
-
whose union is the entire universe set.
|
|
14
|
-
|
|
15
|
-
Parameters
|
|
16
|
-
----------
|
|
17
|
-
G : NetworkX graph.
|
|
18
|
-
|
|
19
|
-
communities : list or iterable of sets of nodes
|
|
20
|
-
If not a list, the iterable is converted internally to a list.
|
|
21
|
-
If it is an iterator it is exhausted.
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
|
-
# Alternate implementation:
|
|
25
|
-
# return all(sum(1 if v in c else 0 for c in communities) == 1 for v in G)
|
|
26
|
-
if not isinstance(communities, list):
|
|
27
|
-
communities = list(communities)
|
|
28
|
-
nodes = {n for c in communities for n in c if n in G}
|
|
29
|
-
|
|
30
|
-
return len(G) == len(nodes) == sum(len(c) for c in communities)
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import functools
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = [
|
|
6
|
-
"edge_betweenness_partition",
|
|
7
|
-
"edge_current_flow_betweenness_partition",
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
12
|
-
def edge_betweenness_partition(G, number_of_sets, *, weight=None):
|
|
13
|
-
"""Partition created by iteratively removing the highest edge betweenness edge.
|
|
14
|
-
|
|
15
|
-
This algorithm works by calculating the edge betweenness for all
|
|
16
|
-
edges and removing the edge with the highest value. It is then
|
|
17
|
-
determined whether the graph has been broken into at least
|
|
18
|
-
`number_of_sets` connected components.
|
|
19
|
-
If not the process is repeated.
|
|
20
|
-
|
|
21
|
-
Parameters
|
|
22
|
-
----------
|
|
23
|
-
G : NetworkX Graph, DiGraph or MultiGraph
|
|
24
|
-
Graph to be partitioned
|
|
25
|
-
|
|
26
|
-
number_of_sets : int
|
|
27
|
-
Number of sets in the desired partition of the graph
|
|
28
|
-
|
|
29
|
-
weight : key, optional, default=None
|
|
30
|
-
The key to use if using weights for edge betweenness calculation
|
|
31
|
-
|
|
32
|
-
Returns
|
|
33
|
-
-------
|
|
34
|
-
C : list of sets
|
|
35
|
-
Partition of the nodes of G
|
|
36
|
-
|
|
37
|
-
Raises
|
|
38
|
-
------
|
|
39
|
-
NetworkXError
|
|
40
|
-
If number_of_sets is <= 0 or if number_of_sets > len(G)
|
|
41
|
-
|
|
42
|
-
Examples
|
|
43
|
-
--------
|
|
44
|
-
>>> G = nx.karate_club_graph()
|
|
45
|
-
>>> part = nx.community.edge_betweenness_partition(G, 2)
|
|
46
|
-
>>> {0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 16, 17, 19, 21} in part
|
|
47
|
-
True
|
|
48
|
-
>>> {
|
|
49
|
-
... 2,
|
|
50
|
-
... 8,
|
|
51
|
-
... 9,
|
|
52
|
-
... 14,
|
|
53
|
-
... 15,
|
|
54
|
-
... 18,
|
|
55
|
-
... 20,
|
|
56
|
-
... 22,
|
|
57
|
-
... 23,
|
|
58
|
-
... 24,
|
|
59
|
-
... 25,
|
|
60
|
-
... 26,
|
|
61
|
-
... 27,
|
|
62
|
-
... 28,
|
|
63
|
-
... 29,
|
|
64
|
-
... 30,
|
|
65
|
-
... 31,
|
|
66
|
-
... 32,
|
|
67
|
-
... 33,
|
|
68
|
-
... } in part
|
|
69
|
-
True
|
|
70
|
-
|
|
71
|
-
See Also
|
|
72
|
-
--------
|
|
73
|
-
edge_current_flow_betweenness_partition
|
|
74
|
-
|
|
75
|
-
Notes
|
|
76
|
-
-----
|
|
77
|
-
This algorithm is fairly slow, as both the calculation of connected
|
|
78
|
-
components and edge betweenness relies on all pairs shortest
|
|
79
|
-
path algorithms. They could potentially be combined to cut down
|
|
80
|
-
on overall computation time.
|
|
81
|
-
|
|
82
|
-
References
|
|
83
|
-
----------
|
|
84
|
-
.. [1] Santo Fortunato 'Community Detection in Graphs' Physical Reports
|
|
85
|
-
Volume 486, Issue 3-5 p. 75-174
|
|
86
|
-
http://arxiv.org/abs/0906.0612
|
|
87
|
-
"""
|
|
88
|
-
if number_of_sets <= 0:
|
|
89
|
-
raise nx.NetworkXError("number_of_sets must be >0")
|
|
90
|
-
if number_of_sets == 1:
|
|
91
|
-
return [set(G)]
|
|
92
|
-
if number_of_sets == len(G):
|
|
93
|
-
return [{n} for n in G]
|
|
94
|
-
if number_of_sets > len(G):
|
|
95
|
-
raise nx.NetworkXError("number_of_sets must be <= len(G)")
|
|
96
|
-
|
|
97
|
-
H = G.copy()
|
|
98
|
-
partition = list(nx.connected_components(H))
|
|
99
|
-
while len(partition) < number_of_sets:
|
|
100
|
-
ranking = nx.edge_betweenness_centrality(H, weight=weight)
|
|
101
|
-
edge = max(ranking, key=ranking.get)
|
|
102
|
-
H.remove_edge(*edge)
|
|
103
|
-
partition = list(nx.connected_components(H))
|
|
104
|
-
return partition
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
108
|
-
def edge_current_flow_betweenness_partition(G, number_of_sets, *, weight=None):
|
|
109
|
-
"""Partition created by removing the highest edge current flow betweenness edge.
|
|
110
|
-
|
|
111
|
-
This algorithm works by calculating the edge current flow
|
|
112
|
-
betweenness for all edges and removing the edge with the
|
|
113
|
-
highest value. It is then determined whether the graph has
|
|
114
|
-
been broken into at least `number_of_sets` connected
|
|
115
|
-
components. If not the process is repeated.
|
|
116
|
-
|
|
117
|
-
Parameters
|
|
118
|
-
----------
|
|
119
|
-
G : NetworkX Graph, DiGraph or MultiGraph
|
|
120
|
-
Graph to be partitioned
|
|
121
|
-
|
|
122
|
-
number_of_sets : int
|
|
123
|
-
Number of sets in the desired partition of the graph
|
|
124
|
-
|
|
125
|
-
weight : key, optional (default=None)
|
|
126
|
-
The edge attribute key to use as weights for
|
|
127
|
-
edge current flow betweenness calculations
|
|
128
|
-
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
C : list of sets
|
|
132
|
-
Partition of G
|
|
133
|
-
|
|
134
|
-
Raises
|
|
135
|
-
------
|
|
136
|
-
NetworkXError
|
|
137
|
-
If number_of_sets is <= 0 or number_of_sets > len(G)
|
|
138
|
-
|
|
139
|
-
Examples
|
|
140
|
-
--------
|
|
141
|
-
>>> G = nx.karate_club_graph()
|
|
142
|
-
>>> part = nx.community.edge_current_flow_betweenness_partition(G, 2)
|
|
143
|
-
>>> {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 16, 17, 19, 21} in part
|
|
144
|
-
True
|
|
145
|
-
>>> {8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33} in part
|
|
146
|
-
True
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
See Also
|
|
150
|
-
--------
|
|
151
|
-
edge_betweenness_partition
|
|
152
|
-
|
|
153
|
-
Notes
|
|
154
|
-
-----
|
|
155
|
-
This algorithm is extremely slow, as the recalculation of the edge
|
|
156
|
-
current flow betweenness is extremely slow.
|
|
157
|
-
|
|
158
|
-
References
|
|
159
|
-
----------
|
|
160
|
-
.. [1] Santo Fortunato 'Community Detection in Graphs' Physical Reports
|
|
161
|
-
Volume 486, Issue 3-5 p. 75-174
|
|
162
|
-
http://arxiv.org/abs/0906.0612
|
|
163
|
-
"""
|
|
164
|
-
if number_of_sets <= 0:
|
|
165
|
-
raise nx.NetworkXError("number_of_sets must be >0")
|
|
166
|
-
elif number_of_sets == 1:
|
|
167
|
-
return [set(G)]
|
|
168
|
-
elif number_of_sets == len(G):
|
|
169
|
-
return [{n} for n in G]
|
|
170
|
-
elif number_of_sets > len(G):
|
|
171
|
-
raise nx.NetworkXError("number_of_sets must be <= len(G)")
|
|
172
|
-
|
|
173
|
-
rank = functools.partial(
|
|
174
|
-
nx.edge_current_flow_betweenness_centrality, normalized=False, weight=weight
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
# current flow requires a connected network so we track the components explicitly
|
|
178
|
-
H = G.copy()
|
|
179
|
-
partition = list(nx.connected_components(H))
|
|
180
|
-
if len(partition) > 1:
|
|
181
|
-
Hcc_subgraphs = [H.subgraph(cc).copy() for cc in partition]
|
|
182
|
-
else:
|
|
183
|
-
Hcc_subgraphs = [H]
|
|
184
|
-
|
|
185
|
-
ranking = {}
|
|
186
|
-
for Hcc in Hcc_subgraphs:
|
|
187
|
-
ranking.update(rank(Hcc))
|
|
188
|
-
|
|
189
|
-
while len(partition) < number_of_sets:
|
|
190
|
-
edge = max(ranking, key=ranking.get)
|
|
191
|
-
for cc, Hcc in zip(partition, Hcc_subgraphs):
|
|
192
|
-
if edge[0] in cc:
|
|
193
|
-
Hcc.remove_edge(*edge)
|
|
194
|
-
del ranking[edge]
|
|
195
|
-
splitcc_list = list(nx.connected_components(Hcc))
|
|
196
|
-
if len(splitcc_list) > 1:
|
|
197
|
-
# there are 2 connected components. split off smaller one
|
|
198
|
-
cc_new = min(splitcc_list, key=len)
|
|
199
|
-
Hcc_new = Hcc.subgraph(cc_new).copy()
|
|
200
|
-
# update edge rankings for Hcc_new
|
|
201
|
-
newranks = rank(Hcc_new)
|
|
202
|
-
for e, r in newranks.items():
|
|
203
|
-
ranking[e if e in ranking else e[::-1]] = r
|
|
204
|
-
# append new cc and Hcc to their lists.
|
|
205
|
-
partition.append(cc_new)
|
|
206
|
-
Hcc_subgraphs.append(Hcc_new)
|
|
207
|
-
|
|
208
|
-
# leave existing cc and Hcc in their lists, but shrink them
|
|
209
|
-
Hcc.remove_nodes_from(cc_new)
|
|
210
|
-
cc.difference_update(cc_new)
|
|
211
|
-
# update edge rankings for Hcc whether it was split or not
|
|
212
|
-
newranks = rank(Hcc)
|
|
213
|
-
for e, r in newranks.items():
|
|
214
|
-
ranking[e if e in ranking else e[::-1]] = r
|
|
215
|
-
break
|
|
216
|
-
return partition
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
from collections import defaultdict
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = ["k_clique_communities"]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@nx._dispatchable
|
|
9
|
-
def k_clique_communities(G, k, cliques=None):
|
|
10
|
-
"""Find k-clique communities in graph using the percolation method.
|
|
11
|
-
|
|
12
|
-
A k-clique community is the union of all cliques of size k that
|
|
13
|
-
can be reached through adjacent (sharing k-1 nodes) k-cliques.
|
|
14
|
-
|
|
15
|
-
Parameters
|
|
16
|
-
----------
|
|
17
|
-
G : NetworkX graph
|
|
18
|
-
|
|
19
|
-
k : int
|
|
20
|
-
Size of smallest clique
|
|
21
|
-
|
|
22
|
-
cliques: list or generator
|
|
23
|
-
Precomputed cliques (use networkx.find_cliques(G))
|
|
24
|
-
|
|
25
|
-
Returns
|
|
26
|
-
-------
|
|
27
|
-
Yields sets of nodes, one for each k-clique community.
|
|
28
|
-
|
|
29
|
-
Examples
|
|
30
|
-
--------
|
|
31
|
-
>>> G = nx.complete_graph(5)
|
|
32
|
-
>>> K5 = nx.convert_node_labels_to_integers(G, first_label=2)
|
|
33
|
-
>>> G.add_edges_from(K5.edges())
|
|
34
|
-
>>> c = list(nx.community.k_clique_communities(G, 4))
|
|
35
|
-
>>> sorted(list(c[0]))
|
|
36
|
-
[0, 1, 2, 3, 4, 5, 6]
|
|
37
|
-
>>> list(nx.community.k_clique_communities(G, 6))
|
|
38
|
-
[]
|
|
39
|
-
|
|
40
|
-
References
|
|
41
|
-
----------
|
|
42
|
-
.. [1] Gergely Palla, Imre Derényi, Illés Farkas1, and Tamás Vicsek,
|
|
43
|
-
Uncovering the overlapping community structure of complex networks
|
|
44
|
-
in nature and society Nature 435, 814-818, 2005,
|
|
45
|
-
doi:10.1038/nature03607
|
|
46
|
-
"""
|
|
47
|
-
if k < 2:
|
|
48
|
-
raise nx.NetworkXError(f"k={k}, k must be greater than 1.")
|
|
49
|
-
if cliques is None:
|
|
50
|
-
cliques = nx.find_cliques(G)
|
|
51
|
-
cliques = [frozenset(c) for c in cliques if len(c) >= k]
|
|
52
|
-
|
|
53
|
-
# First index which nodes are in which cliques
|
|
54
|
-
membership_dict = defaultdict(list)
|
|
55
|
-
for clique in cliques:
|
|
56
|
-
for node in clique:
|
|
57
|
-
membership_dict[node].append(clique)
|
|
58
|
-
|
|
59
|
-
# For each clique, see which adjacent cliques percolate
|
|
60
|
-
perc_graph = nx.Graph()
|
|
61
|
-
perc_graph.add_nodes_from(cliques)
|
|
62
|
-
for clique in cliques:
|
|
63
|
-
for adj_clique in _get_adjacent_cliques(clique, membership_dict):
|
|
64
|
-
if len(clique.intersection(adj_clique)) >= (k - 1):
|
|
65
|
-
perc_graph.add_edge(clique, adj_clique)
|
|
66
|
-
|
|
67
|
-
# Connected components of clique graph with perc edges
|
|
68
|
-
# are the percolated cliques
|
|
69
|
-
for component in nx.connected_components(perc_graph):
|
|
70
|
-
yield (frozenset.union(*component))
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _get_adjacent_cliques(clique, membership_dict):
|
|
74
|
-
adjacent_cliques = set()
|
|
75
|
-
for n in clique:
|
|
76
|
-
for adj_clique in membership_dict[n]:
|
|
77
|
-
if clique != adj_clique:
|
|
78
|
-
adjacent_cliques.add(adj_clique)
|
|
79
|
-
return adjacent_cliques
|