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,347 +0,0 @@
|
|
|
1
|
-
"""Functions for measuring the quality of a partition (into
|
|
2
|
-
communities).
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from itertools import combinations
|
|
7
|
-
|
|
8
|
-
import networkx as nx
|
|
9
|
-
from networkx import NetworkXError
|
|
10
|
-
from networkx.algorithms.community.community_utils import is_partition
|
|
11
|
-
from networkx.utils.decorators import argmap
|
|
12
|
-
|
|
13
|
-
__all__ = ["modularity", "partition_quality"]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class NotAPartition(NetworkXError):
|
|
17
|
-
"""Raised if a given collection is not a partition."""
|
|
18
|
-
|
|
19
|
-
def __init__(self, G, collection):
|
|
20
|
-
msg = f"{collection} is not a valid partition of the graph {G}"
|
|
21
|
-
super().__init__(msg)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _require_partition(G, partition):
|
|
25
|
-
"""Decorator to check that a valid partition is input to a function
|
|
26
|
-
|
|
27
|
-
Raises :exc:`networkx.NetworkXError` if the partition is not valid.
|
|
28
|
-
|
|
29
|
-
This decorator should be used on functions whose first two arguments
|
|
30
|
-
are a graph and a partition of the nodes of that graph (in that
|
|
31
|
-
order)::
|
|
32
|
-
|
|
33
|
-
>>> @require_partition
|
|
34
|
-
... def foo(G, partition):
|
|
35
|
-
... print("partition is valid!")
|
|
36
|
-
...
|
|
37
|
-
>>> G = nx.complete_graph(5)
|
|
38
|
-
>>> partition = [{0, 1}, {2, 3}, {4}]
|
|
39
|
-
>>> foo(G, partition)
|
|
40
|
-
partition is valid!
|
|
41
|
-
>>> partition = [{0}, {2, 3}, {4}]
|
|
42
|
-
>>> foo(G, partition)
|
|
43
|
-
Traceback (most recent call last):
|
|
44
|
-
...
|
|
45
|
-
networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G
|
|
46
|
-
>>> partition = [{0, 1}, {1, 2, 3}, {4}]
|
|
47
|
-
>>> foo(G, partition)
|
|
48
|
-
Traceback (most recent call last):
|
|
49
|
-
...
|
|
50
|
-
networkx.exception.NetworkXError: `partition` is not a valid partition of the nodes of G
|
|
51
|
-
|
|
52
|
-
"""
|
|
53
|
-
if is_partition(G, partition):
|
|
54
|
-
return G, partition
|
|
55
|
-
raise nx.NetworkXError("`partition` is not a valid partition of the nodes of G")
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
require_partition = argmap(_require_partition, (0, 1))
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
@nx._dispatchable
|
|
62
|
-
def intra_community_edges(G, partition):
|
|
63
|
-
"""Returns the number of intra-community edges for a partition of `G`.
|
|
64
|
-
|
|
65
|
-
Parameters
|
|
66
|
-
----------
|
|
67
|
-
G : NetworkX graph.
|
|
68
|
-
|
|
69
|
-
partition : iterable of sets of nodes
|
|
70
|
-
This must be a partition of the nodes of `G`.
|
|
71
|
-
|
|
72
|
-
The "intra-community edges" are those edges joining a pair of nodes
|
|
73
|
-
in the same block of the partition.
|
|
74
|
-
|
|
75
|
-
"""
|
|
76
|
-
return sum(G.subgraph(block).size() for block in partition)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@nx._dispatchable
|
|
80
|
-
def inter_community_edges(G, partition):
|
|
81
|
-
"""Returns the number of inter-community edges for a partition of `G`.
|
|
82
|
-
according to the given
|
|
83
|
-
partition of the nodes of `G`.
|
|
84
|
-
|
|
85
|
-
Parameters
|
|
86
|
-
----------
|
|
87
|
-
G : NetworkX graph.
|
|
88
|
-
|
|
89
|
-
partition : iterable of sets of nodes
|
|
90
|
-
This must be a partition of the nodes of `G`.
|
|
91
|
-
|
|
92
|
-
The *inter-community edges* are those edges joining a pair of nodes
|
|
93
|
-
in different blocks of the partition.
|
|
94
|
-
|
|
95
|
-
Implementation note: this function creates an intermediate graph
|
|
96
|
-
that may require the same amount of memory as that of `G`.
|
|
97
|
-
|
|
98
|
-
"""
|
|
99
|
-
# Alternate implementation that does not require constructing a new
|
|
100
|
-
# graph object (but does require constructing an affiliation
|
|
101
|
-
# dictionary):
|
|
102
|
-
#
|
|
103
|
-
# aff = dict(chain.from_iterable(((v, block) for v in block)
|
|
104
|
-
# for block in partition))
|
|
105
|
-
# return sum(1 for u, v in G.edges() if aff[u] != aff[v])
|
|
106
|
-
#
|
|
107
|
-
MG = nx.MultiDiGraph if G.is_directed() else nx.MultiGraph
|
|
108
|
-
return nx.quotient_graph(G, partition, create_using=MG).size()
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
@nx._dispatchable
|
|
112
|
-
def inter_community_non_edges(G, partition):
|
|
113
|
-
"""Returns the number of inter-community non-edges according to the
|
|
114
|
-
given partition of the nodes of `G`.
|
|
115
|
-
|
|
116
|
-
Parameters
|
|
117
|
-
----------
|
|
118
|
-
G : NetworkX graph.
|
|
119
|
-
|
|
120
|
-
partition : iterable of sets of nodes
|
|
121
|
-
This must be a partition of the nodes of `G`.
|
|
122
|
-
|
|
123
|
-
A *non-edge* is a pair of nodes (undirected if `G` is undirected)
|
|
124
|
-
that are not adjacent in `G`. The *inter-community non-edges* are
|
|
125
|
-
those non-edges on a pair of nodes in different blocks of the
|
|
126
|
-
partition.
|
|
127
|
-
|
|
128
|
-
Implementation note: this function creates two intermediate graphs,
|
|
129
|
-
which may require up to twice the amount of memory as required to
|
|
130
|
-
store `G`.
|
|
131
|
-
|
|
132
|
-
"""
|
|
133
|
-
# Alternate implementation that does not require constructing two
|
|
134
|
-
# new graph objects (but does require constructing an affiliation
|
|
135
|
-
# dictionary):
|
|
136
|
-
#
|
|
137
|
-
# aff = dict(chain.from_iterable(((v, block) for v in block)
|
|
138
|
-
# for block in partition))
|
|
139
|
-
# return sum(1 for u, v in nx.non_edges(G) if aff[u] != aff[v])
|
|
140
|
-
#
|
|
141
|
-
return inter_community_edges(nx.complement(G), partition)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
145
|
-
def modularity(G, communities, weight="weight", resolution=1):
|
|
146
|
-
r"""Returns the modularity of the given partition of the graph.
|
|
147
|
-
|
|
148
|
-
Modularity is defined in [1]_ as
|
|
149
|
-
|
|
150
|
-
.. math::
|
|
151
|
-
Q = \frac{1}{2m} \sum_{ij} \left( A_{ij} - \gamma\frac{k_ik_j}{2m}\right)
|
|
152
|
-
\delta(c_i,c_j)
|
|
153
|
-
|
|
154
|
-
where $m$ is the number of edges (or sum of all edge weights as in [5]_),
|
|
155
|
-
$A$ is the adjacency matrix of `G`, $k_i$ is the (weighted) degree of $i$,
|
|
156
|
-
$\gamma$ is the resolution parameter, and $\delta(c_i, c_j)$ is 1 if $i$ and
|
|
157
|
-
$j$ are in the same community else 0.
|
|
158
|
-
|
|
159
|
-
According to [2]_ (and verified by some algebra) this can be reduced to
|
|
160
|
-
|
|
161
|
-
.. math::
|
|
162
|
-
Q = \sum_{c=1}^{n}
|
|
163
|
-
\left[ \frac{L_c}{m} - \gamma\left( \frac{k_c}{2m} \right) ^2 \right]
|
|
164
|
-
|
|
165
|
-
where the sum iterates over all communities $c$, $m$ is the number of edges,
|
|
166
|
-
$L_c$ is the number of intra-community links for community $c$,
|
|
167
|
-
$k_c$ is the sum of degrees of the nodes in community $c$,
|
|
168
|
-
and $\gamma$ is the resolution parameter.
|
|
169
|
-
|
|
170
|
-
The resolution parameter sets an arbitrary tradeoff between intra-group
|
|
171
|
-
edges and inter-group edges. More complex grouping patterns can be
|
|
172
|
-
discovered by analyzing the same network with multiple values of gamma
|
|
173
|
-
and then combining the results [3]_. That said, it is very common to
|
|
174
|
-
simply use gamma=1. More on the choice of gamma is in [4]_.
|
|
175
|
-
|
|
176
|
-
The second formula is the one actually used in calculation of the modularity.
|
|
177
|
-
For directed graphs the second formula replaces $k_c$ with $k^{in}_c k^{out}_c$.
|
|
178
|
-
|
|
179
|
-
Parameters
|
|
180
|
-
----------
|
|
181
|
-
G : NetworkX Graph
|
|
182
|
-
|
|
183
|
-
communities : list or iterable of set of nodes
|
|
184
|
-
These node sets must represent a partition of G's nodes.
|
|
185
|
-
|
|
186
|
-
weight : string or None, optional (default="weight")
|
|
187
|
-
The edge attribute that holds the numerical value used
|
|
188
|
-
as a weight. If None or an edge does not have that attribute,
|
|
189
|
-
then that edge has weight 1.
|
|
190
|
-
|
|
191
|
-
resolution : float (default=1)
|
|
192
|
-
If resolution is less than 1, modularity favors larger communities.
|
|
193
|
-
Greater than 1 favors smaller communities.
|
|
194
|
-
|
|
195
|
-
Returns
|
|
196
|
-
-------
|
|
197
|
-
Q : float
|
|
198
|
-
The modularity of the partition.
|
|
199
|
-
|
|
200
|
-
Raises
|
|
201
|
-
------
|
|
202
|
-
NotAPartition
|
|
203
|
-
If `communities` is not a partition of the nodes of `G`.
|
|
204
|
-
|
|
205
|
-
Examples
|
|
206
|
-
--------
|
|
207
|
-
>>> G = nx.barbell_graph(3, 0)
|
|
208
|
-
>>> nx.community.modularity(G, [{0, 1, 2}, {3, 4, 5}])
|
|
209
|
-
0.35714285714285715
|
|
210
|
-
>>> nx.community.modularity(G, nx.community.label_propagation_communities(G))
|
|
211
|
-
0.35714285714285715
|
|
212
|
-
|
|
213
|
-
References
|
|
214
|
-
----------
|
|
215
|
-
.. [1] M. E. J. Newman "Networks: An Introduction", page 224.
|
|
216
|
-
Oxford University Press, 2011.
|
|
217
|
-
.. [2] Clauset, Aaron, Mark EJ Newman, and Cristopher Moore.
|
|
218
|
-
"Finding community structure in very large networks."
|
|
219
|
-
Phys. Rev. E 70.6 (2004). <https://arxiv.org/abs/cond-mat/0408187>
|
|
220
|
-
.. [3] Reichardt and Bornholdt "Statistical Mechanics of Community Detection"
|
|
221
|
-
Phys. Rev. E 74, 016110, 2006. https://doi.org/10.1103/PhysRevE.74.016110
|
|
222
|
-
.. [4] M. E. J. Newman, "Equivalence between modularity optimization and
|
|
223
|
-
maximum likelihood methods for community detection"
|
|
224
|
-
Phys. Rev. E 94, 052315, 2016. https://doi.org/10.1103/PhysRevE.94.052315
|
|
225
|
-
.. [5] Blondel, V.D. et al. "Fast unfolding of communities in large
|
|
226
|
-
networks" J. Stat. Mech 10008, 1-12 (2008).
|
|
227
|
-
https://doi.org/10.1088/1742-5468/2008/10/P10008
|
|
228
|
-
"""
|
|
229
|
-
if not isinstance(communities, list):
|
|
230
|
-
communities = list(communities)
|
|
231
|
-
if not is_partition(G, communities):
|
|
232
|
-
raise NotAPartition(G, communities)
|
|
233
|
-
|
|
234
|
-
directed = G.is_directed()
|
|
235
|
-
if directed:
|
|
236
|
-
out_degree = dict(G.out_degree(weight=weight))
|
|
237
|
-
in_degree = dict(G.in_degree(weight=weight))
|
|
238
|
-
m = sum(out_degree.values())
|
|
239
|
-
norm = 1 / m**2
|
|
240
|
-
else:
|
|
241
|
-
out_degree = in_degree = dict(G.degree(weight=weight))
|
|
242
|
-
deg_sum = sum(out_degree.values())
|
|
243
|
-
m = deg_sum / 2
|
|
244
|
-
norm = 1 / deg_sum**2
|
|
245
|
-
|
|
246
|
-
def community_contribution(community):
|
|
247
|
-
comm = set(community)
|
|
248
|
-
L_c = sum(wt for u, v, wt in G.edges(comm, data=weight, default=1) if v in comm)
|
|
249
|
-
|
|
250
|
-
out_degree_sum = sum(out_degree[u] for u in comm)
|
|
251
|
-
in_degree_sum = sum(in_degree[u] for u in comm) if directed else out_degree_sum
|
|
252
|
-
|
|
253
|
-
return L_c / m - resolution * out_degree_sum * in_degree_sum * norm
|
|
254
|
-
|
|
255
|
-
return sum(map(community_contribution, communities))
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
@require_partition
|
|
259
|
-
@nx._dispatchable
|
|
260
|
-
def partition_quality(G, partition):
|
|
261
|
-
"""Returns the coverage and performance of a partition of G.
|
|
262
|
-
|
|
263
|
-
The *coverage* of a partition is the ratio of the number of
|
|
264
|
-
intra-community edges to the total number of edges in the graph.
|
|
265
|
-
|
|
266
|
-
The *performance* of a partition is the number of
|
|
267
|
-
intra-community edges plus inter-community non-edges divided by the total
|
|
268
|
-
number of potential edges.
|
|
269
|
-
|
|
270
|
-
This algorithm has complexity $O(C^2 + L)$ where C is the number of
|
|
271
|
-
communities and L is the number of links.
|
|
272
|
-
|
|
273
|
-
Parameters
|
|
274
|
-
----------
|
|
275
|
-
G : NetworkX graph
|
|
276
|
-
|
|
277
|
-
partition : sequence
|
|
278
|
-
Partition of the nodes of `G`, represented as a sequence of
|
|
279
|
-
sets of nodes (blocks). Each block of the partition represents a
|
|
280
|
-
community.
|
|
281
|
-
|
|
282
|
-
Returns
|
|
283
|
-
-------
|
|
284
|
-
(float, float)
|
|
285
|
-
The (coverage, performance) tuple of the partition, as defined above.
|
|
286
|
-
|
|
287
|
-
Raises
|
|
288
|
-
------
|
|
289
|
-
NetworkXError
|
|
290
|
-
If `partition` is not a valid partition of the nodes of `G`.
|
|
291
|
-
|
|
292
|
-
Notes
|
|
293
|
-
-----
|
|
294
|
-
If `G` is a multigraph;
|
|
295
|
-
- for coverage, the multiplicity of edges is counted
|
|
296
|
-
- for performance, the result is -1 (total number of possible edges is not defined)
|
|
297
|
-
|
|
298
|
-
References
|
|
299
|
-
----------
|
|
300
|
-
.. [1] Santo Fortunato.
|
|
301
|
-
"Community Detection in Graphs".
|
|
302
|
-
*Physical Reports*, Volume 486, Issue 3--5 pp. 75--174
|
|
303
|
-
<https://arxiv.org/abs/0906.0612>
|
|
304
|
-
"""
|
|
305
|
-
|
|
306
|
-
node_community = {}
|
|
307
|
-
for i, community in enumerate(partition):
|
|
308
|
-
for node in community:
|
|
309
|
-
node_community[node] = i
|
|
310
|
-
|
|
311
|
-
# `performance` is not defined for multigraphs
|
|
312
|
-
if not G.is_multigraph():
|
|
313
|
-
# Iterate over the communities, quadratic, to calculate `possible_inter_community_edges`
|
|
314
|
-
possible_inter_community_edges = sum(
|
|
315
|
-
len(p1) * len(p2) for p1, p2 in combinations(partition, 2)
|
|
316
|
-
)
|
|
317
|
-
|
|
318
|
-
if G.is_directed():
|
|
319
|
-
possible_inter_community_edges *= 2
|
|
320
|
-
else:
|
|
321
|
-
possible_inter_community_edges = 0
|
|
322
|
-
|
|
323
|
-
# Compute the number of edges in the complete graph -- `n` nodes,
|
|
324
|
-
# directed or undirected, depending on `G`
|
|
325
|
-
n = len(G)
|
|
326
|
-
total_pairs = n * (n - 1)
|
|
327
|
-
if not G.is_directed():
|
|
328
|
-
total_pairs //= 2
|
|
329
|
-
|
|
330
|
-
intra_community_edges = 0
|
|
331
|
-
inter_community_non_edges = possible_inter_community_edges
|
|
332
|
-
|
|
333
|
-
# Iterate over the links to count `intra_community_edges` and `inter_community_non_edges`
|
|
334
|
-
for e in G.edges():
|
|
335
|
-
if node_community[e[0]] == node_community[e[1]]:
|
|
336
|
-
intra_community_edges += 1
|
|
337
|
-
else:
|
|
338
|
-
inter_community_non_edges -= 1
|
|
339
|
-
|
|
340
|
-
coverage = intra_community_edges / len(G.edges)
|
|
341
|
-
|
|
342
|
-
if G.is_multigraph():
|
|
343
|
-
performance = -1.0
|
|
344
|
-
else:
|
|
345
|
-
performance = (intra_community_edges + inter_community_non_edges) / total_pairs
|
|
346
|
-
|
|
347
|
-
return coverage, performance
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"""Attracting components."""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
from networkx.utils.decorators import not_implemented_for
|
|
5
|
-
|
|
6
|
-
__all__ = [
|
|
7
|
-
"number_attracting_components",
|
|
8
|
-
"attracting_components",
|
|
9
|
-
"is_attracting_component",
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@not_implemented_for("undirected")
|
|
14
|
-
@nx._dispatchable
|
|
15
|
-
def attracting_components(G):
|
|
16
|
-
"""Generates the attracting components in `G`.
|
|
17
|
-
|
|
18
|
-
An attracting component in a directed graph `G` is a strongly connected
|
|
19
|
-
component with the property that a random walker on the graph will never
|
|
20
|
-
leave the component, once it enters the component.
|
|
21
|
-
|
|
22
|
-
The nodes in attracting components can also be thought of as recurrent
|
|
23
|
-
nodes. If a random walker enters the attractor containing the node, then
|
|
24
|
-
the node will be visited infinitely often.
|
|
25
|
-
|
|
26
|
-
To obtain induced subgraphs on each component use:
|
|
27
|
-
``(G.subgraph(c).copy() for c in attracting_components(G))``
|
|
28
|
-
|
|
29
|
-
Parameters
|
|
30
|
-
----------
|
|
31
|
-
G : DiGraph, MultiDiGraph
|
|
32
|
-
The graph to be analyzed.
|
|
33
|
-
|
|
34
|
-
Returns
|
|
35
|
-
-------
|
|
36
|
-
attractors : generator of sets
|
|
37
|
-
A generator of sets of nodes, one for each attracting component of G.
|
|
38
|
-
|
|
39
|
-
Raises
|
|
40
|
-
------
|
|
41
|
-
NetworkXNotImplemented
|
|
42
|
-
If the input graph is undirected.
|
|
43
|
-
|
|
44
|
-
See Also
|
|
45
|
-
--------
|
|
46
|
-
number_attracting_components
|
|
47
|
-
is_attracting_component
|
|
48
|
-
|
|
49
|
-
"""
|
|
50
|
-
scc = list(nx.strongly_connected_components(G))
|
|
51
|
-
cG = nx.condensation(G, scc)
|
|
52
|
-
for n in cG:
|
|
53
|
-
if cG.out_degree(n) == 0:
|
|
54
|
-
yield scc[n]
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@not_implemented_for("undirected")
|
|
58
|
-
@nx._dispatchable
|
|
59
|
-
def number_attracting_components(G):
|
|
60
|
-
"""Returns the number of attracting components in `G`.
|
|
61
|
-
|
|
62
|
-
Parameters
|
|
63
|
-
----------
|
|
64
|
-
G : DiGraph, MultiDiGraph
|
|
65
|
-
The graph to be analyzed.
|
|
66
|
-
|
|
67
|
-
Returns
|
|
68
|
-
-------
|
|
69
|
-
n : int
|
|
70
|
-
The number of attracting components in G.
|
|
71
|
-
|
|
72
|
-
Raises
|
|
73
|
-
------
|
|
74
|
-
NetworkXNotImplemented
|
|
75
|
-
If the input graph is undirected.
|
|
76
|
-
|
|
77
|
-
See Also
|
|
78
|
-
--------
|
|
79
|
-
attracting_components
|
|
80
|
-
is_attracting_component
|
|
81
|
-
|
|
82
|
-
"""
|
|
83
|
-
return sum(1 for ac in attracting_components(G))
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@not_implemented_for("undirected")
|
|
87
|
-
@nx._dispatchable
|
|
88
|
-
def is_attracting_component(G):
|
|
89
|
-
"""Returns True if `G` consists of a single attracting component.
|
|
90
|
-
|
|
91
|
-
Parameters
|
|
92
|
-
----------
|
|
93
|
-
G : DiGraph, MultiDiGraph
|
|
94
|
-
The graph to be analyzed.
|
|
95
|
-
|
|
96
|
-
Returns
|
|
97
|
-
-------
|
|
98
|
-
attracting : bool
|
|
99
|
-
True if `G` has a single attracting component. Otherwise, False.
|
|
100
|
-
|
|
101
|
-
Raises
|
|
102
|
-
------
|
|
103
|
-
NetworkXNotImplemented
|
|
104
|
-
If the input graph is undirected.
|
|
105
|
-
|
|
106
|
-
See Also
|
|
107
|
-
--------
|
|
108
|
-
attracting_components
|
|
109
|
-
number_attracting_components
|
|
110
|
-
|
|
111
|
-
"""
|
|
112
|
-
ac = list(attracting_components(G))
|
|
113
|
-
if len(ac) == 1:
|
|
114
|
-
return len(ac[0]) == len(G)
|
|
115
|
-
return False
|