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,272 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
=======================
|
|
3
|
-
Distance-regular graphs
|
|
4
|
-
=======================
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from collections import defaultdict
|
|
8
|
-
from itertools import combinations_with_replacement
|
|
9
|
-
from math import log
|
|
10
|
-
|
|
11
|
-
import networkx as nx
|
|
12
|
-
from networkx.utils import not_implemented_for
|
|
13
|
-
|
|
14
|
-
from .distance_measures import diameter
|
|
15
|
-
|
|
16
|
-
__all__ = [
|
|
17
|
-
"is_distance_regular",
|
|
18
|
-
"is_strongly_regular",
|
|
19
|
-
"intersection_array",
|
|
20
|
-
"global_parameters",
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@nx._dispatchable
|
|
25
|
-
def is_distance_regular(G):
|
|
26
|
-
"""Returns True if the graph is distance regular, False otherwise.
|
|
27
|
-
|
|
28
|
-
A connected graph G is distance-regular if for any nodes x,y
|
|
29
|
-
and any integers i,j=0,1,...,d (where d is the graph
|
|
30
|
-
diameter), the number of vertices at distance i from x and
|
|
31
|
-
distance j from y depends only on i,j and the graph distance
|
|
32
|
-
between x and y, independently of the choice of x and y.
|
|
33
|
-
|
|
34
|
-
Parameters
|
|
35
|
-
----------
|
|
36
|
-
G: Networkx graph (undirected)
|
|
37
|
-
|
|
38
|
-
Returns
|
|
39
|
-
-------
|
|
40
|
-
bool
|
|
41
|
-
True if the graph is Distance Regular, False otherwise
|
|
42
|
-
|
|
43
|
-
Examples
|
|
44
|
-
--------
|
|
45
|
-
>>> G = nx.hypercube_graph(6)
|
|
46
|
-
>>> nx.is_distance_regular(G)
|
|
47
|
-
True
|
|
48
|
-
|
|
49
|
-
See Also
|
|
50
|
-
--------
|
|
51
|
-
intersection_array, global_parameters
|
|
52
|
-
|
|
53
|
-
Notes
|
|
54
|
-
-----
|
|
55
|
-
For undirected and simple graphs only
|
|
56
|
-
|
|
57
|
-
References
|
|
58
|
-
----------
|
|
59
|
-
.. [1] Brouwer, A. E.; Cohen, A. M.; and Neumaier, A.
|
|
60
|
-
Distance-Regular Graphs. New York: Springer-Verlag, 1989.
|
|
61
|
-
.. [2] Weisstein, Eric W. "Distance-Regular Graph."
|
|
62
|
-
http://mathworld.wolfram.com/Distance-RegularGraph.html
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
try:
|
|
66
|
-
intersection_array(G)
|
|
67
|
-
return True
|
|
68
|
-
except nx.NetworkXError:
|
|
69
|
-
return False
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def global_parameters(b, c):
|
|
73
|
-
"""Returns global parameters for a given intersection array.
|
|
74
|
-
|
|
75
|
-
Given a distance-regular graph G with diameter d and integers b_i,
|
|
76
|
-
c_i,i = 0,....,d such that for any 2 vertices x,y in G at a distance
|
|
77
|
-
i=d(x,y), there are exactly c_i neighbors of y at a distance of i-1 from x
|
|
78
|
-
and b_i neighbors of y at a distance of i+1 from x.
|
|
79
|
-
|
|
80
|
-
Thus, a distance regular graph has the global parameters,
|
|
81
|
-
[[c_0,a_0,b_0],[c_1,a_1,b_1],......,[c_d,a_d,b_d]] for the
|
|
82
|
-
intersection array [b_0,b_1,.....b_{d-1};c_1,c_2,.....c_d]
|
|
83
|
-
where a_i+b_i+c_i=k , k= degree of every vertex.
|
|
84
|
-
|
|
85
|
-
Parameters
|
|
86
|
-
----------
|
|
87
|
-
b : list
|
|
88
|
-
|
|
89
|
-
c : list
|
|
90
|
-
|
|
91
|
-
Returns
|
|
92
|
-
-------
|
|
93
|
-
iterable
|
|
94
|
-
An iterable over three tuples.
|
|
95
|
-
|
|
96
|
-
Examples
|
|
97
|
-
--------
|
|
98
|
-
>>> G = nx.dodecahedral_graph()
|
|
99
|
-
>>> b, c = nx.intersection_array(G)
|
|
100
|
-
>>> list(nx.global_parameters(b, c))
|
|
101
|
-
[(0, 0, 3), (1, 0, 2), (1, 1, 1), (1, 1, 1), (2, 0, 1), (3, 0, 0)]
|
|
102
|
-
|
|
103
|
-
References
|
|
104
|
-
----------
|
|
105
|
-
.. [1] Weisstein, Eric W. "Global Parameters."
|
|
106
|
-
From MathWorld--A Wolfram Web Resource.
|
|
107
|
-
http://mathworld.wolfram.com/GlobalParameters.html
|
|
108
|
-
|
|
109
|
-
See Also
|
|
110
|
-
--------
|
|
111
|
-
intersection_array
|
|
112
|
-
"""
|
|
113
|
-
return ((y, b[0] - x - y, x) for x, y in zip(b + [0], [0] + c))
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@not_implemented_for("directed")
|
|
117
|
-
@not_implemented_for("multigraph")
|
|
118
|
-
@nx._dispatchable
|
|
119
|
-
def intersection_array(G):
|
|
120
|
-
"""Returns the intersection array of a distance-regular graph.
|
|
121
|
-
|
|
122
|
-
Given a distance-regular graph G with integers b_i, c_i,i = 0,....,d
|
|
123
|
-
such that for any 2 vertices x,y in G at a distance i=d(x,y), there
|
|
124
|
-
are exactly c_i neighbors of y at a distance of i-1 from x and b_i
|
|
125
|
-
neighbors of y at a distance of i+1 from x.
|
|
126
|
-
|
|
127
|
-
A distance regular graph's intersection array is given by,
|
|
128
|
-
[b_0,b_1,.....b_{d-1};c_1,c_2,.....c_d]
|
|
129
|
-
|
|
130
|
-
Parameters
|
|
131
|
-
----------
|
|
132
|
-
G: Networkx graph (undirected)
|
|
133
|
-
|
|
134
|
-
Returns
|
|
135
|
-
-------
|
|
136
|
-
b,c: tuple of lists
|
|
137
|
-
|
|
138
|
-
Examples
|
|
139
|
-
--------
|
|
140
|
-
>>> G = nx.icosahedral_graph()
|
|
141
|
-
>>> nx.intersection_array(G)
|
|
142
|
-
([5, 2, 1], [1, 2, 5])
|
|
143
|
-
|
|
144
|
-
References
|
|
145
|
-
----------
|
|
146
|
-
.. [1] Weisstein, Eric W. "Intersection Array."
|
|
147
|
-
From MathWorld--A Wolfram Web Resource.
|
|
148
|
-
http://mathworld.wolfram.com/IntersectionArray.html
|
|
149
|
-
|
|
150
|
-
See Also
|
|
151
|
-
--------
|
|
152
|
-
global_parameters
|
|
153
|
-
"""
|
|
154
|
-
# the input graph is very unlikely to be distance-regular: here are the
|
|
155
|
-
# number a(n) of connected simple graphs, and the number b(n) of
|
|
156
|
-
# distance-regular graphs among them:
|
|
157
|
-
#
|
|
158
|
-
# n | 1 2 3 4 5 6 7 8 9 10
|
|
159
|
-
# -----+------------------------------------------------------------------
|
|
160
|
-
# a(n) | 1 1 2 6 21 112 853 11117 261080 11716571 https://oeis.org/A001349
|
|
161
|
-
# b(n) | 1 1 1 2 2 4 2 5 4 7 https://oeis.org/A241814
|
|
162
|
-
#
|
|
163
|
-
# in light of this, let's compute shortest path lengths as we go instead of
|
|
164
|
-
# precomputing them all
|
|
165
|
-
# test for regular graph (all degrees must be equal)
|
|
166
|
-
if not nx.is_regular(G) or not nx.is_connected(G):
|
|
167
|
-
raise nx.NetworkXError("Graph is not distance regular.")
|
|
168
|
-
|
|
169
|
-
path_length = defaultdict(dict)
|
|
170
|
-
bint = {} # 'b' intersection array
|
|
171
|
-
cint = {} # 'c' intersection array
|
|
172
|
-
|
|
173
|
-
# see https://doi.org/10.1016/j.ejc.2004.07.004, Theorem 1.5, page 81:
|
|
174
|
-
# the diameter of a distance-regular graph is at most (8 log_2 n) / 3,
|
|
175
|
-
# so let's compute it as we go in the hope that we can stop early
|
|
176
|
-
diam = 0
|
|
177
|
-
max_diameter_for_dr_graphs = (8 * log(len(G), 2)) / 3
|
|
178
|
-
for u, v in combinations_with_replacement(G, 2):
|
|
179
|
-
# compute needed shortest path lengths
|
|
180
|
-
pl_u = path_length[u]
|
|
181
|
-
if v not in pl_u:
|
|
182
|
-
pl_u.update(nx.single_source_shortest_path_length(G, u))
|
|
183
|
-
for x, distance in pl_u.items():
|
|
184
|
-
path_length[x][u] = distance
|
|
185
|
-
|
|
186
|
-
i = path_length[u][v]
|
|
187
|
-
diam = max(diam, i)
|
|
188
|
-
|
|
189
|
-
# diameter too large: graph can't be distance-regular
|
|
190
|
-
if diam > max_diameter_for_dr_graphs:
|
|
191
|
-
raise nx.NetworkXError("Graph is not distance regular.")
|
|
192
|
-
|
|
193
|
-
vnbrs = G[v]
|
|
194
|
-
# compute needed path lengths
|
|
195
|
-
for n in vnbrs:
|
|
196
|
-
pl_n = path_length[n]
|
|
197
|
-
if u not in pl_n:
|
|
198
|
-
pl_n.update(nx.single_source_shortest_path_length(G, n))
|
|
199
|
-
for x, distance in pl_n.items():
|
|
200
|
-
path_length[x][n] = distance
|
|
201
|
-
|
|
202
|
-
# number of neighbors of v at a distance of i-1 from u
|
|
203
|
-
c = sum(1 for n in vnbrs if pl_u[n] == i - 1)
|
|
204
|
-
# number of neighbors of v at a distance of i+1 from u
|
|
205
|
-
b = sum(1 for n in vnbrs if pl_u[n] == i + 1)
|
|
206
|
-
# b, c are independent of u and v
|
|
207
|
-
if cint.get(i, c) != c or bint.get(i, b) != b:
|
|
208
|
-
raise nx.NetworkXError("Graph is not distance regular")
|
|
209
|
-
bint[i] = b
|
|
210
|
-
cint[i] = c
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
[bint.get(j, 0) for j in range(diam)],
|
|
214
|
-
[cint.get(j + 1, 0) for j in range(diam)],
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
# TODO There is a definition for directed strongly regular graphs.
|
|
219
|
-
@not_implemented_for("directed")
|
|
220
|
-
@not_implemented_for("multigraph")
|
|
221
|
-
@nx._dispatchable
|
|
222
|
-
def is_strongly_regular(G):
|
|
223
|
-
"""Returns True if and only if the given graph is strongly
|
|
224
|
-
regular.
|
|
225
|
-
|
|
226
|
-
An undirected graph is *strongly regular* if
|
|
227
|
-
|
|
228
|
-
* it is regular,
|
|
229
|
-
* each pair of adjacent vertices has the same number of neighbors in
|
|
230
|
-
common,
|
|
231
|
-
* each pair of nonadjacent vertices has the same number of neighbors
|
|
232
|
-
in common.
|
|
233
|
-
|
|
234
|
-
Each strongly regular graph is a distance-regular graph.
|
|
235
|
-
Conversely, if a distance-regular graph has diameter two, then it is
|
|
236
|
-
a strongly regular graph. For more information on distance-regular
|
|
237
|
-
graphs, see :func:`is_distance_regular`.
|
|
238
|
-
|
|
239
|
-
Parameters
|
|
240
|
-
----------
|
|
241
|
-
G : NetworkX graph
|
|
242
|
-
An undirected graph.
|
|
243
|
-
|
|
244
|
-
Returns
|
|
245
|
-
-------
|
|
246
|
-
bool
|
|
247
|
-
Whether `G` is strongly regular.
|
|
248
|
-
|
|
249
|
-
Examples
|
|
250
|
-
--------
|
|
251
|
-
|
|
252
|
-
The cycle graph on five vertices is strongly regular. It is
|
|
253
|
-
two-regular, each pair of adjacent vertices has no shared neighbors,
|
|
254
|
-
and each pair of nonadjacent vertices has one shared neighbor::
|
|
255
|
-
|
|
256
|
-
>>> G = nx.cycle_graph(5)
|
|
257
|
-
>>> nx.is_strongly_regular(G)
|
|
258
|
-
True
|
|
259
|
-
|
|
260
|
-
"""
|
|
261
|
-
# Here is an alternate implementation based directly on the
|
|
262
|
-
# definition of strongly regular graphs:
|
|
263
|
-
#
|
|
264
|
-
# return (all_equal(G.degree().values())
|
|
265
|
-
# and all_equal(len(common_neighbors(G, u, v))
|
|
266
|
-
# for u, v in G.edges())
|
|
267
|
-
# and all_equal(len(common_neighbors(G, u, v))
|
|
268
|
-
# for u, v in non_edges(G)))
|
|
269
|
-
#
|
|
270
|
-
# We instead use the fact that a distance-regular graph of diameter
|
|
271
|
-
# two is strongly regular.
|
|
272
|
-
return is_distance_regular(G) and diameter(G) == 2
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Dominance algorithms.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from functools import reduce
|
|
6
|
-
|
|
7
|
-
import networkx as nx
|
|
8
|
-
from networkx.utils import not_implemented_for
|
|
9
|
-
|
|
10
|
-
__all__ = ["immediate_dominators", "dominance_frontiers"]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@not_implemented_for("undirected")
|
|
14
|
-
@nx._dispatchable
|
|
15
|
-
def immediate_dominators(G, start):
|
|
16
|
-
"""Returns the immediate dominators of all nodes of a directed graph.
|
|
17
|
-
|
|
18
|
-
Parameters
|
|
19
|
-
----------
|
|
20
|
-
G : a DiGraph or MultiDiGraph
|
|
21
|
-
The graph where dominance is to be computed.
|
|
22
|
-
|
|
23
|
-
start : node
|
|
24
|
-
The start node of dominance computation.
|
|
25
|
-
|
|
26
|
-
Returns
|
|
27
|
-
-------
|
|
28
|
-
idom : dict keyed by nodes
|
|
29
|
-
A dict containing the immediate dominators of each node reachable from
|
|
30
|
-
`start`, except for `start` itself.
|
|
31
|
-
|
|
32
|
-
Raises
|
|
33
|
-
------
|
|
34
|
-
NetworkXNotImplemented
|
|
35
|
-
If `G` is undirected.
|
|
36
|
-
|
|
37
|
-
NetworkXError
|
|
38
|
-
If `start` is not in `G`.
|
|
39
|
-
|
|
40
|
-
Notes
|
|
41
|
-
-----
|
|
42
|
-
The immediate dominators are the parents of their corresponding nodes in
|
|
43
|
-
the dominator tree. Every node reachable from `start` has an immediate
|
|
44
|
-
dominator, except for `start` itself.
|
|
45
|
-
|
|
46
|
-
Examples
|
|
47
|
-
--------
|
|
48
|
-
>>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
|
|
49
|
-
>>> sorted(nx.immediate_dominators(G, 1).items())
|
|
50
|
-
[(2, 1), (3, 1), (4, 3), (5, 1)]
|
|
51
|
-
|
|
52
|
-
References
|
|
53
|
-
----------
|
|
54
|
-
.. [1] Cooper, Keith D., Harvey, Timothy J. and Kennedy, Ken.
|
|
55
|
-
"A simple, fast dominance algorithm." (2006).
|
|
56
|
-
https://hdl.handle.net/1911/96345
|
|
57
|
-
.. [2] Lengauer, Thomas; Tarjan, Robert Endre (July 1979).
|
|
58
|
-
"A fast algorithm for finding dominators in a flowgraph".
|
|
59
|
-
ACM Transactions on Programming Languages and Systems. 1 (1): 121--141.
|
|
60
|
-
https://dl.acm.org/doi/10.1145/357062.357071
|
|
61
|
-
"""
|
|
62
|
-
if start not in G:
|
|
63
|
-
raise nx.NetworkXError("start is not in G")
|
|
64
|
-
|
|
65
|
-
idom = {start: None}
|
|
66
|
-
|
|
67
|
-
order = list(nx.dfs_postorder_nodes(G, start))
|
|
68
|
-
dfn = {u: i for i, u in enumerate(order)}
|
|
69
|
-
order.pop()
|
|
70
|
-
order.reverse()
|
|
71
|
-
|
|
72
|
-
def intersect(u, v):
|
|
73
|
-
while u != v:
|
|
74
|
-
while dfn[u] < dfn[v]:
|
|
75
|
-
u = idom[u]
|
|
76
|
-
while dfn[u] > dfn[v]:
|
|
77
|
-
v = idom[v]
|
|
78
|
-
return u
|
|
79
|
-
|
|
80
|
-
changed = True
|
|
81
|
-
while changed:
|
|
82
|
-
changed = False
|
|
83
|
-
for u in order:
|
|
84
|
-
new_idom = reduce(intersect, (v for v in G.pred[u] if v in idom))
|
|
85
|
-
if u not in idom or idom[u] != new_idom:
|
|
86
|
-
idom[u] = new_idom
|
|
87
|
-
changed = True
|
|
88
|
-
|
|
89
|
-
del idom[start]
|
|
90
|
-
return idom
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@not_implemented_for("undirected")
|
|
94
|
-
@nx._dispatchable
|
|
95
|
-
def dominance_frontiers(G, start):
|
|
96
|
-
"""Returns the dominance frontiers of all nodes of a directed graph.
|
|
97
|
-
|
|
98
|
-
Parameters
|
|
99
|
-
----------
|
|
100
|
-
G : a DiGraph or MultiDiGraph
|
|
101
|
-
The graph where dominance is to be computed.
|
|
102
|
-
|
|
103
|
-
start : node
|
|
104
|
-
The start node of dominance computation.
|
|
105
|
-
|
|
106
|
-
Returns
|
|
107
|
-
-------
|
|
108
|
-
df : dict keyed by nodes
|
|
109
|
-
A dict containing the dominance frontiers of each node reachable from
|
|
110
|
-
`start` as lists.
|
|
111
|
-
|
|
112
|
-
Raises
|
|
113
|
-
------
|
|
114
|
-
NetworkXNotImplemented
|
|
115
|
-
If `G` is undirected.
|
|
116
|
-
|
|
117
|
-
NetworkXError
|
|
118
|
-
If `start` is not in `G`.
|
|
119
|
-
|
|
120
|
-
Examples
|
|
121
|
-
--------
|
|
122
|
-
>>> G = nx.DiGraph([(1, 2), (1, 3), (2, 5), (3, 4), (4, 5)])
|
|
123
|
-
>>> sorted((u, sorted(df)) for u, df in nx.dominance_frontiers(G, 1).items())
|
|
124
|
-
[(1, []), (2, [5]), (3, [5]), (4, [5]), (5, [])]
|
|
125
|
-
|
|
126
|
-
References
|
|
127
|
-
----------
|
|
128
|
-
.. [1] Cooper, Keith D., Harvey, Timothy J. and Kennedy, Ken.
|
|
129
|
-
"A simple, fast dominance algorithm." (2006).
|
|
130
|
-
https://hdl.handle.net/1911/96345
|
|
131
|
-
"""
|
|
132
|
-
idom = nx.immediate_dominators(G, start) | {start: None}
|
|
133
|
-
|
|
134
|
-
df = {u: set() for u in idom}
|
|
135
|
-
for u in idom:
|
|
136
|
-
if u == start or len(G.pred[u]) >= 2:
|
|
137
|
-
for v in G.pred[u]:
|
|
138
|
-
if v in idom:
|
|
139
|
-
while v != idom[u]:
|
|
140
|
-
df[v].add(u)
|
|
141
|
-
v = idom[v]
|
|
142
|
-
return df
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
"""Functions for computing dominating sets in a graph."""
|
|
2
|
-
|
|
3
|
-
import math
|
|
4
|
-
from heapq import heappop, heappush
|
|
5
|
-
from itertools import chain, count
|
|
6
|
-
|
|
7
|
-
import networkx as nx
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
"dominating_set",
|
|
11
|
-
"is_dominating_set",
|
|
12
|
-
"connected_dominating_set",
|
|
13
|
-
"is_connected_dominating_set",
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@nx._dispatchable
|
|
18
|
-
def dominating_set(G, start_with=None):
|
|
19
|
-
r"""Finds a dominating set for the graph G.
|
|
20
|
-
|
|
21
|
-
A *dominating set* for a graph with node set *V* is a subset *D* of
|
|
22
|
-
*V* such that every node not in *D* is adjacent to at least one
|
|
23
|
-
member of *D* [1]_.
|
|
24
|
-
|
|
25
|
-
Parameters
|
|
26
|
-
----------
|
|
27
|
-
G : NetworkX graph
|
|
28
|
-
|
|
29
|
-
start_with : node (default=None)
|
|
30
|
-
Node to use as a starting point for the algorithm.
|
|
31
|
-
|
|
32
|
-
Returns
|
|
33
|
-
-------
|
|
34
|
-
D : set
|
|
35
|
-
A dominating set for G.
|
|
36
|
-
|
|
37
|
-
Notes
|
|
38
|
-
-----
|
|
39
|
-
This function is an implementation of algorithm 7 in [2]_ which
|
|
40
|
-
finds some dominating set, not necessarily the smallest one.
|
|
41
|
-
|
|
42
|
-
See also
|
|
43
|
-
--------
|
|
44
|
-
is_dominating_set
|
|
45
|
-
|
|
46
|
-
References
|
|
47
|
-
----------
|
|
48
|
-
.. [1] https://en.wikipedia.org/wiki/Dominating_set
|
|
49
|
-
|
|
50
|
-
.. [2] Abdol-Hossein Esfahanian. Connectivity Algorithms.
|
|
51
|
-
http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf
|
|
52
|
-
|
|
53
|
-
"""
|
|
54
|
-
all_nodes = set(G)
|
|
55
|
-
if start_with is None:
|
|
56
|
-
start_with = nx.utils.arbitrary_element(all_nodes)
|
|
57
|
-
if start_with not in G:
|
|
58
|
-
raise nx.NetworkXError(f"node {start_with} is not in G")
|
|
59
|
-
dominating_set = {start_with}
|
|
60
|
-
dominated_nodes = set(G[start_with])
|
|
61
|
-
remaining_nodes = all_nodes - dominated_nodes - dominating_set
|
|
62
|
-
while remaining_nodes:
|
|
63
|
-
# Choose an arbitrary node and determine its undominated neighbors.
|
|
64
|
-
v = remaining_nodes.pop()
|
|
65
|
-
undominated_nbrs = set(G[v]) - dominating_set
|
|
66
|
-
# Add the node to the dominating set and the neighbors to the
|
|
67
|
-
# dominated set. Finally, remove all of those nodes from the set
|
|
68
|
-
# of remaining nodes.
|
|
69
|
-
dominating_set.add(v)
|
|
70
|
-
dominated_nodes |= undominated_nbrs
|
|
71
|
-
remaining_nodes -= undominated_nbrs
|
|
72
|
-
return dominating_set
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@nx._dispatchable
|
|
76
|
-
def is_dominating_set(G, nbunch):
|
|
77
|
-
"""Checks if `nbunch` is a dominating set for `G`.
|
|
78
|
-
|
|
79
|
-
A *dominating set* for a graph with node set *V* is a subset *D* of
|
|
80
|
-
*V* such that every node not in *D* is adjacent to at least one
|
|
81
|
-
member of *D* [1]_.
|
|
82
|
-
|
|
83
|
-
Parameters
|
|
84
|
-
----------
|
|
85
|
-
G : NetworkX graph
|
|
86
|
-
|
|
87
|
-
nbunch : iterable
|
|
88
|
-
An iterable of nodes in the graph `G`.
|
|
89
|
-
|
|
90
|
-
Returns
|
|
91
|
-
-------
|
|
92
|
-
dominating : bool
|
|
93
|
-
True if `nbunch` is a dominating set of `G`, false otherwise.
|
|
94
|
-
|
|
95
|
-
See also
|
|
96
|
-
--------
|
|
97
|
-
dominating_set
|
|
98
|
-
|
|
99
|
-
References
|
|
100
|
-
----------
|
|
101
|
-
.. [1] https://en.wikipedia.org/wiki/Dominating_set
|
|
102
|
-
|
|
103
|
-
"""
|
|
104
|
-
testset = {n for n in nbunch if n in G}
|
|
105
|
-
nbrs = set(chain.from_iterable(G[n] for n in testset))
|
|
106
|
-
return len(set(G) - testset - nbrs) == 0
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
@nx.utils.not_implemented_for("directed")
|
|
110
|
-
@nx._dispatchable
|
|
111
|
-
def connected_dominating_set(G):
|
|
112
|
-
"""Returns a connected dominating set.
|
|
113
|
-
|
|
114
|
-
A *dominating set* for a graph *G* with node set *V* is a subset *D* of *V*
|
|
115
|
-
such that every node not in *D* is adjacent to at least one member of *D*
|
|
116
|
-
[1]_. A *connected dominating set* is a dominating set *C* that induces a
|
|
117
|
-
connected subgraph of *G* [2]_.
|
|
118
|
-
Note that connected dominating sets are not unique in general and that there
|
|
119
|
-
may be other connected dominating sets.
|
|
120
|
-
|
|
121
|
-
Parameters
|
|
122
|
-
----------
|
|
123
|
-
G : NewtorkX graph
|
|
124
|
-
Undirected connected graph.
|
|
125
|
-
|
|
126
|
-
Returns
|
|
127
|
-
-------
|
|
128
|
-
connected_dominating_set : set
|
|
129
|
-
A dominating set of nodes which induces a connected subgraph of G.
|
|
130
|
-
|
|
131
|
-
Raises
|
|
132
|
-
------
|
|
133
|
-
NetworkXNotImplemented
|
|
134
|
-
If G is directed.
|
|
135
|
-
|
|
136
|
-
NetworkXError
|
|
137
|
-
If G is disconnected.
|
|
138
|
-
|
|
139
|
-
Examples
|
|
140
|
-
________
|
|
141
|
-
>>> G = nx.Graph(
|
|
142
|
-
... [
|
|
143
|
-
... (1, 2),
|
|
144
|
-
... (1, 3),
|
|
145
|
-
... (1, 4),
|
|
146
|
-
... (1, 5),
|
|
147
|
-
... (1, 6),
|
|
148
|
-
... (2, 7),
|
|
149
|
-
... (3, 8),
|
|
150
|
-
... (4, 9),
|
|
151
|
-
... (5, 10),
|
|
152
|
-
... (6, 11),
|
|
153
|
-
... (7, 12),
|
|
154
|
-
... (8, 12),
|
|
155
|
-
... (9, 12),
|
|
156
|
-
... (10, 12),
|
|
157
|
-
... (11, 12),
|
|
158
|
-
... ]
|
|
159
|
-
... )
|
|
160
|
-
>>> nx.connected_dominating_set(G)
|
|
161
|
-
{1, 2, 3, 4, 5, 6, 7}
|
|
162
|
-
|
|
163
|
-
Notes
|
|
164
|
-
-----
|
|
165
|
-
This function implements Algorithm I in its basic version as described
|
|
166
|
-
in [3]_. The idea behind the algorithm is the following: grow a tree *T*,
|
|
167
|
-
starting from a node with maximum degree. Throughout the growing process,
|
|
168
|
-
nonleaf nodes in *T* are our connected dominating set (CDS), leaf nodes in
|
|
169
|
-
*T* are marked as "seen" and nodes in G that are not yet in *T* are marked as
|
|
170
|
-
"unseen". We maintain a max-heap of all "seen" nodes, and track the number
|
|
171
|
-
of "unseen" neighbors for each node. At each step we pop the heap top -- a
|
|
172
|
-
"seen" (leaf) node with maximal number of "unseen" neighbors, add it to the
|
|
173
|
-
CDS and mark all its "unseen" neighbors as "seen". For each one of the newly
|
|
174
|
-
created "seen" nodes, we also decrement the number of "unseen" neighbors for
|
|
175
|
-
all its neighbors. The algorithm terminates when there are no more "unseen"
|
|
176
|
-
nodes.
|
|
177
|
-
Runtime complexity of this implementation is $O(|E|*log|V|)$ (amortized).
|
|
178
|
-
|
|
179
|
-
References
|
|
180
|
-
----------
|
|
181
|
-
.. [1] https://en.wikipedia.org/wiki/Dominating_set
|
|
182
|
-
.. [2] https://en.wikipedia.org/wiki/Connected_dominating_set
|
|
183
|
-
.. [3] Guha, S. and Khuller, S.
|
|
184
|
-
*Approximation Algorithms for Connected Dominating Sets*,
|
|
185
|
-
Algorithmica, 20, 374-387, 1998.
|
|
186
|
-
|
|
187
|
-
"""
|
|
188
|
-
if len(G) == 0:
|
|
189
|
-
return set()
|
|
190
|
-
|
|
191
|
-
if not nx.is_connected(G):
|
|
192
|
-
raise nx.NetworkXError("G must be a connected graph")
|
|
193
|
-
|
|
194
|
-
if len(G) == 1:
|
|
195
|
-
return set(G)
|
|
196
|
-
|
|
197
|
-
G_succ = G._adj # For speed-up
|
|
198
|
-
|
|
199
|
-
# Use the count c to avoid comparing nodes
|
|
200
|
-
c = count()
|
|
201
|
-
|
|
202
|
-
# Keep track of the number of unseen nodes adjacent to each node
|
|
203
|
-
unseen_degree = dict(G.degree)
|
|
204
|
-
|
|
205
|
-
# Find node with highest degree and update its neighbors
|
|
206
|
-
(max_deg_node, max_deg) = max(unseen_degree.items(), key=lambda x: x[1])
|
|
207
|
-
for nbr in G_succ[max_deg_node]:
|
|
208
|
-
unseen_degree[nbr] -= 1
|
|
209
|
-
|
|
210
|
-
# Initially all nodes except max_deg_node are unseen
|
|
211
|
-
unseen = set(G) - {max_deg_node}
|
|
212
|
-
|
|
213
|
-
# We want a max-heap of the unseen-degree using heapq, which is a min-heap
|
|
214
|
-
# So we store the negative of the unseen-degree
|
|
215
|
-
seen = [(-max_deg, next(c), max_deg_node)]
|
|
216
|
-
|
|
217
|
-
connected_dominating_set = set()
|
|
218
|
-
|
|
219
|
-
# Main loop
|
|
220
|
-
while unseen:
|
|
221
|
-
(neg_deg, cnt, u) = heappop(seen)
|
|
222
|
-
# Check if u's unseen-degree changed while in the heap
|
|
223
|
-
if -neg_deg > unseen_degree[u]:
|
|
224
|
-
heappush(seen, (-unseen_degree[u], cnt, u))
|
|
225
|
-
continue
|
|
226
|
-
# Mark all u's unseen neighbors as seen and add them to the heap
|
|
227
|
-
for v in G_succ[u]:
|
|
228
|
-
if v in unseen:
|
|
229
|
-
unseen.remove(v)
|
|
230
|
-
for nbr in G_succ[v]:
|
|
231
|
-
unseen_degree[nbr] -= 1
|
|
232
|
-
heappush(seen, (-unseen_degree[v], next(c), v))
|
|
233
|
-
# Add u to the dominating set
|
|
234
|
-
connected_dominating_set.add(u)
|
|
235
|
-
|
|
236
|
-
return connected_dominating_set
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
@nx.utils.not_implemented_for("directed")
|
|
240
|
-
@nx._dispatchable
|
|
241
|
-
def is_connected_dominating_set(G, nbunch):
|
|
242
|
-
"""Checks if `nbunch` is a connected dominating set for `G`.
|
|
243
|
-
|
|
244
|
-
A *dominating set* for a graph *G* with node set *V* is a subset *D* of
|
|
245
|
-
*V* such that every node not in *D* is adjacent to at least one
|
|
246
|
-
member of *D* [1]_. A *connected dominating set* is a dominating
|
|
247
|
-
set *C* that induces a connected subgraph of *G* [2]_.
|
|
248
|
-
|
|
249
|
-
Parameters
|
|
250
|
-
----------
|
|
251
|
-
G : NetworkX graph
|
|
252
|
-
Undirected graph.
|
|
253
|
-
|
|
254
|
-
nbunch : iterable
|
|
255
|
-
An iterable of nodes in the graph `G`.
|
|
256
|
-
|
|
257
|
-
Returns
|
|
258
|
-
-------
|
|
259
|
-
connected_dominating : bool
|
|
260
|
-
True if `nbunch` is connected dominating set of `G`, false otherwise.
|
|
261
|
-
|
|
262
|
-
References
|
|
263
|
-
----------
|
|
264
|
-
.. [1] https://en.wikipedia.org/wiki/Dominating_set
|
|
265
|
-
.. [2] https://en.wikipedia.org/wiki/Connected_dominating_set
|
|
266
|
-
|
|
267
|
-
"""
|
|
268
|
-
return nx.is_dominating_set(G, nbunch) and nx.is_connected(nx.subgraph(G, nbunch))
|