okstra 0.130.4 → 0.131.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1722 -98
- 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,361 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Subraph centrality and communicability betweenness.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import networkx as nx
|
|
6
|
-
from networkx.utils import not_implemented_for
|
|
7
|
-
|
|
8
|
-
__all__ = [
|
|
9
|
-
"subgraph_centrality_exp",
|
|
10
|
-
"subgraph_centrality",
|
|
11
|
-
"communicability_betweenness_centrality",
|
|
12
|
-
"estrada_index",
|
|
13
|
-
]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@not_implemented_for("directed")
|
|
17
|
-
@not_implemented_for("multigraph")
|
|
18
|
-
@nx._dispatchable
|
|
19
|
-
def subgraph_centrality_exp(G, *, normalized=False):
|
|
20
|
-
r"""Returns the subgraph centrality for each node of G.
|
|
21
|
-
|
|
22
|
-
Subgraph centrality of a node `n` is the sum of weighted closed
|
|
23
|
-
walks of all lengths starting and ending at node `n`. The weights
|
|
24
|
-
decrease with path length. Each closed walk is associated with a
|
|
25
|
-
connected subgraph ([1]_).
|
|
26
|
-
|
|
27
|
-
Parameters
|
|
28
|
-
----------
|
|
29
|
-
G: graph
|
|
30
|
-
normalized : bool
|
|
31
|
-
If True, normalize the centrality values using the largest eigenvalue of the
|
|
32
|
-
adjacency matrix so that the centrality values are generally between 0 and 1.
|
|
33
|
-
|
|
34
|
-
Returns
|
|
35
|
-
-------
|
|
36
|
-
nodes:dictionary
|
|
37
|
-
Dictionary of nodes with subgraph centrality as the value.
|
|
38
|
-
|
|
39
|
-
Raises
|
|
40
|
-
------
|
|
41
|
-
NetworkXError
|
|
42
|
-
If the graph is not undirected and simple.
|
|
43
|
-
|
|
44
|
-
See Also
|
|
45
|
-
--------
|
|
46
|
-
subgraph_centrality:
|
|
47
|
-
Alternative algorithm of the subgraph centrality for each node of G.
|
|
48
|
-
|
|
49
|
-
Notes
|
|
50
|
-
-----
|
|
51
|
-
This version of the algorithm exponentiates the adjacency matrix.
|
|
52
|
-
|
|
53
|
-
The subgraph centrality of a node `u` in G can be found using
|
|
54
|
-
the matrix exponential of the adjacency matrix of G [1]_,
|
|
55
|
-
|
|
56
|
-
.. math::
|
|
57
|
-
|
|
58
|
-
SC(u)=(e^A)_{uu} .
|
|
59
|
-
|
|
60
|
-
Examples
|
|
61
|
-
--------
|
|
62
|
-
(Example from [1]_)
|
|
63
|
-
|
|
64
|
-
>>> G = nx.Graph(
|
|
65
|
-
... [
|
|
66
|
-
... (1, 2),
|
|
67
|
-
... (1, 5),
|
|
68
|
-
... (1, 8),
|
|
69
|
-
... (2, 3),
|
|
70
|
-
... (2, 8),
|
|
71
|
-
... (3, 4),
|
|
72
|
-
... (3, 6),
|
|
73
|
-
... (4, 5),
|
|
74
|
-
... (4, 7),
|
|
75
|
-
... (5, 6),
|
|
76
|
-
... (6, 7),
|
|
77
|
-
... (7, 8),
|
|
78
|
-
... ]
|
|
79
|
-
... )
|
|
80
|
-
>>> sc = nx.subgraph_centrality_exp(G)
|
|
81
|
-
>>> print([f"{node} {sc[node]:0.2f}" for node in sorted(sc)])
|
|
82
|
-
['1 3.90', '2 3.90', '3 3.64', '4 3.71', '5 3.64', '6 3.71', '7 3.64', '8 3.90']
|
|
83
|
-
>>> sc = nx.subgraph_centrality(G, normalized=True)
|
|
84
|
-
>>> print([f"{node} {sc[node]:0.3f}" for node in sorted(sc)])
|
|
85
|
-
['1 0.194', '2 0.194', '3 0.181', '4 0.184', '5 0.181', '6 0.184', '7 0.181', '8 0.194']
|
|
86
|
-
|
|
87
|
-
References
|
|
88
|
-
----------
|
|
89
|
-
.. [1] Ernesto Estrada, Juan A. Rodriguez-Velazquez,
|
|
90
|
-
"Subgraph centrality in complex networks",
|
|
91
|
-
Physical Review E 71, 056103 (2005).
|
|
92
|
-
https://arxiv.org/abs/cond-mat/0504730
|
|
93
|
-
|
|
94
|
-
"""
|
|
95
|
-
# alternative implementation that calculates the matrix exponential
|
|
96
|
-
import scipy as sp
|
|
97
|
-
|
|
98
|
-
nodelist = list(G) # ordering of nodes in matrix
|
|
99
|
-
A = nx.to_numpy_array(G, nodelist)
|
|
100
|
-
# convert to 0-1 matrix
|
|
101
|
-
A[A != 0.0] = 1
|
|
102
|
-
expA = sp.linalg.expm(A)
|
|
103
|
-
values = map(float, expA.diagonal())
|
|
104
|
-
if normalized:
|
|
105
|
-
values = values / values.max()
|
|
106
|
-
# convert diagonal to dictionary keyed by node
|
|
107
|
-
sc = dict(zip(nodelist, values))
|
|
108
|
-
return sc
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
@not_implemented_for("directed")
|
|
112
|
-
@not_implemented_for("multigraph")
|
|
113
|
-
@nx._dispatchable
|
|
114
|
-
def subgraph_centrality(G, *, normalized=False):
|
|
115
|
-
r"""Returns subgraph centrality for each node in G.
|
|
116
|
-
|
|
117
|
-
Subgraph centrality of a node `n` is the sum of weighted closed
|
|
118
|
-
walks of all lengths starting and ending at node `n`. The weights
|
|
119
|
-
decrease with path length. Each closed walk is associated with a
|
|
120
|
-
connected subgraph ([1]_).
|
|
121
|
-
|
|
122
|
-
Parameters
|
|
123
|
-
----------
|
|
124
|
-
G: Graph
|
|
125
|
-
normalized : bool
|
|
126
|
-
If True, normalize the centrality values using the largest eigenvalue of the
|
|
127
|
-
adjacency matrix so that the centrality values are generally between 0 and 1.
|
|
128
|
-
|
|
129
|
-
Returns
|
|
130
|
-
-------
|
|
131
|
-
nodes : dictionary
|
|
132
|
-
Dictionary of nodes with subgraph centrality as the value.
|
|
133
|
-
|
|
134
|
-
Raises
|
|
135
|
-
------
|
|
136
|
-
NetworkXError
|
|
137
|
-
If the graph is not undirected and simple.
|
|
138
|
-
|
|
139
|
-
See Also
|
|
140
|
-
--------
|
|
141
|
-
subgraph_centrality_exp:
|
|
142
|
-
Alternative algorithm of the subgraph centrality for each node of G.
|
|
143
|
-
|
|
144
|
-
Notes
|
|
145
|
-
-----
|
|
146
|
-
This version of the algorithm computes eigenvalues and eigenvectors
|
|
147
|
-
of the adjacency matrix.
|
|
148
|
-
|
|
149
|
-
Subgraph centrality of a node `u` in G can be found using
|
|
150
|
-
a spectral decomposition of the adjacency matrix [1]_,
|
|
151
|
-
|
|
152
|
-
.. math::
|
|
153
|
-
|
|
154
|
-
SC(u)=\sum_{j=1}^{N}(v_{j}^{u})^2 e^{\lambda_{j}},
|
|
155
|
-
|
|
156
|
-
where `v_j` is an eigenvector of the adjacency matrix `A` of G
|
|
157
|
-
corresponding to the eigenvalue `\lambda_j`.
|
|
158
|
-
|
|
159
|
-
Examples
|
|
160
|
-
--------
|
|
161
|
-
(Example from [1]_)
|
|
162
|
-
|
|
163
|
-
>>> G = nx.Graph(
|
|
164
|
-
... [
|
|
165
|
-
... (1, 2),
|
|
166
|
-
... (1, 5),
|
|
167
|
-
... (1, 8),
|
|
168
|
-
... (2, 3),
|
|
169
|
-
... (2, 8),
|
|
170
|
-
... (3, 4),
|
|
171
|
-
... (3, 6),
|
|
172
|
-
... (4, 5),
|
|
173
|
-
... (4, 7),
|
|
174
|
-
... (5, 6),
|
|
175
|
-
... (6, 7),
|
|
176
|
-
... (7, 8),
|
|
177
|
-
... ]
|
|
178
|
-
... )
|
|
179
|
-
>>> sc = nx.subgraph_centrality(G)
|
|
180
|
-
>>> print([f"{node} {sc[node]:0.2f}" for node in sorted(sc)])
|
|
181
|
-
['1 3.90', '2 3.90', '3 3.64', '4 3.71', '5 3.64', '6 3.71', '7 3.64', '8 3.90']
|
|
182
|
-
>>> sc = nx.subgraph_centrality(G, normalized=True)
|
|
183
|
-
>>> print([f"{node} {sc[node]:0.3f}" for node in sorted(sc)])
|
|
184
|
-
['1 0.194', '2 0.194', '3 0.181', '4 0.184', '5 0.181', '6 0.184', '7 0.181', '8 0.194']
|
|
185
|
-
|
|
186
|
-
References
|
|
187
|
-
----------
|
|
188
|
-
.. [1] Ernesto Estrada, Juan A. Rodriguez-Velazquez,
|
|
189
|
-
"Subgraph centrality in complex networks",
|
|
190
|
-
Physical Review E 71, 056103 (2005).
|
|
191
|
-
https://arxiv.org/abs/cond-mat/0504730
|
|
192
|
-
|
|
193
|
-
"""
|
|
194
|
-
import numpy as np
|
|
195
|
-
|
|
196
|
-
nodelist = list(G) # ordering of nodes in matrix
|
|
197
|
-
A = nx.to_numpy_array(G, nodelist)
|
|
198
|
-
# convert to 0-1 matrix
|
|
199
|
-
A[np.nonzero(A)] = 1
|
|
200
|
-
w, v = np.linalg.eigh(A)
|
|
201
|
-
vsquare = np.array(v) ** 2
|
|
202
|
-
if normalized:
|
|
203
|
-
expw = np.exp(w - w.max())
|
|
204
|
-
else:
|
|
205
|
-
expw = np.exp(w)
|
|
206
|
-
xg = vsquare @ expw
|
|
207
|
-
# convert vector dictionary keyed by node
|
|
208
|
-
sc = dict(zip(nodelist, map(float, xg)))
|
|
209
|
-
return sc
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
@not_implemented_for("directed")
|
|
213
|
-
@not_implemented_for("multigraph")
|
|
214
|
-
@nx._dispatchable
|
|
215
|
-
def communicability_betweenness_centrality(G):
|
|
216
|
-
r"""Returns subgraph communicability for all pairs of nodes in G.
|
|
217
|
-
|
|
218
|
-
Communicability betweenness measure makes use of the number of walks
|
|
219
|
-
connecting every pair of nodes as the basis of a betweenness centrality
|
|
220
|
-
measure.
|
|
221
|
-
|
|
222
|
-
Parameters
|
|
223
|
-
----------
|
|
224
|
-
G: graph
|
|
225
|
-
|
|
226
|
-
Returns
|
|
227
|
-
-------
|
|
228
|
-
nodes : dictionary
|
|
229
|
-
Dictionary of nodes with communicability betweenness as the value.
|
|
230
|
-
|
|
231
|
-
Raises
|
|
232
|
-
------
|
|
233
|
-
NetworkXError
|
|
234
|
-
If the graph is not undirected and simple.
|
|
235
|
-
|
|
236
|
-
Notes
|
|
237
|
-
-----
|
|
238
|
-
Let `G=(V,E)` be a simple undirected graph with `n` nodes and `m` edges,
|
|
239
|
-
and `A` denote the adjacency matrix of `G`.
|
|
240
|
-
|
|
241
|
-
Let `G(r)=(V,E(r))` be the graph resulting from
|
|
242
|
-
removing all edges connected to node `r` but not the node itself.
|
|
243
|
-
|
|
244
|
-
The adjacency matrix for `G(r)` is `A+E(r)`, where `E(r)` has nonzeros
|
|
245
|
-
only in row and column `r`.
|
|
246
|
-
|
|
247
|
-
The subraph betweenness of a node `r` is [1]_
|
|
248
|
-
|
|
249
|
-
.. math::
|
|
250
|
-
|
|
251
|
-
\omega_{r} = \frac{1}{C}\sum_{p}\sum_{q}\frac{G_{prq}}{G_{pq}},
|
|
252
|
-
p\neq q, q\neq r,
|
|
253
|
-
|
|
254
|
-
where
|
|
255
|
-
`G_{prq}=(e^{A}_{pq} - (e^{A+E(r)})_{pq}` is the number of walks
|
|
256
|
-
involving node r,
|
|
257
|
-
`G_{pq}=(e^{A})_{pq}` is the number of closed walks starting
|
|
258
|
-
at node `p` and ending at node `q`,
|
|
259
|
-
and `C=(n-1)^{2}-(n-1)` is a normalization factor equal to the
|
|
260
|
-
number of terms in the sum.
|
|
261
|
-
|
|
262
|
-
The resulting `\omega_{r}` takes values between zero and one.
|
|
263
|
-
The lower bound cannot be attained for a connected
|
|
264
|
-
graph, and the upper bound is attained in the star graph.
|
|
265
|
-
|
|
266
|
-
References
|
|
267
|
-
----------
|
|
268
|
-
.. [1] Ernesto Estrada, Desmond J. Higham, Naomichi Hatano,
|
|
269
|
-
"Communicability Betweenness in Complex Networks"
|
|
270
|
-
Physica A 388 (2009) 764-774.
|
|
271
|
-
https://arxiv.org/abs/0905.4102
|
|
272
|
-
|
|
273
|
-
Examples
|
|
274
|
-
--------
|
|
275
|
-
>>> G = nx.Graph([(0, 1), (1, 2), (1, 5), (5, 4), (2, 4), (2, 3), (4, 3), (3, 6)])
|
|
276
|
-
>>> cbc = nx.communicability_betweenness_centrality(G)
|
|
277
|
-
>>> print([f"{node} {cbc[node]:0.2f}" for node in sorted(cbc)])
|
|
278
|
-
['0 0.03', '1 0.45', '2 0.51', '3 0.45', '4 0.40', '5 0.19', '6 0.03']
|
|
279
|
-
"""
|
|
280
|
-
import numpy as np
|
|
281
|
-
import scipy as sp
|
|
282
|
-
|
|
283
|
-
nodelist = list(G) # ordering of nodes in matrix
|
|
284
|
-
n = len(nodelist)
|
|
285
|
-
A = nx.to_numpy_array(G, nodelist)
|
|
286
|
-
# convert to 0-1 matrix
|
|
287
|
-
A[np.nonzero(A)] = 1
|
|
288
|
-
expA = sp.linalg.expm(A)
|
|
289
|
-
mapping = dict(zip(nodelist, range(n)))
|
|
290
|
-
cbc = {}
|
|
291
|
-
for v in G:
|
|
292
|
-
# remove row and col of node v
|
|
293
|
-
i = mapping[v]
|
|
294
|
-
row = A[i, :].copy()
|
|
295
|
-
col = A[:, i].copy()
|
|
296
|
-
A[i, :] = 0
|
|
297
|
-
A[:, i] = 0
|
|
298
|
-
B = (expA - sp.linalg.expm(A)) / expA
|
|
299
|
-
# sum with row/col of node v and diag set to zero
|
|
300
|
-
B[i, :] = 0
|
|
301
|
-
B[:, i] = 0
|
|
302
|
-
B -= np.diag(np.diag(B))
|
|
303
|
-
cbc[v] = float(B.sum())
|
|
304
|
-
# put row and col back
|
|
305
|
-
A[i, :] = row
|
|
306
|
-
A[:, i] = col
|
|
307
|
-
# rescale when more than two nodes
|
|
308
|
-
order = len(cbc)
|
|
309
|
-
if order > 2:
|
|
310
|
-
scale = 1.0 / ((order - 1.0) ** 2 - (order - 1.0))
|
|
311
|
-
cbc = {node: value * scale for node, value in cbc.items()}
|
|
312
|
-
return cbc
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
@nx._dispatchable
|
|
316
|
-
def estrada_index(G):
|
|
317
|
-
r"""Returns the Estrada index of a the graph G.
|
|
318
|
-
|
|
319
|
-
The Estrada Index is a topological index of folding or 3D "compactness" ([1]_).
|
|
320
|
-
|
|
321
|
-
Parameters
|
|
322
|
-
----------
|
|
323
|
-
G: graph
|
|
324
|
-
|
|
325
|
-
Returns
|
|
326
|
-
-------
|
|
327
|
-
estrada index: float
|
|
328
|
-
|
|
329
|
-
Raises
|
|
330
|
-
------
|
|
331
|
-
NetworkXError
|
|
332
|
-
If the graph is not undirected and simple.
|
|
333
|
-
|
|
334
|
-
Notes
|
|
335
|
-
-----
|
|
336
|
-
Let `G=(V,E)` be a simple undirected graph with `n` nodes and let
|
|
337
|
-
`\lambda_{1}\leq\lambda_{2}\leq\cdots\lambda_{n}`
|
|
338
|
-
be a non-increasing ordering of the eigenvalues of its adjacency
|
|
339
|
-
matrix `A`. The Estrada index is ([1]_, [2]_)
|
|
340
|
-
|
|
341
|
-
.. math::
|
|
342
|
-
EE(G)=\sum_{j=1}^n e^{\lambda _j}.
|
|
343
|
-
|
|
344
|
-
References
|
|
345
|
-
----------
|
|
346
|
-
.. [1] E. Estrada, "Characterization of 3D molecular structure",
|
|
347
|
-
Chem. Phys. Lett. 319, 713 (2000).
|
|
348
|
-
https://doi.org/10.1016/S0009-2614(00)00158-5
|
|
349
|
-
.. [2] José Antonio de la Peñaa, Ivan Gutman, Juan Rada,
|
|
350
|
-
"Estimating the Estrada index",
|
|
351
|
-
Linear Algebra and its Applications. 427, 1 (2007).
|
|
352
|
-
https://doi.org/10.1016/j.laa.2007.06.020
|
|
353
|
-
|
|
354
|
-
Examples
|
|
355
|
-
--------
|
|
356
|
-
>>> G = nx.Graph([(0, 1), (1, 2), (1, 5), (5, 4), (2, 4), (2, 3), (4, 3), (3, 6)])
|
|
357
|
-
>>> ei = nx.estrada_index(G)
|
|
358
|
-
>>> print(f"{ei:0.5}")
|
|
359
|
-
20.55
|
|
360
|
-
"""
|
|
361
|
-
return sum(subgraph_centrality(G).values())
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
"""Trophic levels"""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
from networkx.utils import not_implemented_for
|
|
5
|
-
|
|
6
|
-
__all__ = ["trophic_levels", "trophic_differences", "trophic_incoherence_parameter"]
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@not_implemented_for("undirected")
|
|
10
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
11
|
-
def trophic_levels(G, weight="weight"):
|
|
12
|
-
r"""Compute the trophic levels of nodes.
|
|
13
|
-
|
|
14
|
-
The trophic level of a node $i$ is
|
|
15
|
-
|
|
16
|
-
.. math::
|
|
17
|
-
|
|
18
|
-
s_i = 1 + \frac{1}{k^{in}_i} \sum_{j} a_{ij} s_j
|
|
19
|
-
|
|
20
|
-
where $k^{in}_i$ is the in-degree of i
|
|
21
|
-
|
|
22
|
-
.. math::
|
|
23
|
-
|
|
24
|
-
k^{in}_i = \sum_{j} a_{ij}
|
|
25
|
-
|
|
26
|
-
and nodes with $k^{in}_i = 0$ have $s_i = 1$ by convention.
|
|
27
|
-
|
|
28
|
-
These are calculated using the method outlined in Levine [1]_.
|
|
29
|
-
|
|
30
|
-
Parameters
|
|
31
|
-
----------
|
|
32
|
-
G : DiGraph
|
|
33
|
-
A directed networkx graph
|
|
34
|
-
|
|
35
|
-
Returns
|
|
36
|
-
-------
|
|
37
|
-
nodes : dict
|
|
38
|
-
Dictionary of nodes with trophic level as the value.
|
|
39
|
-
|
|
40
|
-
References
|
|
41
|
-
----------
|
|
42
|
-
.. [1] Stephen Levine (1980) J. theor. Biol. 83, 195-207
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
basal_nodes = [n for n, deg in G.in_degree if deg == 0]
|
|
46
|
-
if not basal_nodes:
|
|
47
|
-
raise nx.NetworkXError(
|
|
48
|
-
"This graph has no basal nodes (nodes with no incoming edges)."
|
|
49
|
-
"Trophic levels are not defined without at least one basal node."
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
reachable_nodes = {
|
|
53
|
-
node for layer in nx.bfs_layers(G, sources=basal_nodes) for node in layer
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if len(reachable_nodes) != len(G.nodes):
|
|
57
|
-
raise nx.NetworkXError(
|
|
58
|
-
"Trophic levels are only defined for graphs where every node has a path "
|
|
59
|
-
"from a basal node (basal nodes are nodes with no incoming edges)."
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
import numpy as np
|
|
63
|
-
|
|
64
|
-
# find adjacency matrix
|
|
65
|
-
a = nx.adjacency_matrix(G, weight=weight).T.toarray()
|
|
66
|
-
|
|
67
|
-
# drop rows/columns where in-degree is zero
|
|
68
|
-
rowsum = np.sum(a, axis=1)
|
|
69
|
-
p = a[rowsum != 0][:, rowsum != 0]
|
|
70
|
-
# normalise so sum of in-degree weights is 1 along each row
|
|
71
|
-
p = p / rowsum[rowsum != 0][:, np.newaxis]
|
|
72
|
-
|
|
73
|
-
# calculate trophic levels
|
|
74
|
-
nn = p.shape[0]
|
|
75
|
-
i = np.eye(nn)
|
|
76
|
-
try:
|
|
77
|
-
n = np.linalg.inv(i - p)
|
|
78
|
-
except np.linalg.LinAlgError as err:
|
|
79
|
-
# LinAlgError is raised when there is a non-basal node
|
|
80
|
-
msg = (
|
|
81
|
-
"Trophic levels are only defined for graphs where every "
|
|
82
|
-
+ "node has a path from a basal node (basal nodes are nodes "
|
|
83
|
-
+ "with no incoming edges)."
|
|
84
|
-
)
|
|
85
|
-
raise nx.NetworkXError(msg) from err
|
|
86
|
-
y = n.sum(axis=1) + 1
|
|
87
|
-
|
|
88
|
-
levels = {}
|
|
89
|
-
|
|
90
|
-
# all nodes with in-degree zero have trophic level == 1
|
|
91
|
-
zero_node_ids = (node_id for node_id, degree in G.in_degree if degree == 0)
|
|
92
|
-
for node_id in zero_node_ids:
|
|
93
|
-
levels[node_id] = 1
|
|
94
|
-
|
|
95
|
-
# all other nodes have levels as calculated
|
|
96
|
-
nonzero_node_ids = (node_id for node_id, degree in G.in_degree if degree != 0)
|
|
97
|
-
for i, node_id in enumerate(nonzero_node_ids):
|
|
98
|
-
levels[node_id] = y.item(i)
|
|
99
|
-
|
|
100
|
-
return levels
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@not_implemented_for("undirected")
|
|
104
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
105
|
-
def trophic_differences(G, weight="weight"):
|
|
106
|
-
r"""Compute the trophic differences of the edges of a directed graph.
|
|
107
|
-
|
|
108
|
-
The trophic difference $x_ij$ for each edge is defined in Johnson et al.
|
|
109
|
-
[1]_ as:
|
|
110
|
-
|
|
111
|
-
.. math::
|
|
112
|
-
x_ij = s_j - s_i
|
|
113
|
-
|
|
114
|
-
Where $s_i$ is the trophic level of node $i$.
|
|
115
|
-
|
|
116
|
-
Parameters
|
|
117
|
-
----------
|
|
118
|
-
G : DiGraph
|
|
119
|
-
A directed networkx graph
|
|
120
|
-
|
|
121
|
-
Returns
|
|
122
|
-
-------
|
|
123
|
-
diffs : dict
|
|
124
|
-
Dictionary of edges with trophic differences as the value.
|
|
125
|
-
|
|
126
|
-
References
|
|
127
|
-
----------
|
|
128
|
-
.. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A.
|
|
129
|
-
Munoz (2014) PNAS "Trophic coherence determines food-web stability"
|
|
130
|
-
"""
|
|
131
|
-
levels = trophic_levels(G, weight=weight)
|
|
132
|
-
diffs = {}
|
|
133
|
-
for u, v in G.edges:
|
|
134
|
-
diffs[(u, v)] = levels[v] - levels[u]
|
|
135
|
-
return diffs
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
@not_implemented_for("undirected")
|
|
139
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
140
|
-
def trophic_incoherence_parameter(G, weight="weight", cannibalism=False):
|
|
141
|
-
r"""Compute the trophic incoherence parameter of a graph.
|
|
142
|
-
|
|
143
|
-
Trophic coherence is defined as the homogeneity of the distribution of
|
|
144
|
-
trophic distances: the more similar, the more coherent. This is measured by
|
|
145
|
-
the standard deviation of the trophic differences and referred to as the
|
|
146
|
-
trophic incoherence parameter $q$ by [1].
|
|
147
|
-
|
|
148
|
-
Parameters
|
|
149
|
-
----------
|
|
150
|
-
G : DiGraph
|
|
151
|
-
A directed networkx graph
|
|
152
|
-
|
|
153
|
-
cannibalism: Boolean
|
|
154
|
-
If set to False, self edges are not considered in the calculation
|
|
155
|
-
|
|
156
|
-
Returns
|
|
157
|
-
-------
|
|
158
|
-
trophic_incoherence_parameter : float
|
|
159
|
-
The trophic coherence of a graph
|
|
160
|
-
|
|
161
|
-
References
|
|
162
|
-
----------
|
|
163
|
-
.. [1] Samuel Johnson, Virginia Dominguez-Garcia, Luca Donetti, Miguel A.
|
|
164
|
-
Munoz (2014) PNAS "Trophic coherence determines food-web stability"
|
|
165
|
-
"""
|
|
166
|
-
import numpy as np
|
|
167
|
-
|
|
168
|
-
if cannibalism:
|
|
169
|
-
diffs = trophic_differences(G, weight=weight)
|
|
170
|
-
else:
|
|
171
|
-
# If no cannibalism, remove self-edges
|
|
172
|
-
self_loops = list(nx.selfloop_edges(G))
|
|
173
|
-
if self_loops:
|
|
174
|
-
# Make a copy so we do not change G's edges in memory
|
|
175
|
-
G_2 = G.copy()
|
|
176
|
-
G_2.remove_edges_from(self_loops)
|
|
177
|
-
else:
|
|
178
|
-
# Avoid copy otherwise
|
|
179
|
-
G_2 = G
|
|
180
|
-
diffs = trophic_differences(G_2, weight=weight)
|
|
181
|
-
return float(np.std(list(diffs.values())))
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"""Algorithm to select influential nodes in a graph using VoteRank."""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = ["voterank"]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@nx._dispatchable
|
|
9
|
-
def voterank(G, number_of_nodes=None):
|
|
10
|
-
"""Select a list of influential nodes in a graph using VoteRank algorithm
|
|
11
|
-
|
|
12
|
-
VoteRank [1]_ computes a ranking of the nodes in a graph G based on a
|
|
13
|
-
voting scheme. With VoteRank, all nodes vote for each of its in-neighbors
|
|
14
|
-
and the node with the highest votes is elected iteratively. The voting
|
|
15
|
-
ability of out-neighbors of elected nodes is decreased in subsequent turns.
|
|
16
|
-
|
|
17
|
-
Parameters
|
|
18
|
-
----------
|
|
19
|
-
G : graph
|
|
20
|
-
A NetworkX graph.
|
|
21
|
-
|
|
22
|
-
number_of_nodes : integer, optional
|
|
23
|
-
Number of ranked nodes to extract (default all nodes).
|
|
24
|
-
|
|
25
|
-
Returns
|
|
26
|
-
-------
|
|
27
|
-
voterank : list
|
|
28
|
-
Ordered list of computed seeds.
|
|
29
|
-
Only nodes with positive number of votes are returned.
|
|
30
|
-
|
|
31
|
-
Examples
|
|
32
|
-
--------
|
|
33
|
-
>>> G = nx.Graph([(0, 1), (0, 2), (0, 3), (1, 4)])
|
|
34
|
-
>>> nx.voterank(G)
|
|
35
|
-
[0, 1]
|
|
36
|
-
|
|
37
|
-
The algorithm can be used both for undirected and directed graphs.
|
|
38
|
-
However, the directed version is different in two ways:
|
|
39
|
-
(i) nodes only vote for their in-neighbors and
|
|
40
|
-
(ii) only the voting ability of elected node and its out-neighbors are updated:
|
|
41
|
-
|
|
42
|
-
>>> G = nx.DiGraph([(0, 1), (2, 1), (2, 3), (3, 4)])
|
|
43
|
-
>>> nx.voterank(G)
|
|
44
|
-
[2, 3]
|
|
45
|
-
|
|
46
|
-
Notes
|
|
47
|
-
-----
|
|
48
|
-
Each edge is treated independently in case of multigraphs.
|
|
49
|
-
|
|
50
|
-
References
|
|
51
|
-
----------
|
|
52
|
-
.. [1] Zhang, J.-X. et al. (2016).
|
|
53
|
-
Identifying a set of influential spreaders in complex networks.
|
|
54
|
-
Sci. Rep. 6, 27823; doi: 10.1038/srep27823.
|
|
55
|
-
"""
|
|
56
|
-
influential_nodes = []
|
|
57
|
-
vote_rank = {}
|
|
58
|
-
if len(G) == 0:
|
|
59
|
-
return influential_nodes
|
|
60
|
-
if number_of_nodes is None or number_of_nodes > len(G):
|
|
61
|
-
number_of_nodes = len(G)
|
|
62
|
-
if G.is_directed():
|
|
63
|
-
# For directed graphs compute average out-degree
|
|
64
|
-
avgDegree = sum(deg for _, deg in G.out_degree()) / len(G)
|
|
65
|
-
else:
|
|
66
|
-
# For undirected graphs compute average degree
|
|
67
|
-
avgDegree = sum(deg for _, deg in G.degree()) / len(G)
|
|
68
|
-
# step 1 - initiate all nodes to (0,1) (score, voting ability)
|
|
69
|
-
for n in G.nodes():
|
|
70
|
-
vote_rank[n] = [0, 1]
|
|
71
|
-
# Repeat steps 1b to 4 until num_seeds are elected.
|
|
72
|
-
for _ in range(number_of_nodes):
|
|
73
|
-
# step 1b - reset rank
|
|
74
|
-
for n in G.nodes():
|
|
75
|
-
vote_rank[n][0] = 0
|
|
76
|
-
# step 2 - vote
|
|
77
|
-
for n, nbr in G.edges():
|
|
78
|
-
# In directed graphs nodes only vote for their in-neighbors
|
|
79
|
-
vote_rank[n][0] += vote_rank[nbr][1]
|
|
80
|
-
if not G.is_directed():
|
|
81
|
-
vote_rank[nbr][0] += vote_rank[n][1]
|
|
82
|
-
for n in influential_nodes:
|
|
83
|
-
vote_rank[n][0] = 0
|
|
84
|
-
# step 3 - select top node
|
|
85
|
-
n = max(G.nodes, key=lambda x: vote_rank[x][0])
|
|
86
|
-
if vote_rank[n][0] == 0:
|
|
87
|
-
return influential_nodes
|
|
88
|
-
influential_nodes.append(n)
|
|
89
|
-
# weaken the selected node
|
|
90
|
-
vote_rank[n] = [0, 0]
|
|
91
|
-
# step 4 - update voterank properties
|
|
92
|
-
for _, nbr in G.edges(n):
|
|
93
|
-
vote_rank[nbr][1] -= 1 / avgDegree
|
|
94
|
-
vote_rank[nbr][1] = max(vote_rank[nbr][1], 0)
|
|
95
|
-
return influential_nodes
|