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,127 +0,0 @@
|
|
|
1
|
-
"""Generators of x-y pairs of node data."""
|
|
2
|
-
|
|
3
|
-
import networkx as nx
|
|
4
|
-
|
|
5
|
-
__all__ = ["node_attribute_xy", "node_degree_xy"]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@nx._dispatchable(node_attrs="attribute")
|
|
9
|
-
def node_attribute_xy(G, attribute, nodes=None):
|
|
10
|
-
"""Yields 2-tuples of node attribute values for all edges in `G`.
|
|
11
|
-
|
|
12
|
-
This generator yields, for each edge in `G` incident to a node in `nodes`,
|
|
13
|
-
a 2-tuple of form ``(attribute value, attribute value)`` for the parameter
|
|
14
|
-
specified node-attribute.
|
|
15
|
-
|
|
16
|
-
Parameters
|
|
17
|
-
----------
|
|
18
|
-
G: NetworkX graph
|
|
19
|
-
|
|
20
|
-
attribute: key
|
|
21
|
-
The node attribute key.
|
|
22
|
-
|
|
23
|
-
nodes: list or iterable (optional)
|
|
24
|
-
Use only edges that are incident to specified nodes.
|
|
25
|
-
The default is all nodes.
|
|
26
|
-
|
|
27
|
-
Yields
|
|
28
|
-
------
|
|
29
|
-
(x, y): 2-tuple
|
|
30
|
-
Generates 2-tuple of (attribute, attribute) values.
|
|
31
|
-
|
|
32
|
-
Examples
|
|
33
|
-
--------
|
|
34
|
-
>>> G = nx.DiGraph()
|
|
35
|
-
>>> G.add_node(1, color="red")
|
|
36
|
-
>>> G.add_node(2, color="blue")
|
|
37
|
-
>>> G.add_node(3, color="green")
|
|
38
|
-
>>> G.add_edge(1, 2)
|
|
39
|
-
>>> list(nx.node_attribute_xy(G, "color"))
|
|
40
|
-
[('red', 'blue')]
|
|
41
|
-
|
|
42
|
-
Notes
|
|
43
|
-
-----
|
|
44
|
-
For undirected graphs, each edge is produced twice, once for each edge
|
|
45
|
-
representation (u, v) and (v, u), with the exception of self-loop edges
|
|
46
|
-
which only appear once.
|
|
47
|
-
"""
|
|
48
|
-
if nodes is None:
|
|
49
|
-
nodes = set(G)
|
|
50
|
-
else:
|
|
51
|
-
nodes = set(nodes)
|
|
52
|
-
Gnodes = G.nodes
|
|
53
|
-
for u, nbrsdict in G.adjacency():
|
|
54
|
-
if u not in nodes:
|
|
55
|
-
continue
|
|
56
|
-
uattr = Gnodes[u].get(attribute, None)
|
|
57
|
-
if G.is_multigraph():
|
|
58
|
-
for v, keys in nbrsdict.items():
|
|
59
|
-
vattr = Gnodes[v].get(attribute, None)
|
|
60
|
-
for _ in keys:
|
|
61
|
-
yield (uattr, vattr)
|
|
62
|
-
else:
|
|
63
|
-
for v in nbrsdict:
|
|
64
|
-
vattr = Gnodes[v].get(attribute, None)
|
|
65
|
-
yield (uattr, vattr)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
@nx._dispatchable(edge_attrs="weight")
|
|
69
|
-
def node_degree_xy(G, x="out", y="in", weight=None, nodes=None):
|
|
70
|
-
"""Yields 2-tuples of ``(degree, degree)`` values for edges in `G`.
|
|
71
|
-
|
|
72
|
-
This generator yields, for each edge in `G` incident to a node in `nodes`,
|
|
73
|
-
a 2-tuple of form ``(degree, degree)``. The node degrees are weighted
|
|
74
|
-
when a `weight` attribute is specified.
|
|
75
|
-
|
|
76
|
-
Parameters
|
|
77
|
-
----------
|
|
78
|
-
G: NetworkX graph
|
|
79
|
-
|
|
80
|
-
x: string ('in','out')
|
|
81
|
-
The degree type for source node (directed graphs only).
|
|
82
|
-
|
|
83
|
-
y: string ('in','out')
|
|
84
|
-
The degree type for target node (directed graphs only).
|
|
85
|
-
|
|
86
|
-
weight: string or None, optional (default=None)
|
|
87
|
-
The edge attribute that holds the numerical value used
|
|
88
|
-
as a weight. If None, then each edge has weight 1.
|
|
89
|
-
The degree is the sum of the edge weights adjacent to the node.
|
|
90
|
-
|
|
91
|
-
nodes: list or iterable (optional)
|
|
92
|
-
Use only edges that are adjacency to specified nodes.
|
|
93
|
-
The default is all nodes.
|
|
94
|
-
|
|
95
|
-
Yields
|
|
96
|
-
------
|
|
97
|
-
(x, y): 2-tuple
|
|
98
|
-
Generates 2-tuple of (degree, degree) values.
|
|
99
|
-
|
|
100
|
-
Examples
|
|
101
|
-
--------
|
|
102
|
-
>>> G = nx.DiGraph()
|
|
103
|
-
>>> G.add_edge(1, 2)
|
|
104
|
-
>>> list(nx.node_degree_xy(G, x="out", y="in"))
|
|
105
|
-
[(1, 1)]
|
|
106
|
-
>>> list(nx.node_degree_xy(G, x="in", y="out"))
|
|
107
|
-
[(0, 0)]
|
|
108
|
-
|
|
109
|
-
Notes
|
|
110
|
-
-----
|
|
111
|
-
For undirected graphs, each edge is produced twice, once for each edge
|
|
112
|
-
representation (u, v) and (v, u), with the exception of self-loop edges
|
|
113
|
-
which only appear once.
|
|
114
|
-
"""
|
|
115
|
-
nodes = set(G) if nodes is None else set(nodes)
|
|
116
|
-
if G.is_directed():
|
|
117
|
-
direction = {"out": G.out_degree, "in": G.in_degree}
|
|
118
|
-
xdeg = direction[x]
|
|
119
|
-
ydeg = direction[y]
|
|
120
|
-
else:
|
|
121
|
-
xdeg = ydeg = G.degree
|
|
122
|
-
|
|
123
|
-
for u, degu in xdeg(nodes, weight=weight):
|
|
124
|
-
# use G.edges to treat multigraphs correctly
|
|
125
|
-
neighbors = (nbr for _, nbr in G.edges(u) if nbr in nodes)
|
|
126
|
-
for _, degv in ydeg(neighbors, weight=weight):
|
|
127
|
-
yield degu, degv
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Algorithms for asteroidal triples and asteroidal numbers in graphs.
|
|
3
|
-
|
|
4
|
-
An asteroidal triple in a graph G is a set of three non-adjacent vertices
|
|
5
|
-
u, v and w such that there exist a path between any two of them that avoids
|
|
6
|
-
closed neighborhood of the third. More formally, v_j, v_k belongs to the same
|
|
7
|
-
connected component of G - N[v_i], where N[v_i] denotes the closed neighborhood
|
|
8
|
-
of v_i. A graph which does not contain any asteroidal triples is called
|
|
9
|
-
an AT-free graph. The class of AT-free graphs is a graph class for which
|
|
10
|
-
many NP-complete problems are solvable in polynomial time. Amongst them,
|
|
11
|
-
independent set and coloring.
|
|
12
|
-
"""
|
|
13
|
-
|
|
14
|
-
import networkx as nx
|
|
15
|
-
from networkx.utils import not_implemented_for
|
|
16
|
-
|
|
17
|
-
__all__ = ["is_at_free", "find_asteroidal_triple"]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@not_implemented_for("directed")
|
|
21
|
-
@not_implemented_for("multigraph")
|
|
22
|
-
@nx._dispatchable
|
|
23
|
-
def find_asteroidal_triple(G):
|
|
24
|
-
r"""Find an asteroidal triple in the given graph.
|
|
25
|
-
|
|
26
|
-
An asteroidal triple is a triple of non-adjacent vertices such that
|
|
27
|
-
there exists a path between any two of them which avoids the closed
|
|
28
|
-
neighborhood of the third. It checks all independent triples of vertices
|
|
29
|
-
and whether they are an asteroidal triple or not. This is done with the
|
|
30
|
-
help of a data structure called a component structure.
|
|
31
|
-
A component structure encodes information about which vertices belongs to
|
|
32
|
-
the same connected component when the closed neighborhood of a given vertex
|
|
33
|
-
is removed from the graph. The algorithm used to check is the trivial
|
|
34
|
-
one, outlined in [1]_, which has a runtime of
|
|
35
|
-
:math:`O(|V||\overline{E} + |V||E|)`, where the second term is the
|
|
36
|
-
creation of the component structure.
|
|
37
|
-
|
|
38
|
-
Parameters
|
|
39
|
-
----------
|
|
40
|
-
G : NetworkX Graph
|
|
41
|
-
The graph to check whether is AT-free or not
|
|
42
|
-
|
|
43
|
-
Returns
|
|
44
|
-
-------
|
|
45
|
-
list or None
|
|
46
|
-
An asteroidal triple is returned as a list of nodes. If no asteroidal
|
|
47
|
-
triple exists, i.e. the graph is AT-free, then None is returned.
|
|
48
|
-
|
|
49
|
-
Notes
|
|
50
|
-
-----
|
|
51
|
-
The component structure and the algorithm is described in [1]_. The current
|
|
52
|
-
implementation implements the trivial algorithm for simple graphs.
|
|
53
|
-
|
|
54
|
-
References
|
|
55
|
-
----------
|
|
56
|
-
.. [1] Ekkehard Köhler,
|
|
57
|
-
"Recognizing Graphs without asteroidal triples",
|
|
58
|
-
Journal of Discrete Algorithms 2, pages 439-452, 2004.
|
|
59
|
-
https://www.sciencedirect.com/science/article/pii/S157086670400019X
|
|
60
|
-
"""
|
|
61
|
-
V = set(G.nodes)
|
|
62
|
-
|
|
63
|
-
if len(V) < 6:
|
|
64
|
-
# An asteroidal triple cannot exist in a graph with 5 or less vertices.
|
|
65
|
-
return None
|
|
66
|
-
|
|
67
|
-
component_structure = create_component_structure(G)
|
|
68
|
-
|
|
69
|
-
for u, v in nx.non_edges(G):
|
|
70
|
-
u_neighborhood = set(G[u]).union([u])
|
|
71
|
-
v_neighborhood = set(G[v]).union([v])
|
|
72
|
-
union_of_neighborhoods = u_neighborhood.union(v_neighborhood)
|
|
73
|
-
for w in V - union_of_neighborhoods:
|
|
74
|
-
# Check for each pair of vertices whether they belong to the
|
|
75
|
-
# same connected component when the closed neighborhood of the
|
|
76
|
-
# third is removed.
|
|
77
|
-
if (
|
|
78
|
-
component_structure[u][v] == component_structure[u][w]
|
|
79
|
-
and component_structure[v][u] == component_structure[v][w]
|
|
80
|
-
and component_structure[w][u] == component_structure[w][v]
|
|
81
|
-
):
|
|
82
|
-
return [u, v, w]
|
|
83
|
-
return None
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@not_implemented_for("directed")
|
|
87
|
-
@not_implemented_for("multigraph")
|
|
88
|
-
@nx._dispatchable
|
|
89
|
-
def is_at_free(G):
|
|
90
|
-
"""Check if a graph is AT-free.
|
|
91
|
-
|
|
92
|
-
The method uses the `find_asteroidal_triple` method to recognize
|
|
93
|
-
an AT-free graph. If no asteroidal triple is found the graph is
|
|
94
|
-
AT-free and True is returned. If at least one asteroidal triple is
|
|
95
|
-
found the graph is not AT-free and False is returned.
|
|
96
|
-
|
|
97
|
-
Parameters
|
|
98
|
-
----------
|
|
99
|
-
G : NetworkX Graph
|
|
100
|
-
The graph to check whether is AT-free or not.
|
|
101
|
-
|
|
102
|
-
Returns
|
|
103
|
-
-------
|
|
104
|
-
bool
|
|
105
|
-
True if G is AT-free and False otherwise.
|
|
106
|
-
|
|
107
|
-
Examples
|
|
108
|
-
--------
|
|
109
|
-
>>> G = nx.Graph([(0, 1), (0, 2), (1, 2), (1, 3), (1, 4), (4, 5)])
|
|
110
|
-
>>> nx.is_at_free(G)
|
|
111
|
-
True
|
|
112
|
-
|
|
113
|
-
>>> G = nx.cycle_graph(6)
|
|
114
|
-
>>> nx.is_at_free(G)
|
|
115
|
-
False
|
|
116
|
-
"""
|
|
117
|
-
return find_asteroidal_triple(G) is None
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
@not_implemented_for("directed")
|
|
121
|
-
@not_implemented_for("multigraph")
|
|
122
|
-
@nx._dispatchable
|
|
123
|
-
def create_component_structure(G):
|
|
124
|
-
r"""Create component structure for G.
|
|
125
|
-
|
|
126
|
-
A *component structure* is an `nxn` array, denoted `c`, where `n` is
|
|
127
|
-
the number of vertices, where each row and column corresponds to a vertex.
|
|
128
|
-
|
|
129
|
-
.. math::
|
|
130
|
-
c_{uv} = \begin{cases} 0, if v \in N[u] \\
|
|
131
|
-
k, if v \in component k of G \setminus N[u] \end{cases}
|
|
132
|
-
|
|
133
|
-
Where `k` is an arbitrary label for each component. The structure is used
|
|
134
|
-
to simplify the detection of asteroidal triples.
|
|
135
|
-
|
|
136
|
-
Parameters
|
|
137
|
-
----------
|
|
138
|
-
G : NetworkX Graph
|
|
139
|
-
Undirected, simple graph.
|
|
140
|
-
|
|
141
|
-
Returns
|
|
142
|
-
-------
|
|
143
|
-
component_structure : dictionary
|
|
144
|
-
A dictionary of dictionaries, keyed by pairs of vertices.
|
|
145
|
-
|
|
146
|
-
"""
|
|
147
|
-
V = set(G.nodes)
|
|
148
|
-
component_structure = {}
|
|
149
|
-
for v in V:
|
|
150
|
-
label = 0
|
|
151
|
-
closed_neighborhood = set(G[v]).union({v})
|
|
152
|
-
row_dict = {}
|
|
153
|
-
for u in closed_neighborhood:
|
|
154
|
-
row_dict[u] = 0
|
|
155
|
-
|
|
156
|
-
G_reduced = G.subgraph(set(G.nodes) - closed_neighborhood)
|
|
157
|
-
for cc in nx.connected_components(G_reduced):
|
|
158
|
-
label += 1
|
|
159
|
-
for u in cc:
|
|
160
|
-
row_dict[u] = label
|
|
161
|
-
|
|
162
|
-
component_structure[v] = row_dict
|
|
163
|
-
|
|
164
|
-
return component_structure
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
r"""This module provides functions and operations for bipartite
|
|
2
|
-
graphs. Bipartite graphs `B = (U, V, E)` have two node sets `U,V` and edges in
|
|
3
|
-
`E` that only connect nodes from opposite sets. It is common in the literature
|
|
4
|
-
to use an spatial analogy referring to the two node sets as top and bottom nodes.
|
|
5
|
-
|
|
6
|
-
The bipartite algorithms are not imported into the networkx namespace
|
|
7
|
-
at the top level so the easiest way to use them is with:
|
|
8
|
-
|
|
9
|
-
>>> from networkx.algorithms import bipartite
|
|
10
|
-
|
|
11
|
-
NetworkX does not have a custom bipartite graph class but the Graph()
|
|
12
|
-
or DiGraph() classes can be used to represent bipartite graphs. However,
|
|
13
|
-
you have to keep track of which set each node belongs to, and make
|
|
14
|
-
sure that there is no edge between nodes of the same set. The convention used
|
|
15
|
-
in NetworkX is to use a node attribute named `bipartite` with values 0 or 1 to
|
|
16
|
-
identify the sets each node belongs to. This convention is not enforced in
|
|
17
|
-
the source code of bipartite functions, it's only a recommendation.
|
|
18
|
-
|
|
19
|
-
For example:
|
|
20
|
-
|
|
21
|
-
>>> B = nx.Graph()
|
|
22
|
-
>>> # Add nodes with the node attribute "bipartite"
|
|
23
|
-
>>> B.add_nodes_from([1, 2, 3, 4], bipartite=0)
|
|
24
|
-
>>> B.add_nodes_from(["a", "b", "c"], bipartite=1)
|
|
25
|
-
>>> # Add edges only between nodes of opposite node sets
|
|
26
|
-
>>> B.add_edges_from([(1, "a"), (1, "b"), (2, "b"), (2, "c"), (3, "c"), (4, "a")])
|
|
27
|
-
|
|
28
|
-
Many algorithms of the bipartite module of NetworkX require, as an argument, a
|
|
29
|
-
container with all the nodes that belong to one set, in addition to the bipartite
|
|
30
|
-
graph `B`. The functions in the bipartite package do not check that the node set
|
|
31
|
-
is actually correct nor that the input graph is actually bipartite.
|
|
32
|
-
If `B` is connected, you can find the two node sets using a two-coloring
|
|
33
|
-
algorithm:
|
|
34
|
-
|
|
35
|
-
>>> nx.is_connected(B)
|
|
36
|
-
True
|
|
37
|
-
>>> bottom_nodes, top_nodes = bipartite.sets(B)
|
|
38
|
-
|
|
39
|
-
However, if the input graph is not connected, there are more than one possible
|
|
40
|
-
colorations. This is the reason why we require the user to pass a container
|
|
41
|
-
with all nodes of one bipartite node set as an argument to most bipartite
|
|
42
|
-
functions. In the face of ambiguity, we refuse the temptation to guess and
|
|
43
|
-
raise an :exc:`AmbiguousSolution <networkx.AmbiguousSolution>`
|
|
44
|
-
Exception if the input graph for
|
|
45
|
-
:func:`bipartite.sets <networkx.algorithms.bipartite.basic.sets>`
|
|
46
|
-
is disconnected.
|
|
47
|
-
|
|
48
|
-
Using the `bipartite` node attribute, you can easily get the two node sets:
|
|
49
|
-
|
|
50
|
-
>>> top_nodes = {n for n, d in B.nodes(data=True) if d["bipartite"] == 0}
|
|
51
|
-
>>> bottom_nodes = set(B) - top_nodes
|
|
52
|
-
|
|
53
|
-
So you can easily use the bipartite algorithms that require, as an argument, a
|
|
54
|
-
container with all nodes that belong to one node set:
|
|
55
|
-
|
|
56
|
-
>>> print(round(bipartite.density(B, bottom_nodes), 2))
|
|
57
|
-
0.5
|
|
58
|
-
>>> G = bipartite.projected_graph(B, top_nodes)
|
|
59
|
-
|
|
60
|
-
All bipartite graph generators in NetworkX build bipartite graphs with the
|
|
61
|
-
`bipartite` node attribute. Thus, you can use the same approach:
|
|
62
|
-
|
|
63
|
-
>>> RB = bipartite.random_graph(5, 7, 0.2)
|
|
64
|
-
>>> RB_top = {n for n, d in RB.nodes(data=True) if d["bipartite"] == 0}
|
|
65
|
-
>>> RB_bottom = set(RB) - RB_top
|
|
66
|
-
>>> list(RB_top)
|
|
67
|
-
[0, 1, 2, 3, 4]
|
|
68
|
-
>>> list(RB_bottom)
|
|
69
|
-
[5, 6, 7, 8, 9, 10, 11]
|
|
70
|
-
|
|
71
|
-
For other bipartite graph generators see
|
|
72
|
-
:mod:`Generators <networkx.algorithms.bipartite.generators>`.
|
|
73
|
-
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
from networkx.algorithms.bipartite.basic import *
|
|
77
|
-
from networkx.algorithms.bipartite.centrality import *
|
|
78
|
-
from networkx.algorithms.bipartite.cluster import *
|
|
79
|
-
from networkx.algorithms.bipartite.covering import *
|
|
80
|
-
from networkx.algorithms.bipartite.edgelist import *
|
|
81
|
-
from networkx.algorithms.bipartite.matching import *
|
|
82
|
-
from networkx.algorithms.bipartite.matrix import *
|
|
83
|
-
from networkx.algorithms.bipartite.projection import *
|
|
84
|
-
from networkx.algorithms.bipartite.redundancy import *
|
|
85
|
-
from networkx.algorithms.bipartite.spectral import *
|
|
86
|
-
from networkx.algorithms.bipartite.generators import *
|
|
87
|
-
from networkx.algorithms.bipartite.extendability import *
|
|
88
|
-
from networkx.algorithms.bipartite.link_analysis import *
|
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
==========================
|
|
3
|
-
Bipartite Graph Algorithms
|
|
4
|
-
==========================
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import networkx as nx
|
|
8
|
-
from networkx.algorithms.components import connected_components
|
|
9
|
-
from networkx.exception import AmbiguousSolution
|
|
10
|
-
|
|
11
|
-
__all__ = [
|
|
12
|
-
"is_bipartite",
|
|
13
|
-
"is_bipartite_node_set",
|
|
14
|
-
"color",
|
|
15
|
-
"sets",
|
|
16
|
-
"density",
|
|
17
|
-
"degrees",
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@nx._dispatchable
|
|
22
|
-
def color(G):
|
|
23
|
-
"""Returns a two-coloring of the graph.
|
|
24
|
-
|
|
25
|
-
Raises an exception if the graph is not bipartite.
|
|
26
|
-
|
|
27
|
-
Parameters
|
|
28
|
-
----------
|
|
29
|
-
G : NetworkX graph
|
|
30
|
-
|
|
31
|
-
Returns
|
|
32
|
-
-------
|
|
33
|
-
color : dictionary
|
|
34
|
-
A dictionary keyed by node with a 1 or 0 as data for each node color.
|
|
35
|
-
|
|
36
|
-
Raises
|
|
37
|
-
------
|
|
38
|
-
NetworkXError
|
|
39
|
-
If the graph is not two-colorable.
|
|
40
|
-
|
|
41
|
-
Examples
|
|
42
|
-
--------
|
|
43
|
-
>>> from networkx.algorithms import bipartite
|
|
44
|
-
>>> G = nx.path_graph(4)
|
|
45
|
-
>>> c = bipartite.color(G)
|
|
46
|
-
>>> print(c)
|
|
47
|
-
{0: 1, 1: 0, 2: 1, 3: 0}
|
|
48
|
-
|
|
49
|
-
You can use this to set a node attribute indicating the bipartite set:
|
|
50
|
-
|
|
51
|
-
>>> nx.set_node_attributes(G, c, "bipartite")
|
|
52
|
-
>>> print(G.nodes[0]["bipartite"])
|
|
53
|
-
1
|
|
54
|
-
>>> print(G.nodes[1]["bipartite"])
|
|
55
|
-
0
|
|
56
|
-
"""
|
|
57
|
-
if G.is_directed():
|
|
58
|
-
import itertools
|
|
59
|
-
|
|
60
|
-
def neighbors(v):
|
|
61
|
-
return itertools.chain.from_iterable([G.predecessors(v), G.successors(v)])
|
|
62
|
-
|
|
63
|
-
else:
|
|
64
|
-
neighbors = G.neighbors
|
|
65
|
-
|
|
66
|
-
color = {}
|
|
67
|
-
for n in G: # handle disconnected graphs
|
|
68
|
-
if n in color or len(G[n]) == 0: # skip isolates
|
|
69
|
-
continue
|
|
70
|
-
queue = [n]
|
|
71
|
-
color[n] = 1 # nodes seen with color (1 or 0)
|
|
72
|
-
while queue:
|
|
73
|
-
v = queue.pop()
|
|
74
|
-
c = 1 - color[v] # opposite color of node v
|
|
75
|
-
for w in neighbors(v):
|
|
76
|
-
if w in color:
|
|
77
|
-
if color[w] == color[v]:
|
|
78
|
-
raise nx.NetworkXError("Graph is not bipartite.")
|
|
79
|
-
else:
|
|
80
|
-
color[w] = c
|
|
81
|
-
queue.append(w)
|
|
82
|
-
# color isolates with 0
|
|
83
|
-
color.update(dict.fromkeys(nx.isolates(G), 0))
|
|
84
|
-
return color
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@nx._dispatchable
|
|
88
|
-
def is_bipartite(G):
|
|
89
|
-
"""Returns True if graph G is bipartite, False if not.
|
|
90
|
-
|
|
91
|
-
Parameters
|
|
92
|
-
----------
|
|
93
|
-
G : NetworkX graph
|
|
94
|
-
|
|
95
|
-
Examples
|
|
96
|
-
--------
|
|
97
|
-
>>> from networkx.algorithms import bipartite
|
|
98
|
-
>>> G = nx.path_graph(4)
|
|
99
|
-
>>> print(bipartite.is_bipartite(G))
|
|
100
|
-
True
|
|
101
|
-
|
|
102
|
-
See Also
|
|
103
|
-
--------
|
|
104
|
-
color, is_bipartite_node_set
|
|
105
|
-
"""
|
|
106
|
-
try:
|
|
107
|
-
color(G)
|
|
108
|
-
return True
|
|
109
|
-
except nx.NetworkXError:
|
|
110
|
-
return False
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@nx._dispatchable
|
|
114
|
-
def is_bipartite_node_set(G, nodes):
|
|
115
|
-
"""Returns True if nodes and G/nodes are a bipartition of G.
|
|
116
|
-
|
|
117
|
-
Parameters
|
|
118
|
-
----------
|
|
119
|
-
G : NetworkX graph
|
|
120
|
-
|
|
121
|
-
nodes: list or container
|
|
122
|
-
Check if nodes are a one of a bipartite set.
|
|
123
|
-
|
|
124
|
-
Examples
|
|
125
|
-
--------
|
|
126
|
-
>>> from networkx.algorithms import bipartite
|
|
127
|
-
>>> G = nx.path_graph(4)
|
|
128
|
-
>>> X = set([1, 3])
|
|
129
|
-
>>> bipartite.is_bipartite_node_set(G, X)
|
|
130
|
-
True
|
|
131
|
-
|
|
132
|
-
Notes
|
|
133
|
-
-----
|
|
134
|
-
An exception is raised if the input nodes are not distinct, because in this
|
|
135
|
-
case some bipartite algorithms will yield incorrect results.
|
|
136
|
-
For connected graphs the bipartite sets are unique. This function handles
|
|
137
|
-
disconnected graphs.
|
|
138
|
-
"""
|
|
139
|
-
S = set(nodes)
|
|
140
|
-
|
|
141
|
-
if len(S) < len(nodes):
|
|
142
|
-
# this should maybe just return False?
|
|
143
|
-
raise AmbiguousSolution(
|
|
144
|
-
"The input node set contains duplicates.\n"
|
|
145
|
-
"This may lead to incorrect results when using it in bipartite algorithms.\n"
|
|
146
|
-
"Consider using set(nodes) as the input"
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
for CC in (G.subgraph(c).copy() for c in connected_components(G)):
|
|
150
|
-
X, Y = sets(CC)
|
|
151
|
-
if not (
|
|
152
|
-
(X.issubset(S) and Y.isdisjoint(S)) or (Y.issubset(S) and X.isdisjoint(S))
|
|
153
|
-
):
|
|
154
|
-
return False
|
|
155
|
-
return True
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
@nx._dispatchable
|
|
159
|
-
def sets(G, top_nodes=None):
|
|
160
|
-
"""Returns bipartite node sets of graph G.
|
|
161
|
-
|
|
162
|
-
Raises an exception if the graph is not bipartite or if the input
|
|
163
|
-
graph is disconnected and thus more than one valid solution exists.
|
|
164
|
-
See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
|
|
165
|
-
for further details on how bipartite graphs are handled in NetworkX.
|
|
166
|
-
|
|
167
|
-
Parameters
|
|
168
|
-
----------
|
|
169
|
-
G : NetworkX graph
|
|
170
|
-
|
|
171
|
-
top_nodes : container, optional
|
|
172
|
-
Container with all nodes in one bipartite node set. If not supplied
|
|
173
|
-
it will be computed. But if more than one solution exists an exception
|
|
174
|
-
will be raised.
|
|
175
|
-
|
|
176
|
-
Returns
|
|
177
|
-
-------
|
|
178
|
-
X : set
|
|
179
|
-
Nodes from one side of the bipartite graph.
|
|
180
|
-
Y : set
|
|
181
|
-
Nodes from the other side.
|
|
182
|
-
|
|
183
|
-
Raises
|
|
184
|
-
------
|
|
185
|
-
AmbiguousSolution
|
|
186
|
-
Raised if the input bipartite graph is disconnected and no container
|
|
187
|
-
with all nodes in one bipartite set is provided. When determining
|
|
188
|
-
the nodes in each bipartite set more than one valid solution is
|
|
189
|
-
possible if the input graph is disconnected.
|
|
190
|
-
NetworkXError
|
|
191
|
-
Raised if the input graph is not bipartite.
|
|
192
|
-
|
|
193
|
-
Examples
|
|
194
|
-
--------
|
|
195
|
-
>>> from networkx.algorithms import bipartite
|
|
196
|
-
>>> G = nx.path_graph(4)
|
|
197
|
-
>>> X, Y = bipartite.sets(G)
|
|
198
|
-
>>> list(X)
|
|
199
|
-
[0, 2]
|
|
200
|
-
>>> list(Y)
|
|
201
|
-
[1, 3]
|
|
202
|
-
|
|
203
|
-
See Also
|
|
204
|
-
--------
|
|
205
|
-
color
|
|
206
|
-
|
|
207
|
-
"""
|
|
208
|
-
if G.is_directed():
|
|
209
|
-
is_connected = nx.is_weakly_connected
|
|
210
|
-
else:
|
|
211
|
-
is_connected = nx.is_connected
|
|
212
|
-
if top_nodes is not None:
|
|
213
|
-
X = set(top_nodes)
|
|
214
|
-
Y = set(G) - X
|
|
215
|
-
else:
|
|
216
|
-
if not is_connected(G):
|
|
217
|
-
msg = "Disconnected graph: Ambiguous solution for bipartite sets."
|
|
218
|
-
raise nx.AmbiguousSolution(msg)
|
|
219
|
-
c = color(G)
|
|
220
|
-
X = {n for n, is_top in c.items() if is_top}
|
|
221
|
-
Y = {n for n, is_top in c.items() if not is_top}
|
|
222
|
-
return (X, Y)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
@nx._dispatchable(graphs="B")
|
|
226
|
-
def density(B, nodes):
|
|
227
|
-
"""Returns density of bipartite graph B.
|
|
228
|
-
|
|
229
|
-
Parameters
|
|
230
|
-
----------
|
|
231
|
-
B : NetworkX graph
|
|
232
|
-
|
|
233
|
-
nodes: list or container
|
|
234
|
-
Nodes in one node set of the bipartite graph.
|
|
235
|
-
|
|
236
|
-
Returns
|
|
237
|
-
-------
|
|
238
|
-
d : float
|
|
239
|
-
The bipartite density
|
|
240
|
-
|
|
241
|
-
Examples
|
|
242
|
-
--------
|
|
243
|
-
>>> from networkx.algorithms import bipartite
|
|
244
|
-
>>> G = nx.complete_bipartite_graph(3, 2)
|
|
245
|
-
>>> X = set([0, 1, 2])
|
|
246
|
-
>>> bipartite.density(G, X)
|
|
247
|
-
1.0
|
|
248
|
-
>>> Y = set([3, 4])
|
|
249
|
-
>>> bipartite.density(G, Y)
|
|
250
|
-
1.0
|
|
251
|
-
|
|
252
|
-
Notes
|
|
253
|
-
-----
|
|
254
|
-
The container of nodes passed as argument must contain all nodes
|
|
255
|
-
in one of the two bipartite node sets to avoid ambiguity in the
|
|
256
|
-
case of disconnected graphs.
|
|
257
|
-
See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
|
|
258
|
-
for further details on how bipartite graphs are handled in NetworkX.
|
|
259
|
-
|
|
260
|
-
See Also
|
|
261
|
-
--------
|
|
262
|
-
color
|
|
263
|
-
"""
|
|
264
|
-
n = len(B)
|
|
265
|
-
m = nx.number_of_edges(B)
|
|
266
|
-
nb = len(nodes)
|
|
267
|
-
nt = n - nb
|
|
268
|
-
if m == 0: # includes cases n==0 and n==1
|
|
269
|
-
d = 0.0
|
|
270
|
-
else:
|
|
271
|
-
if B.is_directed():
|
|
272
|
-
d = m / (2 * nb * nt)
|
|
273
|
-
else:
|
|
274
|
-
d = m / (nb * nt)
|
|
275
|
-
return d
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
@nx._dispatchable(graphs="B", edge_attrs="weight")
|
|
279
|
-
def degrees(B, nodes, weight=None):
|
|
280
|
-
"""Returns the degrees of the two node sets in the bipartite graph B.
|
|
281
|
-
|
|
282
|
-
Parameters
|
|
283
|
-
----------
|
|
284
|
-
B : NetworkX graph
|
|
285
|
-
|
|
286
|
-
nodes: list or container
|
|
287
|
-
Nodes in one node set of the bipartite graph.
|
|
288
|
-
|
|
289
|
-
weight : string or None, optional (default=None)
|
|
290
|
-
The edge attribute that holds the numerical value used as a weight.
|
|
291
|
-
If None, then each edge has weight 1.
|
|
292
|
-
The degree is the sum of the edge weights adjacent to the node.
|
|
293
|
-
|
|
294
|
-
Returns
|
|
295
|
-
-------
|
|
296
|
-
(degX,degY) : tuple of dictionaries
|
|
297
|
-
The degrees of the two bipartite sets as dictionaries keyed by node.
|
|
298
|
-
|
|
299
|
-
Examples
|
|
300
|
-
--------
|
|
301
|
-
>>> from networkx.algorithms import bipartite
|
|
302
|
-
>>> G = nx.complete_bipartite_graph(3, 2)
|
|
303
|
-
>>> Y = set([3, 4])
|
|
304
|
-
>>> degX, degY = bipartite.degrees(G, Y)
|
|
305
|
-
>>> dict(degX)
|
|
306
|
-
{0: 2, 1: 2, 2: 2}
|
|
307
|
-
|
|
308
|
-
Notes
|
|
309
|
-
-----
|
|
310
|
-
The container of nodes passed as argument must contain all nodes
|
|
311
|
-
in one of the two bipartite node sets to avoid ambiguity in the
|
|
312
|
-
case of disconnected graphs.
|
|
313
|
-
See :mod:`bipartite documentation <networkx.algorithms.bipartite>`
|
|
314
|
-
for further details on how bipartite graphs are handled in NetworkX.
|
|
315
|
-
|
|
316
|
-
See Also
|
|
317
|
-
--------
|
|
318
|
-
color, density
|
|
319
|
-
"""
|
|
320
|
-
bottom = set(nodes)
|
|
321
|
-
top = set(B) - bottom
|
|
322
|
-
return (B.degree(top, weight), B.degree(bottom, weight))
|