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,625 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Shortest path algorithms for unweighted graphs.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import operator
|
|
6
|
-
|
|
7
|
-
import networkx as nx
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"bidirectional_shortest_path",
|
|
11
|
-
"single_source_shortest_path",
|
|
12
|
-
"single_source_shortest_path_length",
|
|
13
|
-
"single_target_shortest_path",
|
|
14
|
-
"single_target_shortest_path_length",
|
|
15
|
-
"all_pairs_shortest_path",
|
|
16
|
-
"all_pairs_shortest_path_length",
|
|
17
|
-
"predecessor",
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@nx._dispatchable
|
|
22
|
-
def single_source_shortest_path_length(G, source, cutoff=None):
|
|
23
|
-
"""Compute the shortest path lengths from `source` to all reachable nodes in `G`.
|
|
24
|
-
|
|
25
|
-
Parameters
|
|
26
|
-
----------
|
|
27
|
-
G : NetworkX graph
|
|
28
|
-
|
|
29
|
-
source : node
|
|
30
|
-
Starting node for path
|
|
31
|
-
|
|
32
|
-
cutoff : integer, optional
|
|
33
|
-
Depth to stop the search. Only target nodes where the shortest path to
|
|
34
|
-
this node from the source node contains <= ``cutoff + 1`` nodes will be
|
|
35
|
-
included in the returned results.
|
|
36
|
-
|
|
37
|
-
Returns
|
|
38
|
-
-------
|
|
39
|
-
lengths : dict
|
|
40
|
-
Dict keyed by node to shortest path length from source node.
|
|
41
|
-
|
|
42
|
-
Examples
|
|
43
|
-
--------
|
|
44
|
-
>>> G = nx.path_graph(5)
|
|
45
|
-
>>> length = nx.single_source_shortest_path_length(G, 0)
|
|
46
|
-
>>> length[4]
|
|
47
|
-
4
|
|
48
|
-
>>> for node in sorted(length):
|
|
49
|
-
... print(f"{node}: {length[node]}")
|
|
50
|
-
0: 0
|
|
51
|
-
1: 1
|
|
52
|
-
2: 2
|
|
53
|
-
3: 3
|
|
54
|
-
4: 4
|
|
55
|
-
|
|
56
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
57
|
-
argument:
|
|
58
|
-
|
|
59
|
-
>>> length = nx.single_source_shortest_path_length(G, 0, cutoff=2)
|
|
60
|
-
>>> for node in sorted(length):
|
|
61
|
-
... print(f"{node}: {length[node]}")
|
|
62
|
-
0: 0
|
|
63
|
-
1: 1
|
|
64
|
-
2: 2
|
|
65
|
-
|
|
66
|
-
See Also
|
|
67
|
-
--------
|
|
68
|
-
:any:`shortest_path_length` :
|
|
69
|
-
Shortest path length with specifiable source, target, and weight.
|
|
70
|
-
:any:`single_source_dijkstra_path_length` :
|
|
71
|
-
Shortest weighted path length from source with Dijkstra algorithm.
|
|
72
|
-
:any:`single_source_bellman_ford_path_length` :
|
|
73
|
-
Shortest weighted path length from source with Bellman-Ford algorithm.
|
|
74
|
-
"""
|
|
75
|
-
if source not in G:
|
|
76
|
-
raise nx.NodeNotFound(f"Source {source} is not in G")
|
|
77
|
-
if cutoff is None:
|
|
78
|
-
cutoff = float("inf")
|
|
79
|
-
nextlevel = [source]
|
|
80
|
-
return dict(_single_shortest_path_length(G._adj, nextlevel, cutoff))
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _single_shortest_path_length(adj, firstlevel, cutoff):
|
|
84
|
-
"""Yields (node, level) in a breadth first search
|
|
85
|
-
|
|
86
|
-
Shortest Path Length helper function
|
|
87
|
-
Parameters
|
|
88
|
-
----------
|
|
89
|
-
adj : dict
|
|
90
|
-
Adjacency dict or view
|
|
91
|
-
firstlevel : list
|
|
92
|
-
starting nodes, e.g. [source] or [target]
|
|
93
|
-
cutoff : int or float
|
|
94
|
-
level at which we stop the process
|
|
95
|
-
"""
|
|
96
|
-
seen = set(firstlevel)
|
|
97
|
-
nextlevel = firstlevel
|
|
98
|
-
level = 0
|
|
99
|
-
n = len(adj)
|
|
100
|
-
for v in nextlevel:
|
|
101
|
-
yield (v, level)
|
|
102
|
-
while nextlevel and cutoff > level:
|
|
103
|
-
level += 1
|
|
104
|
-
thislevel = nextlevel
|
|
105
|
-
nextlevel = []
|
|
106
|
-
for v in thislevel:
|
|
107
|
-
for w in adj[v]:
|
|
108
|
-
if w not in seen:
|
|
109
|
-
seen.add(w)
|
|
110
|
-
nextlevel.append(w)
|
|
111
|
-
yield (w, level)
|
|
112
|
-
if len(seen) == n:
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@nx._dispatchable
|
|
117
|
-
def single_target_shortest_path_length(G, target, cutoff=None):
|
|
118
|
-
"""Compute the shortest path lengths to target from all reachable nodes.
|
|
119
|
-
|
|
120
|
-
Parameters
|
|
121
|
-
----------
|
|
122
|
-
G : NetworkX graph
|
|
123
|
-
|
|
124
|
-
target : node
|
|
125
|
-
Target node for path
|
|
126
|
-
|
|
127
|
-
cutoff : integer, optional
|
|
128
|
-
Depth to stop the search. Only source nodes where the shortest path
|
|
129
|
-
from this node to the target node contains <= ``cutoff + 1`` nodes will
|
|
130
|
-
be included in the returned results.
|
|
131
|
-
|
|
132
|
-
Returns
|
|
133
|
-
-------
|
|
134
|
-
lengths : dictionary
|
|
135
|
-
Dictionary, keyed by source, of shortest path lengths.
|
|
136
|
-
|
|
137
|
-
Examples
|
|
138
|
-
--------
|
|
139
|
-
>>> G = nx.path_graph(5, create_using=nx.DiGraph())
|
|
140
|
-
>>> length = nx.single_target_shortest_path_length(G, 4)
|
|
141
|
-
>>> length[0]
|
|
142
|
-
4
|
|
143
|
-
>>> for node in sorted(length):
|
|
144
|
-
... print(f"{node}: {length[node]}")
|
|
145
|
-
0: 4
|
|
146
|
-
1: 3
|
|
147
|
-
2: 2
|
|
148
|
-
3: 1
|
|
149
|
-
4: 0
|
|
150
|
-
|
|
151
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
152
|
-
argument:
|
|
153
|
-
|
|
154
|
-
>>> length = nx.single_target_shortest_path_length(G, 4, cutoff=2)
|
|
155
|
-
>>> for node in sorted(length):
|
|
156
|
-
... print(f"{node}: {length[node]}")
|
|
157
|
-
2: 2
|
|
158
|
-
3: 1
|
|
159
|
-
4: 0
|
|
160
|
-
|
|
161
|
-
See Also
|
|
162
|
-
--------
|
|
163
|
-
single_source_shortest_path_length, shortest_path_length
|
|
164
|
-
"""
|
|
165
|
-
if target not in G:
|
|
166
|
-
raise nx.NodeNotFound(f"Target {target} is not in G")
|
|
167
|
-
if cutoff is None:
|
|
168
|
-
cutoff = float("inf")
|
|
169
|
-
# handle either directed or undirected
|
|
170
|
-
adj = G._pred if G.is_directed() else G._adj
|
|
171
|
-
nextlevel = [target]
|
|
172
|
-
return dict(_single_shortest_path_length(adj, nextlevel, cutoff))
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
@nx._dispatchable
|
|
176
|
-
def all_pairs_shortest_path_length(G, cutoff=None):
|
|
177
|
-
"""Computes the shortest path lengths between all nodes in `G`.
|
|
178
|
-
|
|
179
|
-
Parameters
|
|
180
|
-
----------
|
|
181
|
-
G : NetworkX graph
|
|
182
|
-
|
|
183
|
-
cutoff : integer, optional
|
|
184
|
-
Depth at which to stop the search. Only paths of length at most
|
|
185
|
-
`cutoff` (i.e. paths containing <= ``cutoff + 1`` nodes) are returned.
|
|
186
|
-
|
|
187
|
-
Returns
|
|
188
|
-
-------
|
|
189
|
-
lengths : iterator
|
|
190
|
-
(source, dictionary) iterator with dictionary keyed by target and
|
|
191
|
-
shortest path length as the key value.
|
|
192
|
-
|
|
193
|
-
Notes
|
|
194
|
-
-----
|
|
195
|
-
The iterator returned only has reachable node pairs.
|
|
196
|
-
|
|
197
|
-
Examples
|
|
198
|
-
--------
|
|
199
|
-
>>> G = nx.path_graph(5)
|
|
200
|
-
>>> length = dict(nx.all_pairs_shortest_path_length(G))
|
|
201
|
-
>>> for node in [0, 1, 2, 3, 4]:
|
|
202
|
-
... print(f"1 - {node}: {length[1][node]}")
|
|
203
|
-
1 - 0: 1
|
|
204
|
-
1 - 1: 0
|
|
205
|
-
1 - 2: 1
|
|
206
|
-
1 - 3: 2
|
|
207
|
-
1 - 4: 3
|
|
208
|
-
>>> length[3][2]
|
|
209
|
-
1
|
|
210
|
-
>>> length[2][2]
|
|
211
|
-
0
|
|
212
|
-
|
|
213
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
214
|
-
argument:
|
|
215
|
-
|
|
216
|
-
>>> path_lengths = dict(nx.all_pairs_shortest_path_length(G, cutoff=2))
|
|
217
|
-
>>> path_lengths[1] # node 4 is too far away to appear
|
|
218
|
-
{1: 0, 0: 1, 2: 1, 3: 2}
|
|
219
|
-
"""
|
|
220
|
-
length = single_source_shortest_path_length
|
|
221
|
-
# TODO This can be trivially parallelized.
|
|
222
|
-
for n in G:
|
|
223
|
-
yield (n, length(G, n, cutoff=cutoff))
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
@nx._dispatchable
|
|
227
|
-
def bidirectional_shortest_path(G, source, target):
|
|
228
|
-
"""Returns a list of nodes in a shortest path between source and target.
|
|
229
|
-
|
|
230
|
-
Parameters
|
|
231
|
-
----------
|
|
232
|
-
G : NetworkX graph
|
|
233
|
-
|
|
234
|
-
source : node label
|
|
235
|
-
starting node for path
|
|
236
|
-
|
|
237
|
-
target : node label
|
|
238
|
-
ending node for path
|
|
239
|
-
|
|
240
|
-
Returns
|
|
241
|
-
-------
|
|
242
|
-
path: list
|
|
243
|
-
List of nodes in a path from source to target.
|
|
244
|
-
|
|
245
|
-
Raises
|
|
246
|
-
------
|
|
247
|
-
NetworkXNoPath
|
|
248
|
-
If no path exists between source and target.
|
|
249
|
-
|
|
250
|
-
Examples
|
|
251
|
-
--------
|
|
252
|
-
>>> G = nx.Graph()
|
|
253
|
-
>>> nx.add_path(G, [0, 1, 2, 3, 0, 4, 5, 6, 7, 4])
|
|
254
|
-
>>> nx.bidirectional_shortest_path(G, 2, 6)
|
|
255
|
-
[2, 1, 0, 4, 5, 6]
|
|
256
|
-
|
|
257
|
-
See Also
|
|
258
|
-
--------
|
|
259
|
-
shortest_path
|
|
260
|
-
|
|
261
|
-
Notes
|
|
262
|
-
-----
|
|
263
|
-
This algorithm is used by shortest_path(G, source, target).
|
|
264
|
-
"""
|
|
265
|
-
|
|
266
|
-
if source not in G:
|
|
267
|
-
raise nx.NodeNotFound(f"Source {source} is not in G")
|
|
268
|
-
|
|
269
|
-
if target not in G:
|
|
270
|
-
raise nx.NodeNotFound(f"Target {target} is not in G")
|
|
271
|
-
|
|
272
|
-
# call helper to do the real work
|
|
273
|
-
results = _bidirectional_pred_succ(G, source, target)
|
|
274
|
-
pred, succ, w = results
|
|
275
|
-
|
|
276
|
-
# build path from pred+w+succ
|
|
277
|
-
path = []
|
|
278
|
-
# from source to w
|
|
279
|
-
while w is not None:
|
|
280
|
-
path.append(w)
|
|
281
|
-
w = pred[w]
|
|
282
|
-
path.reverse()
|
|
283
|
-
# from w to target
|
|
284
|
-
w = succ[path[-1]]
|
|
285
|
-
while w is not None:
|
|
286
|
-
path.append(w)
|
|
287
|
-
w = succ[w]
|
|
288
|
-
|
|
289
|
-
return path
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def _bidirectional_pred_succ(G, source, target):
|
|
293
|
-
"""Bidirectional shortest path helper.
|
|
294
|
-
|
|
295
|
-
Returns (pred, succ, w) where
|
|
296
|
-
pred is a dictionary of predecessors from w to the source, and
|
|
297
|
-
succ is a dictionary of successors from w to the target.
|
|
298
|
-
"""
|
|
299
|
-
# does BFS from both source and target and meets in the middle
|
|
300
|
-
if target == source:
|
|
301
|
-
return ({target: None}, {source: None}, source)
|
|
302
|
-
|
|
303
|
-
# handle either directed or undirected
|
|
304
|
-
if G.is_directed():
|
|
305
|
-
Gpred = G.pred
|
|
306
|
-
Gsucc = G.succ
|
|
307
|
-
else:
|
|
308
|
-
Gpred = G.adj
|
|
309
|
-
Gsucc = G.adj
|
|
310
|
-
|
|
311
|
-
# predecessor and successors in search
|
|
312
|
-
pred = {source: None}
|
|
313
|
-
succ = {target: None}
|
|
314
|
-
|
|
315
|
-
# initialize fringes, start with forward
|
|
316
|
-
forward_fringe = [source]
|
|
317
|
-
reverse_fringe = [target]
|
|
318
|
-
|
|
319
|
-
while forward_fringe and reverse_fringe:
|
|
320
|
-
if len(forward_fringe) <= len(reverse_fringe):
|
|
321
|
-
this_level = forward_fringe
|
|
322
|
-
forward_fringe = []
|
|
323
|
-
for v in this_level:
|
|
324
|
-
for w in Gsucc[v]:
|
|
325
|
-
if w not in pred:
|
|
326
|
-
forward_fringe.append(w)
|
|
327
|
-
pred[w] = v
|
|
328
|
-
if w in succ: # path found
|
|
329
|
-
return pred, succ, w
|
|
330
|
-
else:
|
|
331
|
-
this_level = reverse_fringe
|
|
332
|
-
reverse_fringe = []
|
|
333
|
-
for v in this_level:
|
|
334
|
-
for w in Gpred[v]:
|
|
335
|
-
if w not in succ:
|
|
336
|
-
succ[w] = v
|
|
337
|
-
reverse_fringe.append(w)
|
|
338
|
-
if w in pred: # found path
|
|
339
|
-
return pred, succ, w
|
|
340
|
-
|
|
341
|
-
raise nx.NetworkXNoPath(f"No path between {source} and {target}.")
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
@nx._dispatchable
|
|
345
|
-
def single_source_shortest_path(G, source, cutoff=None):
|
|
346
|
-
"""Compute shortest path between source
|
|
347
|
-
and all other nodes reachable from source.
|
|
348
|
-
|
|
349
|
-
Parameters
|
|
350
|
-
----------
|
|
351
|
-
G : NetworkX graph
|
|
352
|
-
|
|
353
|
-
source : node label
|
|
354
|
-
Starting node for path
|
|
355
|
-
|
|
356
|
-
cutoff : integer, optional
|
|
357
|
-
Depth to stop the search. Only target nodes where the shortest path to
|
|
358
|
-
this node from the source node contains <= ``cutoff + 1`` nodes will be
|
|
359
|
-
included in the returned results.
|
|
360
|
-
|
|
361
|
-
Returns
|
|
362
|
-
-------
|
|
363
|
-
paths : dictionary
|
|
364
|
-
Dictionary, keyed by target, of shortest paths.
|
|
365
|
-
|
|
366
|
-
Examples
|
|
367
|
-
--------
|
|
368
|
-
>>> G = nx.path_graph(5)
|
|
369
|
-
>>> nx.single_source_shortest_path(G, 0)
|
|
370
|
-
{0: [0], 1: [0, 1], 2: [0, 1, 2], 3: [0, 1, 2, 3], 4: [0, 1, 2, 3, 4]}
|
|
371
|
-
|
|
372
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
373
|
-
argument:
|
|
374
|
-
|
|
375
|
-
>>> nx.single_source_shortest_path(G, 0, cutoff=2)
|
|
376
|
-
{0: [0], 1: [0, 1], 2: [0, 1, 2]}
|
|
377
|
-
|
|
378
|
-
Notes
|
|
379
|
-
-----
|
|
380
|
-
The shortest path is not necessarily unique. So there can be multiple
|
|
381
|
-
paths between the source and each target node, all of which have the
|
|
382
|
-
same 'shortest' length. For each target node, this function returns
|
|
383
|
-
only one of those paths.
|
|
384
|
-
|
|
385
|
-
See Also
|
|
386
|
-
--------
|
|
387
|
-
shortest_path
|
|
388
|
-
"""
|
|
389
|
-
if source not in G:
|
|
390
|
-
raise nx.NodeNotFound(f"Source {source} not in G")
|
|
391
|
-
if cutoff is None:
|
|
392
|
-
cutoff = float("inf")
|
|
393
|
-
nextlevel = [source] # list of nodes to check at next level
|
|
394
|
-
paths = {source: [source]} # paths dictionary (paths to key from source)
|
|
395
|
-
return dict(_single_shortest_path(G._adj, nextlevel, paths, cutoff, operator.add))
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
def _single_shortest_path(adj, firstlevel, paths, cutoff, join):
|
|
399
|
-
"""Returns shortest paths
|
|
400
|
-
|
|
401
|
-
Shortest Path helper function
|
|
402
|
-
Parameters
|
|
403
|
-
----------
|
|
404
|
-
adj : dict
|
|
405
|
-
Adjacency dict or view
|
|
406
|
-
firstlevel : list
|
|
407
|
-
starting nodes, e.g. [source] or [target]
|
|
408
|
-
paths : dict
|
|
409
|
-
paths for starting nodes, e.g. {source: [source]}
|
|
410
|
-
cutoff : int or float
|
|
411
|
-
level at which we stop the process
|
|
412
|
-
join : function
|
|
413
|
-
function to construct a path from two partial paths. Requires two
|
|
414
|
-
list inputs `p1` and `p2`, and returns a list. Usually returns
|
|
415
|
-
`p1 + p2` (forward from source) or `p2 + p1` (backward from target)
|
|
416
|
-
"""
|
|
417
|
-
level = 0
|
|
418
|
-
nextlevel = firstlevel
|
|
419
|
-
n = len(adj)
|
|
420
|
-
while nextlevel and cutoff > level:
|
|
421
|
-
thislevel = nextlevel
|
|
422
|
-
nextlevel = []
|
|
423
|
-
for v in thislevel:
|
|
424
|
-
for w in adj[v]:
|
|
425
|
-
if w not in paths:
|
|
426
|
-
paths[w] = join(paths[v], [w])
|
|
427
|
-
nextlevel.append(w)
|
|
428
|
-
if len(paths) == n:
|
|
429
|
-
return paths
|
|
430
|
-
level += 1
|
|
431
|
-
return paths
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
@nx._dispatchable
|
|
435
|
-
def single_target_shortest_path(G, target, cutoff=None):
|
|
436
|
-
"""Compute shortest path to target from all nodes that reach target.
|
|
437
|
-
|
|
438
|
-
Parameters
|
|
439
|
-
----------
|
|
440
|
-
G : NetworkX graph
|
|
441
|
-
|
|
442
|
-
target : node label
|
|
443
|
-
Target node for path
|
|
444
|
-
|
|
445
|
-
cutoff : integer, optional
|
|
446
|
-
Depth to stop the search. Only source nodes where the shortest path
|
|
447
|
-
from this node to the target node contains <= ``cutoff + 1`` nodes will
|
|
448
|
-
be included in the returned results.
|
|
449
|
-
|
|
450
|
-
Returns
|
|
451
|
-
-------
|
|
452
|
-
paths : dictionary
|
|
453
|
-
Dictionary, keyed by source, of shortest paths.
|
|
454
|
-
|
|
455
|
-
Examples
|
|
456
|
-
--------
|
|
457
|
-
>>> G = nx.path_graph(5, create_using=nx.DiGraph())
|
|
458
|
-
>>> nx.single_target_shortest_path(G, 4)
|
|
459
|
-
{4: [4], 3: [3, 4], 2: [2, 3, 4], 1: [1, 2, 3, 4], 0: [0, 1, 2, 3, 4]}
|
|
460
|
-
|
|
461
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
462
|
-
argument:
|
|
463
|
-
|
|
464
|
-
>>> nx.single_target_shortest_path(G, 4, cutoff=2)
|
|
465
|
-
{4: [4], 3: [3, 4], 2: [2, 3, 4]}
|
|
466
|
-
|
|
467
|
-
Notes
|
|
468
|
-
-----
|
|
469
|
-
The shortest path is not necessarily unique. So there can be multiple
|
|
470
|
-
paths between the source and each target node, all of which have the
|
|
471
|
-
same 'shortest' length. For each target node, this function returns
|
|
472
|
-
only one of those paths.
|
|
473
|
-
|
|
474
|
-
See Also
|
|
475
|
-
--------
|
|
476
|
-
shortest_path, single_source_shortest_path
|
|
477
|
-
"""
|
|
478
|
-
if target not in G:
|
|
479
|
-
raise nx.NodeNotFound(f"Target {target} not in G")
|
|
480
|
-
|
|
481
|
-
def join(p1, p2):
|
|
482
|
-
return p2 + p1
|
|
483
|
-
|
|
484
|
-
# handle undirected graphs
|
|
485
|
-
adj = G._pred if G.is_directed() else G._adj
|
|
486
|
-
if cutoff is None:
|
|
487
|
-
cutoff = float("inf")
|
|
488
|
-
nextlevel = [target] # list of nodes to check at next level
|
|
489
|
-
paths = {target: [target]} # paths dictionary (paths to key from source)
|
|
490
|
-
return dict(_single_shortest_path(adj, nextlevel, paths, cutoff, join))
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
@nx._dispatchable
|
|
494
|
-
def all_pairs_shortest_path(G, cutoff=None):
|
|
495
|
-
"""Compute shortest paths between all nodes.
|
|
496
|
-
|
|
497
|
-
Parameters
|
|
498
|
-
----------
|
|
499
|
-
G : NetworkX graph
|
|
500
|
-
|
|
501
|
-
cutoff : integer, optional
|
|
502
|
-
Depth at which to stop the search. Only paths containing at most
|
|
503
|
-
``cutoff + 1`` nodes are returned.
|
|
504
|
-
|
|
505
|
-
Returns
|
|
506
|
-
-------
|
|
507
|
-
paths : iterator
|
|
508
|
-
Dictionary, keyed by source and target, of shortest paths.
|
|
509
|
-
|
|
510
|
-
Examples
|
|
511
|
-
--------
|
|
512
|
-
>>> G = nx.path_graph(5)
|
|
513
|
-
>>> path = dict(nx.all_pairs_shortest_path(G))
|
|
514
|
-
>>> print(path[0])
|
|
515
|
-
{0: [0], 1: [0, 1], 2: [0, 1, 2], 3: [0, 1, 2, 3], 4: [0, 1, 2, 3, 4]}
|
|
516
|
-
|
|
517
|
-
Only include paths with length less than or equal to the `cutoff` keyword
|
|
518
|
-
argument:
|
|
519
|
-
|
|
520
|
-
>>> path = dict(nx.all_pairs_shortest_path(G, cutoff=2))
|
|
521
|
-
>>> print(path[0])
|
|
522
|
-
{0: [0], 1: [0, 1], 2: [0, 1, 2]}
|
|
523
|
-
|
|
524
|
-
Notes
|
|
525
|
-
-----
|
|
526
|
-
There may be multiple shortest paths with the same length between
|
|
527
|
-
two nodes. For each pair, this function returns only one of those paths.
|
|
528
|
-
|
|
529
|
-
See Also
|
|
530
|
-
--------
|
|
531
|
-
floyd_warshall
|
|
532
|
-
all_pairs_all_shortest_paths
|
|
533
|
-
|
|
534
|
-
"""
|
|
535
|
-
# TODO This can be trivially parallelized.
|
|
536
|
-
for n in G:
|
|
537
|
-
yield (n, single_source_shortest_path(G, n, cutoff=cutoff))
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
@nx._dispatchable
|
|
541
|
-
def predecessor(G, source, target=None, cutoff=None, return_seen=None):
|
|
542
|
-
"""Returns dict of predecessors for the path from source to all nodes in G.
|
|
543
|
-
|
|
544
|
-
Parameters
|
|
545
|
-
----------
|
|
546
|
-
G : NetworkX graph
|
|
547
|
-
|
|
548
|
-
source : node label
|
|
549
|
-
Starting node for path
|
|
550
|
-
|
|
551
|
-
target : node label, optional
|
|
552
|
-
Ending node for path. If provided only predecessors between
|
|
553
|
-
source and target are returned
|
|
554
|
-
|
|
555
|
-
cutoff : integer, optional
|
|
556
|
-
Depth to stop the search. Only paths of length <= `cutoff` are
|
|
557
|
-
returned.
|
|
558
|
-
|
|
559
|
-
return_seen : bool, optional (default=None)
|
|
560
|
-
Whether to return a dictionary, keyed by node, of the level (number of
|
|
561
|
-
hops) to reach the node (as seen during breadth-first-search).
|
|
562
|
-
|
|
563
|
-
Returns
|
|
564
|
-
-------
|
|
565
|
-
pred : dictionary
|
|
566
|
-
Dictionary, keyed by node, of predecessors in the shortest path.
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
(pred, seen): tuple of dictionaries
|
|
570
|
-
If `return_seen` argument is set to `True`, then a tuple of dictionaries
|
|
571
|
-
is returned. The first element is the dictionary, keyed by node, of
|
|
572
|
-
predecessors in the shortest path. The second element is the dictionary,
|
|
573
|
-
keyed by node, of the level (number of hops) to reach the node (as seen
|
|
574
|
-
during breadth-first-search).
|
|
575
|
-
|
|
576
|
-
Examples
|
|
577
|
-
--------
|
|
578
|
-
>>> G = nx.path_graph(4)
|
|
579
|
-
>>> list(G)
|
|
580
|
-
[0, 1, 2, 3]
|
|
581
|
-
>>> nx.predecessor(G, 0)
|
|
582
|
-
{0: [], 1: [0], 2: [1], 3: [2]}
|
|
583
|
-
>>> nx.predecessor(G, 0, cutoff=2)
|
|
584
|
-
{0: [], 1: [0], 2: [1]}
|
|
585
|
-
>>> nx.predecessor(G, 0, return_seen=True)
|
|
586
|
-
({0: [], 1: [0], 2: [1], 3: [2]}, {0: 0, 1: 1, 2: 2, 3: 3})
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
"""
|
|
590
|
-
if source not in G:
|
|
591
|
-
raise nx.NodeNotFound(f"Source {source} not in G")
|
|
592
|
-
|
|
593
|
-
level = 0 # the current level
|
|
594
|
-
nextlevel = [source] # list of nodes to check at next level
|
|
595
|
-
seen = {source: level} # level (number of hops) when seen in BFS
|
|
596
|
-
pred = {source: []} # predecessor dictionary
|
|
597
|
-
while nextlevel:
|
|
598
|
-
level = level + 1
|
|
599
|
-
thislevel = nextlevel
|
|
600
|
-
nextlevel = []
|
|
601
|
-
for v in thislevel:
|
|
602
|
-
for w in G[v]:
|
|
603
|
-
if w not in seen:
|
|
604
|
-
pred[w] = [v]
|
|
605
|
-
seen[w] = level
|
|
606
|
-
nextlevel.append(w)
|
|
607
|
-
elif seen[w] == level: # add v to predecessor list if it
|
|
608
|
-
pred[w].append(v) # is at the correct level
|
|
609
|
-
if cutoff and cutoff <= level:
|
|
610
|
-
break
|
|
611
|
-
|
|
612
|
-
if target is not None:
|
|
613
|
-
if return_seen:
|
|
614
|
-
if target not in pred:
|
|
615
|
-
return ([], -1) # No predecessor
|
|
616
|
-
return (pred[target], seen[target])
|
|
617
|
-
else:
|
|
618
|
-
if target not in pred:
|
|
619
|
-
return [] # No predecessor
|
|
620
|
-
return pred[target]
|
|
621
|
-
else:
|
|
622
|
-
if return_seen:
|
|
623
|
-
return (pred, seen)
|
|
624
|
-
else:
|
|
625
|
-
return pred
|