okstra 0.130.3 → 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 +21 -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/report_views.py +32 -5
- 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 +101 -6
- 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 +18 -12
- package/runtime/templates/reports/i18n/en.json +1 -0
- package/runtime/templates/reports/i18n/ko.json +1 -0
- package/runtime/templates/reports/report.css +18 -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,576 +0,0 @@
|
|
|
1
|
-
"""Basic algorithms for breadth-first searching the nodes of a graph."""
|
|
2
|
-
|
|
3
|
-
from collections import deque
|
|
4
|
-
|
|
5
|
-
import networkx as nx
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"bfs_edges",
|
|
9
|
-
"bfs_tree",
|
|
10
|
-
"bfs_predecessors",
|
|
11
|
-
"bfs_successors",
|
|
12
|
-
"descendants_at_distance",
|
|
13
|
-
"bfs_layers",
|
|
14
|
-
"bfs_labeled_edges",
|
|
15
|
-
"generic_bfs_edges",
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@nx._dispatchable
|
|
20
|
-
def generic_bfs_edges(G, source, neighbors=None, depth_limit=None):
|
|
21
|
-
"""Iterate over edges in a breadth-first search.
|
|
22
|
-
|
|
23
|
-
The breadth-first search begins at `source` and enqueues the
|
|
24
|
-
neighbors of newly visited nodes specified by the `neighbors`
|
|
25
|
-
function.
|
|
26
|
-
|
|
27
|
-
Parameters
|
|
28
|
-
----------
|
|
29
|
-
G : NetworkX graph
|
|
30
|
-
|
|
31
|
-
source : node
|
|
32
|
-
Starting node for the breadth-first search; this function
|
|
33
|
-
iterates over only those edges in the component reachable from
|
|
34
|
-
this node.
|
|
35
|
-
|
|
36
|
-
neighbors : function
|
|
37
|
-
A function that takes a newly visited node of the graph as input
|
|
38
|
-
and returns an *iterator* (not just a list) of nodes that are
|
|
39
|
-
neighbors of that node with custom ordering. If not specified, this is
|
|
40
|
-
just the ``G.neighbors`` method, but in general it can be any function
|
|
41
|
-
that returns an iterator over some or all of the neighbors of a
|
|
42
|
-
given node, in any order.
|
|
43
|
-
|
|
44
|
-
depth_limit : int, optional(default=len(G))
|
|
45
|
-
Specify the maximum search depth.
|
|
46
|
-
|
|
47
|
-
Yields
|
|
48
|
-
------
|
|
49
|
-
edge
|
|
50
|
-
Edges in the breadth-first search starting from `source`.
|
|
51
|
-
|
|
52
|
-
Examples
|
|
53
|
-
--------
|
|
54
|
-
>>> G = nx.path_graph(7)
|
|
55
|
-
>>> list(nx.generic_bfs_edges(G, source=0))
|
|
56
|
-
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
|
|
57
|
-
>>> list(nx.generic_bfs_edges(G, source=2))
|
|
58
|
-
[(2, 1), (2, 3), (1, 0), (3, 4), (4, 5), (5, 6)]
|
|
59
|
-
>>> list(nx.generic_bfs_edges(G, source=2, depth_limit=2))
|
|
60
|
-
[(2, 1), (2, 3), (1, 0), (3, 4)]
|
|
61
|
-
|
|
62
|
-
The `neighbors` param can be used to specify the visitation order of each
|
|
63
|
-
node's neighbors generically. In the following example, we modify the default
|
|
64
|
-
neighbor to return *odd* nodes first:
|
|
65
|
-
|
|
66
|
-
>>> def odd_first(n):
|
|
67
|
-
... return sorted(G.neighbors(n), key=lambda x: x % 2, reverse=True)
|
|
68
|
-
|
|
69
|
-
>>> G = nx.star_graph(5)
|
|
70
|
-
>>> list(nx.generic_bfs_edges(G, source=0)) # Default neighbor ordering
|
|
71
|
-
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]
|
|
72
|
-
>>> list(nx.generic_bfs_edges(G, source=0, neighbors=odd_first))
|
|
73
|
-
[(0, 1), (0, 3), (0, 5), (0, 2), (0, 4)]
|
|
74
|
-
|
|
75
|
-
Notes
|
|
76
|
-
-----
|
|
77
|
-
This implementation is from `PADS`_, which was in the public domain
|
|
78
|
-
when it was first accessed in July, 2004. The modifications
|
|
79
|
-
to allow depth limits are based on the Wikipedia article
|
|
80
|
-
"`Depth-limited-search`_".
|
|
81
|
-
|
|
82
|
-
.. _PADS: http://www.ics.uci.edu/~eppstein/PADS/BFS.py
|
|
83
|
-
.. _Depth-limited-search: https://en.wikipedia.org/wiki/Depth-limited_search
|
|
84
|
-
"""
|
|
85
|
-
if neighbors is None:
|
|
86
|
-
neighbors = G.neighbors
|
|
87
|
-
if depth_limit is None:
|
|
88
|
-
depth_limit = len(G)
|
|
89
|
-
|
|
90
|
-
seen = {source}
|
|
91
|
-
n = len(G)
|
|
92
|
-
depth = 0
|
|
93
|
-
next_parents_children = [(source, neighbors(source))]
|
|
94
|
-
while next_parents_children and depth < depth_limit:
|
|
95
|
-
this_parents_children = next_parents_children
|
|
96
|
-
next_parents_children = []
|
|
97
|
-
for parent, children in this_parents_children:
|
|
98
|
-
for child in children:
|
|
99
|
-
if child not in seen:
|
|
100
|
-
seen.add(child)
|
|
101
|
-
next_parents_children.append((child, neighbors(child)))
|
|
102
|
-
yield parent, child
|
|
103
|
-
if len(seen) == n:
|
|
104
|
-
return
|
|
105
|
-
depth += 1
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
@nx._dispatchable
|
|
109
|
-
def bfs_edges(G, source, reverse=False, depth_limit=None, sort_neighbors=None):
|
|
110
|
-
"""Iterate over edges in a breadth-first-search starting at source.
|
|
111
|
-
|
|
112
|
-
Parameters
|
|
113
|
-
----------
|
|
114
|
-
G : NetworkX graph
|
|
115
|
-
|
|
116
|
-
source : node
|
|
117
|
-
Specify starting node for breadth-first search; this function
|
|
118
|
-
iterates over only those edges in the component reachable from
|
|
119
|
-
this node.
|
|
120
|
-
|
|
121
|
-
reverse : bool, optional
|
|
122
|
-
If True traverse a directed graph in the reverse direction
|
|
123
|
-
|
|
124
|
-
depth_limit : int, optional(default=len(G))
|
|
125
|
-
Specify the maximum search depth
|
|
126
|
-
|
|
127
|
-
sort_neighbors : function (default=None)
|
|
128
|
-
A function that takes an iterator over nodes as the input, and
|
|
129
|
-
returns an iterable of the same nodes with a custom ordering.
|
|
130
|
-
For example, `sorted` will sort the nodes in increasing order.
|
|
131
|
-
|
|
132
|
-
Yields
|
|
133
|
-
------
|
|
134
|
-
edge: 2-tuple of nodes
|
|
135
|
-
Yields edges resulting from the breadth-first search.
|
|
136
|
-
|
|
137
|
-
Examples
|
|
138
|
-
--------
|
|
139
|
-
To get the edges in a breadth-first search:
|
|
140
|
-
|
|
141
|
-
>>> G = nx.path_graph(3)
|
|
142
|
-
>>> list(nx.bfs_edges(G, 0))
|
|
143
|
-
[(0, 1), (1, 2)]
|
|
144
|
-
>>> list(nx.bfs_edges(G, source=0, depth_limit=1))
|
|
145
|
-
[(0, 1)]
|
|
146
|
-
|
|
147
|
-
To get the nodes in a breadth-first search order:
|
|
148
|
-
|
|
149
|
-
>>> G = nx.path_graph(3)
|
|
150
|
-
>>> root = 2
|
|
151
|
-
>>> edges = nx.bfs_edges(G, root)
|
|
152
|
-
>>> nodes = [root] + [v for u, v in edges]
|
|
153
|
-
>>> nodes
|
|
154
|
-
[2, 1, 0]
|
|
155
|
-
|
|
156
|
-
Notes
|
|
157
|
-
-----
|
|
158
|
-
The naming of this function is very similar to
|
|
159
|
-
:func:`~networkx.algorithms.traversal.edgebfs.edge_bfs`. The difference
|
|
160
|
-
is that ``edge_bfs`` yields edges even if they extend back to an already
|
|
161
|
-
explored node while this generator yields the edges of the tree that results
|
|
162
|
-
from a breadth-first-search (BFS) so no edges are reported if they extend
|
|
163
|
-
to already explored nodes. That means ``edge_bfs`` reports all edges while
|
|
164
|
-
``bfs_edges`` only reports those traversed by a node-based BFS. Yet another
|
|
165
|
-
description is that ``bfs_edges`` reports the edges traversed during BFS
|
|
166
|
-
while ``edge_bfs`` reports all edges in the order they are explored.
|
|
167
|
-
|
|
168
|
-
Based on the breadth-first search implementation in PADS [1]_
|
|
169
|
-
by D. Eppstein, July 2004; with modifications to allow depth limits
|
|
170
|
-
as described in [2]_.
|
|
171
|
-
|
|
172
|
-
References
|
|
173
|
-
----------
|
|
174
|
-
.. [1] http://www.ics.uci.edu/~eppstein/PADS/BFS.py.
|
|
175
|
-
.. [2] https://en.wikipedia.org/wiki/Depth-limited_search
|
|
176
|
-
|
|
177
|
-
See Also
|
|
178
|
-
--------
|
|
179
|
-
bfs_tree
|
|
180
|
-
:func:`~networkx.algorithms.traversal.depth_first_search.dfs_edges`
|
|
181
|
-
:func:`~networkx.algorithms.traversal.edgebfs.edge_bfs`
|
|
182
|
-
|
|
183
|
-
"""
|
|
184
|
-
if reverse and G.is_directed():
|
|
185
|
-
successors = G.predecessors
|
|
186
|
-
else:
|
|
187
|
-
successors = G.neighbors
|
|
188
|
-
|
|
189
|
-
if sort_neighbors is not None:
|
|
190
|
-
yield from generic_bfs_edges(
|
|
191
|
-
G, source, lambda node: iter(sort_neighbors(successors(node))), depth_limit
|
|
192
|
-
)
|
|
193
|
-
else:
|
|
194
|
-
yield from generic_bfs_edges(G, source, successors, depth_limit)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
@nx._dispatchable(returns_graph=True)
|
|
198
|
-
def bfs_tree(G, source, reverse=False, depth_limit=None, sort_neighbors=None):
|
|
199
|
-
"""Returns an oriented tree constructed from of a breadth-first-search
|
|
200
|
-
starting at source.
|
|
201
|
-
|
|
202
|
-
Parameters
|
|
203
|
-
----------
|
|
204
|
-
G : NetworkX graph
|
|
205
|
-
|
|
206
|
-
source : node
|
|
207
|
-
Specify starting node for breadth-first search
|
|
208
|
-
|
|
209
|
-
reverse : bool, optional
|
|
210
|
-
If True traverse a directed graph in the reverse direction
|
|
211
|
-
|
|
212
|
-
depth_limit : int, optional(default=len(G))
|
|
213
|
-
Specify the maximum search depth
|
|
214
|
-
|
|
215
|
-
sort_neighbors : function (default=None)
|
|
216
|
-
A function that takes an iterator over nodes as the input, and
|
|
217
|
-
returns an iterable of the same nodes with a custom ordering.
|
|
218
|
-
For example, `sorted` will sort the nodes in increasing order.
|
|
219
|
-
|
|
220
|
-
Returns
|
|
221
|
-
-------
|
|
222
|
-
T: NetworkX DiGraph
|
|
223
|
-
An oriented tree
|
|
224
|
-
|
|
225
|
-
Examples
|
|
226
|
-
--------
|
|
227
|
-
>>> G = nx.path_graph(3)
|
|
228
|
-
>>> list(nx.bfs_tree(G, 1).edges())
|
|
229
|
-
[(1, 0), (1, 2)]
|
|
230
|
-
>>> H = nx.Graph()
|
|
231
|
-
>>> nx.add_path(H, [0, 1, 2, 3, 4, 5, 6])
|
|
232
|
-
>>> nx.add_path(H, [2, 7, 8, 9, 10])
|
|
233
|
-
>>> sorted(list(nx.bfs_tree(H, source=3, depth_limit=3).edges()))
|
|
234
|
-
[(1, 0), (2, 1), (2, 7), (3, 2), (3, 4), (4, 5), (5, 6), (7, 8)]
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
Notes
|
|
238
|
-
-----
|
|
239
|
-
Based on http://www.ics.uci.edu/~eppstein/PADS/BFS.py
|
|
240
|
-
by D. Eppstein, July 2004. The modifications
|
|
241
|
-
to allow depth limits based on the Wikipedia article
|
|
242
|
-
"`Depth-limited-search`_".
|
|
243
|
-
|
|
244
|
-
.. _Depth-limited-search: https://en.wikipedia.org/wiki/Depth-limited_search
|
|
245
|
-
|
|
246
|
-
See Also
|
|
247
|
-
--------
|
|
248
|
-
dfs_tree
|
|
249
|
-
bfs_edges
|
|
250
|
-
edge_bfs
|
|
251
|
-
"""
|
|
252
|
-
T = nx.DiGraph()
|
|
253
|
-
T.add_node(source)
|
|
254
|
-
edges_gen = bfs_edges(
|
|
255
|
-
G,
|
|
256
|
-
source,
|
|
257
|
-
reverse=reverse,
|
|
258
|
-
depth_limit=depth_limit,
|
|
259
|
-
sort_neighbors=sort_neighbors,
|
|
260
|
-
)
|
|
261
|
-
T.add_edges_from(edges_gen)
|
|
262
|
-
return T
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
@nx._dispatchable
|
|
266
|
-
def bfs_predecessors(G, source, depth_limit=None, sort_neighbors=None):
|
|
267
|
-
"""Returns an iterator of predecessors in breadth-first-search from source.
|
|
268
|
-
|
|
269
|
-
Parameters
|
|
270
|
-
----------
|
|
271
|
-
G : NetworkX graph
|
|
272
|
-
|
|
273
|
-
source : node
|
|
274
|
-
Specify starting node for breadth-first search
|
|
275
|
-
|
|
276
|
-
depth_limit : int, optional(default=len(G))
|
|
277
|
-
Specify the maximum search depth
|
|
278
|
-
|
|
279
|
-
sort_neighbors : function (default=None)
|
|
280
|
-
A function that takes an iterator over nodes as the input, and
|
|
281
|
-
returns an iterable of the same nodes with a custom ordering.
|
|
282
|
-
For example, `sorted` will sort the nodes in increasing order.
|
|
283
|
-
|
|
284
|
-
Returns
|
|
285
|
-
-------
|
|
286
|
-
pred: iterator
|
|
287
|
-
(node, predecessor) iterator where `predecessor` is the predecessor of
|
|
288
|
-
`node` in a breadth first search starting from `source`.
|
|
289
|
-
|
|
290
|
-
Examples
|
|
291
|
-
--------
|
|
292
|
-
>>> G = nx.path_graph(3)
|
|
293
|
-
>>> dict(nx.bfs_predecessors(G, 0))
|
|
294
|
-
{1: 0, 2: 1}
|
|
295
|
-
>>> H = nx.Graph()
|
|
296
|
-
>>> H.add_edges_from([(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)])
|
|
297
|
-
>>> dict(nx.bfs_predecessors(H, 0))
|
|
298
|
-
{1: 0, 2: 0, 3: 1, 4: 1, 5: 2, 6: 2}
|
|
299
|
-
>>> M = nx.Graph()
|
|
300
|
-
>>> nx.add_path(M, [0, 1, 2, 3, 4, 5, 6])
|
|
301
|
-
>>> nx.add_path(M, [2, 7, 8, 9, 10])
|
|
302
|
-
>>> sorted(nx.bfs_predecessors(M, source=1, depth_limit=3))
|
|
303
|
-
[(0, 1), (2, 1), (3, 2), (4, 3), (7, 2), (8, 7)]
|
|
304
|
-
>>> N = nx.DiGraph()
|
|
305
|
-
>>> nx.add_path(N, [0, 1, 2, 3, 4, 7])
|
|
306
|
-
>>> nx.add_path(N, [3, 5, 6, 7])
|
|
307
|
-
>>> sorted(nx.bfs_predecessors(N, source=2))
|
|
308
|
-
[(3, 2), (4, 3), (5, 3), (6, 5), (7, 4)]
|
|
309
|
-
|
|
310
|
-
Notes
|
|
311
|
-
-----
|
|
312
|
-
Based on http://www.ics.uci.edu/~eppstein/PADS/BFS.py
|
|
313
|
-
by D. Eppstein, July 2004. The modifications
|
|
314
|
-
to allow depth limits based on the Wikipedia article
|
|
315
|
-
"`Depth-limited-search`_".
|
|
316
|
-
|
|
317
|
-
.. _Depth-limited-search: https://en.wikipedia.org/wiki/Depth-limited_search
|
|
318
|
-
|
|
319
|
-
See Also
|
|
320
|
-
--------
|
|
321
|
-
bfs_tree
|
|
322
|
-
bfs_edges
|
|
323
|
-
edge_bfs
|
|
324
|
-
"""
|
|
325
|
-
for s, t in bfs_edges(
|
|
326
|
-
G, source, depth_limit=depth_limit, sort_neighbors=sort_neighbors
|
|
327
|
-
):
|
|
328
|
-
yield (t, s)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
@nx._dispatchable
|
|
332
|
-
def bfs_successors(G, source, depth_limit=None, sort_neighbors=None):
|
|
333
|
-
"""Returns an iterator of successors in breadth-first-search from source.
|
|
334
|
-
|
|
335
|
-
Parameters
|
|
336
|
-
----------
|
|
337
|
-
G : NetworkX graph
|
|
338
|
-
|
|
339
|
-
source : node
|
|
340
|
-
Specify starting node for breadth-first search
|
|
341
|
-
|
|
342
|
-
depth_limit : int, optional(default=len(G))
|
|
343
|
-
Specify the maximum search depth
|
|
344
|
-
|
|
345
|
-
sort_neighbors : function (default=None)
|
|
346
|
-
A function that takes an iterator over nodes as the input, and
|
|
347
|
-
returns an iterable of the same nodes with a custom ordering.
|
|
348
|
-
For example, `sorted` will sort the nodes in increasing order.
|
|
349
|
-
|
|
350
|
-
Returns
|
|
351
|
-
-------
|
|
352
|
-
succ: iterator
|
|
353
|
-
(node, successors) iterator where `successors` is the non-empty list of
|
|
354
|
-
successors of `node` in a breadth first search from `source`.
|
|
355
|
-
To appear in the iterator, `node` must have successors.
|
|
356
|
-
|
|
357
|
-
Examples
|
|
358
|
-
--------
|
|
359
|
-
>>> G = nx.path_graph(3)
|
|
360
|
-
>>> dict(nx.bfs_successors(G, 0))
|
|
361
|
-
{0: [1], 1: [2]}
|
|
362
|
-
>>> H = nx.Graph()
|
|
363
|
-
>>> H.add_edges_from([(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)])
|
|
364
|
-
>>> dict(nx.bfs_successors(H, 0))
|
|
365
|
-
{0: [1, 2], 1: [3, 4], 2: [5, 6]}
|
|
366
|
-
>>> G = nx.Graph()
|
|
367
|
-
>>> nx.add_path(G, [0, 1, 2, 3, 4, 5, 6])
|
|
368
|
-
>>> nx.add_path(G, [2, 7, 8, 9, 10])
|
|
369
|
-
>>> dict(nx.bfs_successors(G, source=1, depth_limit=3))
|
|
370
|
-
{1: [0, 2], 2: [3, 7], 3: [4], 7: [8]}
|
|
371
|
-
>>> G = nx.DiGraph()
|
|
372
|
-
>>> nx.add_path(G, [0, 1, 2, 3, 4, 5])
|
|
373
|
-
>>> dict(nx.bfs_successors(G, source=3))
|
|
374
|
-
{3: [4], 4: [5]}
|
|
375
|
-
|
|
376
|
-
Notes
|
|
377
|
-
-----
|
|
378
|
-
Based on http://www.ics.uci.edu/~eppstein/PADS/BFS.py
|
|
379
|
-
by D. Eppstein, July 2004.The modifications
|
|
380
|
-
to allow depth limits based on the Wikipedia article
|
|
381
|
-
"`Depth-limited-search`_".
|
|
382
|
-
|
|
383
|
-
.. _Depth-limited-search: https://en.wikipedia.org/wiki/Depth-limited_search
|
|
384
|
-
|
|
385
|
-
See Also
|
|
386
|
-
--------
|
|
387
|
-
bfs_tree
|
|
388
|
-
bfs_edges
|
|
389
|
-
edge_bfs
|
|
390
|
-
"""
|
|
391
|
-
parent = source
|
|
392
|
-
children = []
|
|
393
|
-
for p, c in bfs_edges(
|
|
394
|
-
G, source, depth_limit=depth_limit, sort_neighbors=sort_neighbors
|
|
395
|
-
):
|
|
396
|
-
if p == parent:
|
|
397
|
-
children.append(c)
|
|
398
|
-
continue
|
|
399
|
-
yield (parent, children)
|
|
400
|
-
children = [c]
|
|
401
|
-
parent = p
|
|
402
|
-
yield (parent, children)
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
@nx._dispatchable
|
|
406
|
-
def bfs_layers(G, sources):
|
|
407
|
-
"""Returns an iterator of all the layers in breadth-first search traversal.
|
|
408
|
-
|
|
409
|
-
Parameters
|
|
410
|
-
----------
|
|
411
|
-
G : NetworkX graph
|
|
412
|
-
A graph over which to find the layers using breadth-first search.
|
|
413
|
-
|
|
414
|
-
sources : node in `G` or iterable of nodes in `G`
|
|
415
|
-
Specify starting nodes for single source or multiple sources
|
|
416
|
-
breadth-first search.
|
|
417
|
-
|
|
418
|
-
Yields
|
|
419
|
-
------
|
|
420
|
-
layer : list of nodes
|
|
421
|
-
Yields list of nodes at the same distance from `sources`.
|
|
422
|
-
|
|
423
|
-
Examples
|
|
424
|
-
--------
|
|
425
|
-
>>> G = nx.path_graph(5)
|
|
426
|
-
>>> dict(enumerate(nx.bfs_layers(G, [0, 4])))
|
|
427
|
-
{0: [0, 4], 1: [1, 3], 2: [2]}
|
|
428
|
-
>>> H = nx.Graph()
|
|
429
|
-
>>> H.add_edges_from([(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)])
|
|
430
|
-
>>> dict(enumerate(nx.bfs_layers(H, [1])))
|
|
431
|
-
{0: [1], 1: [0, 3, 4], 2: [2], 3: [5, 6]}
|
|
432
|
-
>>> dict(enumerate(nx.bfs_layers(H, [1, 6])))
|
|
433
|
-
{0: [1, 6], 1: [0, 3, 4, 2], 2: [5]}
|
|
434
|
-
"""
|
|
435
|
-
if sources in G:
|
|
436
|
-
sources = [sources]
|
|
437
|
-
|
|
438
|
-
visited = set(sources)
|
|
439
|
-
current_layer = list(visited)
|
|
440
|
-
|
|
441
|
-
for source in current_layer:
|
|
442
|
-
if source not in G:
|
|
443
|
-
raise nx.NetworkXError(f"The node {source} is not in the graph.")
|
|
444
|
-
|
|
445
|
-
# this is basically BFS, except that the current layer only stores the nodes at
|
|
446
|
-
# same distance from sources at each iteration
|
|
447
|
-
while current_layer:
|
|
448
|
-
yield current_layer
|
|
449
|
-
next_layer = []
|
|
450
|
-
for node in current_layer:
|
|
451
|
-
for child in G[node]:
|
|
452
|
-
if child not in visited:
|
|
453
|
-
visited.add(child)
|
|
454
|
-
next_layer.append(child)
|
|
455
|
-
current_layer = next_layer
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
REVERSE_EDGE = "reverse"
|
|
459
|
-
TREE_EDGE = "tree"
|
|
460
|
-
FORWARD_EDGE = "forward"
|
|
461
|
-
LEVEL_EDGE = "level"
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
@nx._dispatchable
|
|
465
|
-
def bfs_labeled_edges(G, sources):
|
|
466
|
-
"""Iterate over edges in a breadth-first search (BFS) labeled by type.
|
|
467
|
-
|
|
468
|
-
We generate triple of the form (*u*, *v*, *d*), where (*u*, *v*) is the
|
|
469
|
-
edge being explored in the breadth-first search and *d* is one of the
|
|
470
|
-
strings 'tree', 'forward', 'level', or 'reverse'. A 'tree' edge is one in
|
|
471
|
-
which *v* is first discovered and placed into the layer below *u*. A
|
|
472
|
-
'forward' edge is one in which *u* is on the layer above *v* and *v* has
|
|
473
|
-
already been discovered. A 'level' edge is one in which both *u* and *v*
|
|
474
|
-
occur on the same layer. A 'reverse' edge is one in which *u* is on a layer
|
|
475
|
-
below *v*.
|
|
476
|
-
|
|
477
|
-
We emit each edge exactly once. In an undirected graph, 'reverse' edges do
|
|
478
|
-
not occur, because each is discovered either as a 'tree' or 'forward' edge.
|
|
479
|
-
|
|
480
|
-
Parameters
|
|
481
|
-
----------
|
|
482
|
-
G : NetworkX graph
|
|
483
|
-
A graph over which to find the layers using breadth-first search.
|
|
484
|
-
|
|
485
|
-
sources : node in `G` or list of nodes in `G`
|
|
486
|
-
Starting nodes for single source or multiple sources breadth-first search
|
|
487
|
-
|
|
488
|
-
Yields
|
|
489
|
-
------
|
|
490
|
-
edges: generator
|
|
491
|
-
A generator of triples (*u*, *v*, *d*) where (*u*, *v*) is the edge being
|
|
492
|
-
explored and *d* is described above.
|
|
493
|
-
|
|
494
|
-
Examples
|
|
495
|
-
--------
|
|
496
|
-
>>> G = nx.cycle_graph(4, create_using=nx.DiGraph)
|
|
497
|
-
>>> list(nx.bfs_labeled_edges(G, 0))
|
|
498
|
-
[(0, 1, 'tree'), (1, 2, 'tree'), (2, 3, 'tree'), (3, 0, 'reverse')]
|
|
499
|
-
>>> G = nx.complete_graph(3)
|
|
500
|
-
>>> list(nx.bfs_labeled_edges(G, 0))
|
|
501
|
-
[(0, 1, 'tree'), (0, 2, 'tree'), (1, 2, 'level')]
|
|
502
|
-
>>> list(nx.bfs_labeled_edges(G, [0, 1]))
|
|
503
|
-
[(0, 1, 'level'), (0, 2, 'tree'), (1, 2, 'forward')]
|
|
504
|
-
"""
|
|
505
|
-
if sources in G:
|
|
506
|
-
sources = [sources]
|
|
507
|
-
|
|
508
|
-
neighbors = G._adj
|
|
509
|
-
directed = G.is_directed()
|
|
510
|
-
visited = set()
|
|
511
|
-
visit = visited.discard if directed else visited.add
|
|
512
|
-
# We use visited in a negative sense, so the visited set stays empty for the
|
|
513
|
-
# directed case and level edges are reported on their first occurrence in
|
|
514
|
-
# the undirected case. Note our use of visited.discard -- this is built-in
|
|
515
|
-
# thus somewhat faster than a python-defined def nop(x): pass
|
|
516
|
-
depth = {s: 0 for s in sources}
|
|
517
|
-
queue = deque(depth.items())
|
|
518
|
-
push = queue.append
|
|
519
|
-
pop = queue.popleft
|
|
520
|
-
while queue:
|
|
521
|
-
u, du = pop()
|
|
522
|
-
for v in neighbors[u]:
|
|
523
|
-
if v not in depth:
|
|
524
|
-
depth[v] = dv = du + 1
|
|
525
|
-
push((v, dv))
|
|
526
|
-
yield u, v, TREE_EDGE
|
|
527
|
-
else:
|
|
528
|
-
dv = depth[v]
|
|
529
|
-
if du == dv:
|
|
530
|
-
if v not in visited:
|
|
531
|
-
yield u, v, LEVEL_EDGE
|
|
532
|
-
elif du < dv:
|
|
533
|
-
yield u, v, FORWARD_EDGE
|
|
534
|
-
elif directed:
|
|
535
|
-
yield u, v, REVERSE_EDGE
|
|
536
|
-
visit(u)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
@nx._dispatchable
|
|
540
|
-
def descendants_at_distance(G, source, distance):
|
|
541
|
-
"""Returns all nodes at a fixed `distance` from `source` in `G`.
|
|
542
|
-
|
|
543
|
-
Parameters
|
|
544
|
-
----------
|
|
545
|
-
G : NetworkX graph
|
|
546
|
-
A graph
|
|
547
|
-
source : node in `G`
|
|
548
|
-
distance : the distance of the wanted nodes from `source`
|
|
549
|
-
|
|
550
|
-
Returns
|
|
551
|
-
-------
|
|
552
|
-
set()
|
|
553
|
-
The descendants of `source` in `G` at the given `distance` from `source`
|
|
554
|
-
|
|
555
|
-
Examples
|
|
556
|
-
--------
|
|
557
|
-
>>> G = nx.path_graph(5)
|
|
558
|
-
>>> nx.descendants_at_distance(G, 2, 2)
|
|
559
|
-
{0, 4}
|
|
560
|
-
>>> H = nx.DiGraph()
|
|
561
|
-
>>> H.add_edges_from([(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)])
|
|
562
|
-
>>> nx.descendants_at_distance(H, 0, 2)
|
|
563
|
-
{3, 4, 5, 6}
|
|
564
|
-
>>> nx.descendants_at_distance(H, 5, 0)
|
|
565
|
-
{5}
|
|
566
|
-
>>> nx.descendants_at_distance(H, 5, 1)
|
|
567
|
-
set()
|
|
568
|
-
"""
|
|
569
|
-
if source not in G:
|
|
570
|
-
raise nx.NetworkXError(f"The node {source} is not in the graph.")
|
|
571
|
-
|
|
572
|
-
bfs_generator = nx.bfs_layers(G, source)
|
|
573
|
-
for i, layer in enumerate(bfs_generator):
|
|
574
|
-
if i == distance:
|
|
575
|
-
return set(layer)
|
|
576
|
-
return set()
|