From 7e094ab08c9f33957889ef5f66b3c69ad7f1e879 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 17:11:27 +0800 Subject: [PATCH 1/6] Add plan for #295: DirectedTwoCommodityIntegralFlow Co-Authored-By: Claude Opus 4.6 (1M context) --- ...16-directed-two-commodity-integral-flow.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 docs/plans/2026-03-16-directed-two-commodity-integral-flow.md diff --git a/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md b/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md new file mode 100644 index 00000000..0b92a36f --- /dev/null +++ b/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md @@ -0,0 +1,107 @@ +# Plan: Add DirectedTwoCommodityIntegralFlow Model + +**Issue:** #295 +**Type:** [Model] +**Category:** `graph/` (directed graph input) + +## Overview + +Implement the Directed Two-Commodity Integral Flow problem (Garey & Johnson A2 ND38). This is a satisfaction problem: given a directed graph with arc capacities and two source-sink pairs with flow requirements, determine whether two integral flow functions exist that satisfy joint capacity constraints, flow conservation, and requirement thresholds. + +## Batch 1: Implementation (Steps 1-5.5) + +### Step 1: Category = `graph/` + +The problem takes a directed graph as primary input, so it belongs in `src/models/graph/`. + +### Step 1.5: Size getters + +From the complexity expression `(max_capacity + 1)^(2 * num_arcs)`: +- `num_vertices()` -> from `graph.num_vertices()` +- `num_arcs()` -> from `graph.num_arcs()` +- `max_capacity()` -> from `capacities.iter().max().copied().unwrap_or(0)` + +### Step 2: Implement the model + +Create `src/models/graph/directed_two_commodity_integral_flow.rs`: + +**Struct fields:** +- `graph: DirectedGraph` — directed graph G = (V, A) +- `capacities: Vec` — capacity c(a) for each arc +- `source_1: usize` — source vertex s_1 +- `sink_1: usize` — sink vertex t_1 +- `source_2: usize` — source vertex s_2 +- `sink_2: usize` — sink vertex t_2 +- `requirement_1: u64` — flow requirement R_1 +- `requirement_2: u64` — flow requirement R_2 + +**Problem trait:** +- `NAME = "DirectedTwoCommodityIntegralFlow"` +- `Metric = bool` (satisfaction problem) +- `dims()` = for each arc a, the domain for commodity i's flow is {0, ..., c(a)}. Configuration is a flat vector of 2*|A| variables: first |A| for commodity 1, next |A| for commodity 2. `dims()` returns `capacities.iter().chain(capacities.iter()).map(|&c| (c as usize) + 1).collect()` +- `evaluate()`: check (1) joint capacity f_1(a)+f_2(a) <= c(a) for all arcs, (2) flow conservation for each commodity at non-terminal vertices, (3) net flow into sink >= requirement for each commodity +- `variant()` = `variant_params![]` (no type parameters) + +**Implement `SatisfactionProblem` (marker trait).** + +**`inventory::submit!` for `ProblemSchemaEntry`** — fields: graph, capacities, source_1, sink_1, source_2, sink_2, requirement_1, requirement_2. No aliases (name is too long for a standard abbreviation, and none exists in the literature). No dimensions. + +### Step 2.5: Register variant complexity + +```rust +crate::declare_variants! { + default sat DirectedTwoCommodityIntegralFlow => "(max_capacity + 1)^(2 * num_arcs)", +} +``` + +### Step 3: Register the model + +1. `src/models/graph/mod.rs` — add `pub(crate) mod directed_two_commodity_integral_flow;` and `pub use directed_two_commodity_integral_flow::DirectedTwoCommodityIntegralFlow;` +2. `src/models/mod.rs` — add `DirectedTwoCommodityIntegralFlow` to the `graph::` re-export line + +### Step 4: CLI discovery + +Add lowercase alias mapping in `problemreductions-cli/src/problem_name.rs` `resolve_alias()` — no action needed since aliases are now catalog-driven via `ProblemSchemaEntry`. The `ProblemSchemaEntry` with no aliases is sufficient. + +### Step 4.5: CLI create support + +Add a match arm in `problemreductions-cli/src/commands/create.rs` for `"DirectedTwoCommodityIntegralFlow"`: +- Requires: `--arcs`, `--capacities`, `--source-1`, `--sink-1`, `--source-2`, `--sink-2`, `--requirement-1`, `--requirement-2` +- Add new CLI flags to `CreateArgs` in `problemreductions-cli/src/cli.rs`: `capacities`, `source_1`, `sink_1`, `source_2`, `sink_2`, `requirement_1`, `requirement_2` +- Update `all_data_flags_empty()` to include the new flags +- Add entry to "Flags by problem type" help table + +### Step 4.6: Canonical model example + +Add builder function in `src/example_db/model_builders.rs` — use the YES instance from the issue: 6 vertices, 8 arcs (all capacity 1), source_1=0, sink_1=4, source_2=1, sink_2=5, R_1=1, R_2=1. Known satisfying solution: commodity 1 path 0->2->4, commodity 2 path 1->3->5. + +Register in `src/models/graph/mod.rs` `canonical_model_example_specs()`. + +### Step 5: Unit tests + +Create `src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs`: + +- `test_directed_two_commodity_integral_flow_creation` — construct the 6-vertex instance, verify dims +- `test_directed_two_commodity_integral_flow_evaluation_satisfying` — verify the YES instance evaluates to `true` +- `test_directed_two_commodity_integral_flow_evaluation_unsatisfying` — verify the NO instance evaluates to `false` +- `test_directed_two_commodity_integral_flow_solver` — use BruteForce::find_satisfying on the YES instance +- `test_directed_two_commodity_integral_flow_no_solution` — verify BruteForce::find_satisfying returns None on the NO instance +- `test_directed_two_commodity_integral_flow_serialization` — round-trip serde +- `test_directed_two_commodity_integral_flow_paper_example` — verify example from paper (same as YES instance), check solution count + +Link via `#[cfg(test)] #[path = "..."] mod tests;` + +### Step 5.5: Trait consistency + +Add `check_problem_trait(...)` call in `src/unit_tests/trait_consistency.rs` for `DirectedTwoCommodityIntegralFlow`. +No `test_direction` entry needed (satisfaction problem). + +## Batch 2: Paper Entry (Step 6) + +### Step 6: Document in paper + +Add to `docs/paper/reductions.typ`: +1. Display name: `"DirectedTwoCommodityIntegralFlow": [Directed Two-Commodity Integral Flow]` +2. `problem-def("DirectedTwoCommodityIntegralFlow")` with formal definition and body (background, example with CeTZ diagram showing the 6-vertex network with two commodity paths highlighted) + +Run `make paper` to verify compilation. From 0d243857c185b4f4912d5e4154786d8d2bd4d24c Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 18:27:56 +0800 Subject: [PATCH 2/6] Implement #295: Add DirectedTwoCommodityIntegralFlow model Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/paper/reductions.typ | 48 +++ docs/paper/references.bib | 11 + docs/src/reductions/problem_schemas.json | 46 +++ docs/src/reductions/reduction_graph.json | 233 +++++++------ problemreductions-cli/src/cli.rs | 22 ++ problemreductions-cli/src/commands/create.rs | 71 ++++ src/example_db/fixtures/examples.json | 1 + src/lib.rs | 4 +- .../directed_two_commodity_integral_flow.rs | 323 ++++++++++++++++++ src/models/graph/mod.rs | 4 + src/models/mod.rs | 10 +- .../directed_two_commodity_integral_flow.rs | 178 ++++++++++ src/unit_tests/trait_consistency.rs | 13 + 13 files changed, 844 insertions(+), 120 deletions(-) create mode 100644 src/models/graph/directed_two_commodity_integral_flow.rs create mode 100644 src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs diff --git a/docs/paper/reductions.typ b/docs/paper/reductions.typ index ce08d760..6d80472f 100644 --- a/docs/paper/reductions.typ +++ b/docs/paper/reductions.typ @@ -105,6 +105,7 @@ "PartitionIntoTriangles": [Partition Into Triangles], "FlowShopScheduling": [Flow Shop Scheduling], "MinimumTardinessSequencing": [Minimum Tardiness Sequencing], + "DirectedTwoCommodityIntegralFlow": [Directed Two-Commodity Integral Flow], ) // Definition label: "def:" — each definition block must have a matching label @@ -1939,6 +1940,53 @@ NP-completeness was established by Garey, Johnson, and Stockmeyer @gareyJohnsonS ] } +#problem-def("DirectedTwoCommodityIntegralFlow")[ + Given a directed graph $G = (V, A)$ with arc capacities $c: A -> ZZ^+$, two source-sink pairs $(s_1, t_1)$ and $(s_2, t_2)$, and requirements $R_1, R_2 in ZZ^+$, determine whether there exist two integral flow functions $f_1, f_2: A -> ZZ_(>= 0)$ such that (1) $f_1(a) + f_2(a) <= c(a)$ for all $a in A$, (2) flow $f_i$ is conserved at every vertex except $s_1, s_2, t_1, t_2$, and (3) the net flow into $t_i$ under $f_i$ is at least $R_i$ for $i in {1, 2}$. +][ + Directed Two-Commodity Integral Flow is a fundamental NP-complete problem in multicommodity flow theory, catalogued as ND38 in Garey & Johnson @garey1979. While single-commodity max-flow is solvable in polynomial time and fractional multicommodity flow reduces to linear programming, requiring integral flows with just two commodities makes the problem NP-complete. + + NP-completeness was proved by Even, Itai, and Shamir via reduction from 3-SAT @even1976. The problem remains NP-complete even when all arc capacities are 1 and $R_1 = 1$. No sub-exponential exact algorithm is known; brute-force enumeration over $(C + 1)^(2|A|)$ flow assignments dominates, where $C = max_(a in A) c(a)$.#footnote[No algorithm improving on brute-force is known for Directed Two-Commodity Integral Flow.] + + *Example.* Consider a directed graph with 6 vertices and 8 arcs (all with unit capacity), sources $s_1 = 0$, $s_2 = 1$, sinks $t_1 = 4$, $t_2 = 5$, and requirements $R_1 = R_2 = 1$. Commodity 1 routes along the path $0 -> 2 -> 4$ and commodity 2 along $1 -> 3 -> 5$, satisfying all capacity and conservation constraints. + + #figure( + canvas(length: 1cm, { + import draw: * + let positions = ( + (0, 1), // 0 = s1 + (0, -1), // 1 = s2 + (2, 1), // 2 + (2, -1), // 3 + (4, 1), // 4 = t1 + (4, -1), // 5 = t2 + ) + let labels = ($s_1$, $s_2$, $2$, $3$, $t_1$, $t_2$) + let arcs = ((0, 2), (0, 3), (1, 2), (1, 3), (2, 4), (2, 5), (3, 4), (3, 5)) + // Commodity 1 path: arcs 0 (0->2) and 4 (2->4) + let c1-arcs = (0, 4) + // Commodity 2 path: arcs 3 (1->3) and 7 (3->5) + let c2-arcs = (3, 7) + + // Draw arcs + for (idx, (u, v)) in arcs.enumerate() { + let from = positions.at(u) + let to = positions.at(v) + let color = if c1-arcs.contains(idx) { blue } else if c2-arcs.contains(idx) { red } else { gray.darken(20%) } + let thickness = if c1-arcs.contains(idx) or c2-arcs.contains(idx) { 1.2pt } else { 0.6pt } + line(from, to, stroke: (paint: color, thickness: thickness), mark: (end: "straight", scale: 0.5)) + } + + // Draw vertices + for (k, pos) in positions.enumerate() { + let fill = if k == 0 or k == 4 { blue.lighten(70%) } else if k == 1 or k == 5 { red.lighten(70%) } else { white } + circle(pos, radius: 0.3, fill: fill, stroke: 0.6pt, name: str(k)) + content(pos, text(8pt, labels.at(k))) + } + }), + caption: [Two-commodity flow: commodity 1 (blue, $s_1 -> 2 -> t_1$) and commodity 2 (red, $s_2 -> 3 -> t_2$).], + ) +] + // Completeness check: warn about problem types in JSON but missing from paper #{ let json-models = { diff --git a/docs/paper/references.bib b/docs/paper/references.bib index 7186ea64..db782c8d 100644 --- a/docs/paper/references.bib +++ b/docs/paper/references.bib @@ -662,6 +662,17 @@ @inproceedings{cordella2004 doi = {10.1109/TPAMI.2004.75} } +@article{even1976, + author = {Shimon Even and Alon Itai and Adi Shamir}, + title = {On the Complexity of Timetable and Multicommodity Flow Problems}, + journal = {SIAM Journal on Computing}, + volume = {5}, + number = {4}, + pages = {691--703}, + year = {1976}, + doi = {10.1137/0205048} +} + @article{papadimitriou1982, author = {Christos H. Papadimitriou and Mihalis Yannakakis}, title = {The Complexity of Restricted Spanning Tree Problems}, diff --git a/docs/src/reductions/problem_schemas.json b/docs/src/reductions/problem_schemas.json index 5949a528..dbcd7552 100644 --- a/docs/src/reductions/problem_schemas.json +++ b/docs/src/reductions/problem_schemas.json @@ -89,6 +89,52 @@ } ] }, + { + "name": "DirectedTwoCommodityIntegralFlow", + "description": "Two-commodity integral flow feasibility on a directed graph", + "fields": [ + { + "name": "graph", + "type_name": "DirectedGraph", + "description": "Directed graph G = (V, A)" + }, + { + "name": "capacities", + "type_name": "Vec", + "description": "Capacity c(a) for each arc" + }, + { + "name": "source_1", + "type_name": "usize", + "description": "Source vertex s_1 for commodity 1" + }, + { + "name": "sink_1", + "type_name": "usize", + "description": "Sink vertex t_1 for commodity 1" + }, + { + "name": "source_2", + "type_name": "usize", + "description": "Source vertex s_2 for commodity 2" + }, + { + "name": "sink_2", + "type_name": "usize", + "description": "Sink vertex t_2 for commodity 2" + }, + { + "name": "requirement_1", + "type_name": "u64", + "description": "Flow requirement R_1 for commodity 1" + }, + { + "name": "requirement_2", + "type_name": "u64", + "description": "Flow requirement R_2 for commodity 2" + } + ] + }, { "name": "ExactCoverBy3Sets", "description": "Determine if a collection of 3-element subsets contains an exact cover", diff --git a/docs/src/reductions/reduction_graph.json b/docs/src/reductions/reduction_graph.json index cd80f3f0..ae687463 100644 --- a/docs/src/reductions/reduction_graph.json +++ b/docs/src/reductions/reduction_graph.json @@ -57,6 +57,13 @@ "doc_path": "models/algebraic/struct.ClosestVectorProblem.html", "complexity": "2^num_basis_vectors" }, + { + "name": "DirectedTwoCommodityIntegralFlow", + "variant": {}, + "category": "graph", + "doc_path": "models/graph/struct.DirectedTwoCommodityIntegralFlow.html", + "complexity": "(max_capacity + 1)^(2 * num_arcs)" + }, { "name": "ExactCoverBy3Sets", "variant": {}, @@ -539,7 +546,7 @@ "edges": [ { "source": 3, - "target": 12, + "target": 13, "overhead": [ { "field": "num_vars", @@ -554,7 +561,7 @@ }, { "source": 4, - "target": 12, + "target": 13, "overhead": [ { "field": "num_vars", @@ -569,7 +576,7 @@ }, { "source": 4, - "target": 54, + "target": 55, "overhead": [ { "field": "num_spins", @@ -583,7 +590,7 @@ "doc_path": "rules/circuit_spinglass/index.html" }, { - "source": 8, + "source": 9, "target": 4, "overhead": [ { @@ -598,8 +605,8 @@ "doc_path": "rules/factoring_circuit/index.html" }, { - "source": 8, - "target": 13, + "source": 9, + "target": 14, "overhead": [ { "field": "num_vars", @@ -613,8 +620,8 @@ "doc_path": "rules/factoring_ilp/index.html" }, { - "source": 12, - "target": 13, + "source": 13, + "target": 14, "overhead": [ { "field": "num_vars", @@ -628,8 +635,8 @@ "doc_path": "rules/ilp_bool_ilp_i32/index.html" }, { - "source": 12, - "target": 49, + "source": 13, + "target": 50, "overhead": [ { "field": "num_vars", @@ -639,8 +646,8 @@ "doc_path": "rules/ilp_qubo/index.html" }, { - "source": 16, - "target": 19, + "source": 17, + "target": 20, "overhead": [ { "field": "num_vertices", @@ -654,8 +661,8 @@ "doc_path": "rules/kcoloring_casts/index.html" }, { - "source": 19, - "target": 12, + "source": 20, + "target": 13, "overhead": [ { "field": "num_vars", @@ -669,8 +676,8 @@ "doc_path": "rules/coloring_ilp/index.html" }, { - "source": 19, - "target": 49, + "source": 20, + "target": 50, "overhead": [ { "field": "num_vars", @@ -680,8 +687,8 @@ "doc_path": "rules/coloring_qubo/index.html" }, { - "source": 20, - "target": 22, + "source": 21, + "target": 23, "overhead": [ { "field": "num_vars", @@ -695,8 +702,8 @@ "doc_path": "rules/ksatisfiability_casts/index.html" }, { - "source": 20, - "target": 49, + "source": 21, + "target": 50, "overhead": [ { "field": "num_vars", @@ -706,8 +713,8 @@ "doc_path": "rules/ksatisfiability_qubo/index.html" }, { - "source": 21, - "target": 22, + "source": 22, + "target": 23, "overhead": [ { "field": "num_vars", @@ -721,8 +728,8 @@ "doc_path": "rules/ksatisfiability_casts/index.html" }, { - "source": 21, - "target": 49, + "source": 22, + "target": 50, "overhead": [ { "field": "num_vars", @@ -732,8 +739,8 @@ "doc_path": "rules/ksatisfiability_qubo/index.html" }, { - "source": 21, - "target": 58, + "source": 22, + "target": 59, "overhead": [ { "field": "num_elements", @@ -743,8 +750,8 @@ "doc_path": "rules/ksatisfiability_subsetsum/index.html" }, { - "source": 22, - "target": 51, + "source": 23, + "target": 52, "overhead": [ { "field": "num_clauses", @@ -762,8 +769,8 @@ "doc_path": "rules/sat_ksat/index.html" }, { - "source": 23, - "target": 49, + "source": 24, + "target": 50, "overhead": [ { "field": "num_vars", @@ -773,8 +780,8 @@ "doc_path": "rules/knapsack_qubo/index.html" }, { - "source": 24, - "target": 12, + "source": 25, + "target": 13, "overhead": [ { "field": "num_vars", @@ -788,8 +795,8 @@ "doc_path": "rules/longestcommonsubsequence_ilp/index.html" }, { - "source": 25, - "target": 54, + "source": 26, + "target": 55, "overhead": [ { "field": "num_spins", @@ -803,8 +810,8 @@ "doc_path": "rules/spinglass_maxcut/index.html" }, { - "source": 27, - "target": 12, + "source": 28, + "target": 13, "overhead": [ { "field": "num_vars", @@ -818,8 +825,8 @@ "doc_path": "rules/maximumclique_ilp/index.html" }, { - "source": 27, - "target": 31, + "source": 28, + "target": 32, "overhead": [ { "field": "num_vertices", @@ -833,8 +840,8 @@ "doc_path": "rules/maximumclique_maximumindependentset/index.html" }, { - "source": 28, - "target": 29, + "source": 29, + "target": 30, "overhead": [ { "field": "num_vertices", @@ -848,8 +855,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 28, - "target": 33, + "source": 29, + "target": 34, "overhead": [ { "field": "num_vertices", @@ -863,8 +870,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 29, - "target": 34, + "source": 30, + "target": 35, "overhead": [ { "field": "num_vertices", @@ -878,8 +885,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 30, - "target": 28, + "source": 31, + "target": 29, "overhead": [ { "field": "num_vertices", @@ -893,8 +900,8 @@ "doc_path": "rules/maximumindependentset_gridgraph/index.html" }, { - "source": 30, - "target": 31, + "source": 31, + "target": 32, "overhead": [ { "field": "num_vertices", @@ -908,8 +915,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 30, - "target": 32, + "source": 31, + "target": 33, "overhead": [ { "field": "num_vertices", @@ -923,8 +930,8 @@ "doc_path": "rules/maximumindependentset_triangular/index.html" }, { - "source": 30, - "target": 36, + "source": 31, + "target": 37, "overhead": [ { "field": "num_sets", @@ -938,8 +945,8 @@ "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" }, { - "source": 31, - "target": 27, + "source": 32, + "target": 28, "overhead": [ { "field": "num_vertices", @@ -953,8 +960,8 @@ "doc_path": "rules/maximumindependentset_maximumclique/index.html" }, { - "source": 31, - "target": 38, + "source": 32, + "target": 39, "overhead": [ { "field": "num_sets", @@ -968,8 +975,8 @@ "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" }, { - "source": 31, - "target": 45, + "source": 32, + "target": 46, "overhead": [ { "field": "num_vertices", @@ -983,8 +990,8 @@ "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" }, { - "source": 32, - "target": 34, + "source": 33, + "target": 35, "overhead": [ { "field": "num_vertices", @@ -998,8 +1005,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 33, - "target": 30, + "source": 34, + "target": 31, "overhead": [ { "field": "num_vertices", @@ -1013,8 +1020,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 33, - "target": 34, + "source": 34, + "target": 35, "overhead": [ { "field": "num_vertices", @@ -1028,8 +1035,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 34, - "target": 31, + "source": 35, + "target": 32, "overhead": [ { "field": "num_vertices", @@ -1043,8 +1050,8 @@ "doc_path": "rules/maximumindependentset_casts/index.html" }, { - "source": 35, - "target": 12, + "source": 36, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1058,8 +1065,8 @@ "doc_path": "rules/maximummatching_ilp/index.html" }, { - "source": 35, - "target": 38, + "source": 36, + "target": 39, "overhead": [ { "field": "num_sets", @@ -1073,8 +1080,8 @@ "doc_path": "rules/maximummatching_maximumsetpacking/index.html" }, { - "source": 36, - "target": 30, + "source": 37, + "target": 31, "overhead": [ { "field": "num_vertices", @@ -1088,8 +1095,8 @@ "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" }, { - "source": 36, - "target": 38, + "source": 37, + "target": 39, "overhead": [ { "field": "num_sets", @@ -1103,8 +1110,8 @@ "doc_path": "rules/maximumsetpacking_casts/index.html" }, { - "source": 37, - "target": 49, + "source": 38, + "target": 50, "overhead": [ { "field": "num_vars", @@ -1114,8 +1121,8 @@ "doc_path": "rules/maximumsetpacking_qubo/index.html" }, { - "source": 38, - "target": 12, + "source": 39, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1129,8 +1136,8 @@ "doc_path": "rules/maximumsetpacking_ilp/index.html" }, { - "source": 38, - "target": 31, + "source": 39, + "target": 32, "overhead": [ { "field": "num_vertices", @@ -1144,8 +1151,8 @@ "doc_path": "rules/maximumindependentset_maximumsetpacking/index.html" }, { - "source": 38, - "target": 37, + "source": 39, + "target": 38, "overhead": [ { "field": "num_sets", @@ -1159,8 +1166,8 @@ "doc_path": "rules/maximumsetpacking_casts/index.html" }, { - "source": 39, - "target": 12, + "source": 40, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1174,8 +1181,8 @@ "doc_path": "rules/minimumdominatingset_ilp/index.html" }, { - "source": 42, - "target": 12, + "source": 43, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1189,8 +1196,8 @@ "doc_path": "rules/minimumsetcovering_ilp/index.html" }, { - "source": 45, - "target": 31, + "source": 46, + "target": 32, "overhead": [ { "field": "num_vertices", @@ -1204,8 +1211,8 @@ "doc_path": "rules/minimumvertexcover_maximumindependentset/index.html" }, { - "source": 45, - "target": 42, + "source": 46, + "target": 43, "overhead": [ { "field": "num_sets", @@ -1219,8 +1226,8 @@ "doc_path": "rules/minimumvertexcover_minimumsetcovering/index.html" }, { - "source": 49, - "target": 12, + "source": 50, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1234,8 +1241,8 @@ "doc_path": "rules/qubo_ilp/index.html" }, { - "source": 49, - "target": 53, + "source": 50, + "target": 54, "overhead": [ { "field": "num_spins", @@ -1245,7 +1252,7 @@ "doc_path": "rules/spinglass_qubo/index.html" }, { - "source": 51, + "source": 52, "target": 4, "overhead": [ { @@ -1260,8 +1267,8 @@ "doc_path": "rules/sat_circuitsat/index.html" }, { - "source": 51, - "target": 16, + "source": 52, + "target": 17, "overhead": [ { "field": "num_vertices", @@ -1275,8 +1282,8 @@ "doc_path": "rules/sat_coloring/index.html" }, { - "source": 51, - "target": 21, + "source": 52, + "target": 22, "overhead": [ { "field": "num_clauses", @@ -1290,8 +1297,8 @@ "doc_path": "rules/sat_ksat/index.html" }, { - "source": 51, - "target": 30, + "source": 52, + "target": 31, "overhead": [ { "field": "num_vertices", @@ -1305,8 +1312,8 @@ "doc_path": "rules/sat_maximumindependentset/index.html" }, { - "source": 51, - "target": 39, + "source": 52, + "target": 40, "overhead": [ { "field": "num_vertices", @@ -1320,8 +1327,8 @@ "doc_path": "rules/sat_minimumdominatingset/index.html" }, { - "source": 53, - "target": 49, + "source": 54, + "target": 50, "overhead": [ { "field": "num_vars", @@ -1331,8 +1338,8 @@ "doc_path": "rules/spinglass_qubo/index.html" }, { - "source": 54, - "target": 25, + "source": 55, + "target": 26, "overhead": [ { "field": "num_vertices", @@ -1346,8 +1353,8 @@ "doc_path": "rules/spinglass_maxcut/index.html" }, { - "source": 54, - "target": 53, + "source": 55, + "target": 54, "overhead": [ { "field": "num_spins", @@ -1361,8 +1368,8 @@ "doc_path": "rules/spinglass_casts/index.html" }, { - "source": 59, - "target": 12, + "source": 60, + "target": 13, "overhead": [ { "field": "num_vars", @@ -1376,8 +1383,8 @@ "doc_path": "rules/travelingsalesman_ilp/index.html" }, { - "source": 59, - "target": 49, + "source": 60, + "target": 50, "overhead": [ { "field": "num_vars", diff --git a/problemreductions-cli/src/cli.rs b/problemreductions-cli/src/cli.rs index e2dbd5b5..b18fc0d3 100644 --- a/problemreductions-cli/src/cli.rs +++ b/problemreductions-cli/src/cli.rs @@ -244,6 +244,7 @@ Flags by problem type: FlowShopScheduling --task-lengths, --deadline [--num-processors] MinimumTardinessSequencing --n, --deadlines [--precedence-pairs] SCS --strings, --bound [--alphabet-size] + D2CIF --arcs, --capacities, --source-1, --sink-1, --source-2, --sink-2, --requirement-1, --requirement-2 ILP, CircuitSAT (via reduction only) Geometry graph variants (use slash notation, e.g., MIS/KingsSubgraph): @@ -407,6 +408,27 @@ pub struct CreateArgs { /// Alphabet size for SCS (optional; inferred from max symbol + 1 if omitted) #[arg(long)] pub alphabet_size: Option, + /// Arc capacities for DirectedTwoCommodityIntegralFlow (comma-separated, e.g., "1,1,1") + #[arg(long)] + pub capacities: Option, + /// Source vertex for commodity 1 + #[arg(long)] + pub source_1: Option, + /// Sink vertex for commodity 1 + #[arg(long)] + pub sink_1: Option, + /// Source vertex for commodity 2 + #[arg(long)] + pub source_2: Option, + /// Sink vertex for commodity 2 + #[arg(long)] + pub sink_2: Option, + /// Flow requirement for commodity 1 + #[arg(long)] + pub requirement_1: Option, + /// Flow requirement for commodity 2 + #[arg(long)] + pub requirement_2: Option, } #[derive(clap::Args)] diff --git a/problemreductions-cli/src/commands/create.rs b/problemreductions-cli/src/commands/create.rs index db0e6c58..3a50fd3d 100644 --- a/problemreductions-cli/src/commands/create.rs +++ b/problemreductions-cli/src/commands/create.rs @@ -64,6 +64,13 @@ fn all_data_flags_empty(args: &CreateArgs) -> bool { && args.deadline.is_none() && args.num_processors.is_none() && args.alphabet_size.is_none() + && args.capacities.is_none() + && args.source_1.is_none() + && args.sink_1.is_none() + && args.source_2.is_none() + && args.sink_2.is_none() + && args.requirement_1.is_none() + && args.requirement_2.is_none() } fn emit_problem_output(output: &ProblemJsonOutput, out: &OutputConfig) -> Result<()> { @@ -242,6 +249,9 @@ fn example_for(canonical: &str, graph_type: Option<&str>) -> &'static str { "Factoring" => "--target 15 --m 4 --n 4", "SteinerTree" => "--graph 0-1,1-2,1-3,3-4 --edge-weights 2,2,1,1 --terminals 0,2,4", "OptimalLinearArrangement" => "--graph 0-1,1-2,2-3 --bound 5", + "DirectedTwoCommodityIntegralFlow" => { + "--arcs \"0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5\" --capacities 1,1,1,1,1,1,1,1 --source-1 0 --sink-1 4 --source-2 1 --sink-2 5 --requirement-1 1 --requirement-2 1" + } "MinimumFeedbackArcSet" => "--arcs \"0>1,1>2,2>0\"", "RuralPostman" => { "--graph 0-1,1-2,2-3,3-0 --edge-weights 1,1,1,1 --required-edges 0,2 --bound 4" @@ -929,6 +939,67 @@ pub fn create(args: &CreateArgs, out: &OutputConfig) -> Result<()> { ) } + // DirectedTwoCommodityIntegralFlow + "DirectedTwoCommodityIntegralFlow" => { + let arcs_str = args.arcs.as_deref().ok_or_else(|| { + anyhow::anyhow!( + "DirectedTwoCommodityIntegralFlow requires --arcs\n\n\ + Usage: pred create DirectedTwoCommodityIntegralFlow \ + --arcs \"0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5\" \ + --capacities 1,1,1,1,1,1,1,1 \ + --source-1 0 --sink-1 4 --source-2 1 --sink-2 5 \ + --requirement-1 1 --requirement-2 1" + ) + })?; + let (graph, num_arcs) = parse_directed_graph(arcs_str, args.num_vertices)?; + let capacities: Vec = if let Some(ref s) = args.capacities { + util::parse_comma_list(s)? + } else { + vec![1; num_arcs] + }; + anyhow::ensure!( + capacities.len() == num_arcs, + "capacities length ({}) must match number of arcs ({num_arcs})", + capacities.len() + ); + let n = graph.num_vertices(); + let source_1 = args.source_1.ok_or_else(|| { + anyhow::anyhow!("DirectedTwoCommodityIntegralFlow requires --source-1") + })?; + let sink_1 = args.sink_1.ok_or_else(|| { + anyhow::anyhow!("DirectedTwoCommodityIntegralFlow requires --sink-1") + })?; + let source_2 = args.source_2.ok_or_else(|| { + anyhow::anyhow!("DirectedTwoCommodityIntegralFlow requires --source-2") + })?; + let sink_2 = args.sink_2.ok_or_else(|| { + anyhow::anyhow!("DirectedTwoCommodityIntegralFlow requires --sink-2") + })?; + for (name, idx) in [ + ("source_1", source_1), + ("sink_1", sink_1), + ("source_2", source_2), + ("sink_2", sink_2), + ] { + anyhow::ensure!(idx < n, "{name} ({idx}) >= num_vertices ({n})"); + } + let requirement_1 = args.requirement_1.unwrap_or(1); + let requirement_2 = args.requirement_2.unwrap_or(1); + ( + ser(DirectedTwoCommodityIntegralFlow::new( + graph, + capacities, + source_1, + sink_1, + source_2, + sink_2, + requirement_1, + requirement_2, + ))?, + resolved_variant.clone(), + ) + } + // MinimumFeedbackArcSet "MinimumFeedbackArcSet" => { let arcs_str = args.arcs.as_deref().ok_or_else(|| { diff --git a/src/example_db/fixtures/examples.json b/src/example_db/fixtures/examples.json index 83015b13..a45520b5 100644 --- a/src/example_db/fixtures/examples.json +++ b/src/example_db/fixtures/examples.json @@ -4,6 +4,7 @@ {"problem":"BicliqueCover","variant":{},"instance":{"graph":{"edges":[[0,0],[0,1],[1,1],[1,2]],"left_size":2,"right_size":3},"k":2},"samples":[{"config":[1,0,0,1,1,0,1,1,0,1],"metric":{"Valid":6}}],"optimal":[{"config":[0,1,0,1,0,1,0,1,0,1],"metric":{"Valid":5}},{"config":[1,0,1,0,1,0,1,0,1,0],"metric":{"Valid":5}}]}, {"problem":"CircuitSAT","variant":{},"instance":{"circuit":{"assignments":[{"expr":{"op":{"And":[{"op":{"Var":"x1"}},{"op":{"Var":"x2"}}]}},"outputs":["a"]},{"expr":{"op":{"Or":[{"op":{"Var":"x1"}},{"op":{"Var":"x2"}}]}},"outputs":["b"]},{"expr":{"op":{"Xor":[{"op":{"Var":"a"}},{"op":{"Var":"b"}}]}},"outputs":["c"]}]},"variables":["a","b","c","x1","x2"]},"samples":[{"config":[0,1,1,0,1],"metric":true},{"config":[0,1,1,1,0],"metric":true}],"optimal":[{"config":[0,0,0,0,0],"metric":true},{"config":[0,1,1,0,1],"metric":true},{"config":[0,1,1,1,0],"metric":true},{"config":[1,1,0,1,1],"metric":true}]}, {"problem":"ClosestVectorProblem","variant":{"weight":"i32"},"instance":{"basis":[[2,0],[1,2]],"bounds":[{"lower":-2,"upper":4},{"lower":-2,"upper":4}],"target":[2.8,1.5]},"samples":[{"config":[3,3],"metric":{"Valid":0.5385164807134505}}],"optimal":[{"config":[3,3],"metric":{"Valid":0.5385164807134505}}]}, + {"problem":"DirectedTwoCommodityIntegralFlow","variant":{},"instance":{"capacities":[1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"directed","edges":[[0,2,null],[0,3,null],[1,2,null],[1,3,null],[2,4,null],[2,5,null],[3,4,null],[3,5,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}},"requirement_1":1,"requirement_2":1,"sink_1":4,"sink_2":5,"source_1":0,"source_2":1},"samples":[{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true}],"optimal":[{"config":[0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1],"metric":true}]}, {"problem":"ExactCoverBy3Sets","variant":{},"instance":{"subsets":[[0,1,2],[0,2,4],[3,4,5],[3,5,7],[6,7,8],[1,4,6],[2,5,8]],"universe_size":9},"samples":[{"config":[1,0,1,0,1,0,0],"metric":true}],"optimal":[{"config":[1,0,1,0,1,0,0],"metric":true}]}, {"problem":"Factoring","variant":{},"instance":{"m":2,"n":3,"target":15},"samples":[{"config":[1,1,1,0,1],"metric":{"Valid":0}}],"optimal":[{"config":[1,1,1,0,1],"metric":{"Valid":0}}]}, {"problem":"HamiltonianPath","variant":{"graph":"SimpleGraph"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,3,null],[2,3,null],[3,4,null],[3,5,null],[4,2,null],[5,1,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}}},"samples":[{"config":[0,2,4,3,1,5],"metric":true}],"optimal":[{"config":[0,1,5,3,2,4],"metric":true},{"config":[0,1,5,3,4,2],"metric":true},{"config":[0,2,4,3,1,5],"metric":true},{"config":[0,2,4,3,5,1],"metric":true},{"config":[1,0,2,4,3,5],"metric":true},{"config":[1,5,3,4,2,0],"metric":true},{"config":[2,0,1,5,3,4],"metric":true},{"config":[2,4,3,5,1,0],"metric":true},{"config":[3,4,2,0,1,5],"metric":true},{"config":[3,5,1,0,2,4],"metric":true},{"config":[4,2,0,1,3,5],"metric":true},{"config":[4,2,0,1,5,3],"metric":true},{"config":[4,2,3,5,1,0],"metric":true},{"config":[4,3,2,0,1,5],"metric":true},{"config":[4,3,5,1,0,2],"metric":true},{"config":[5,1,0,2,3,4],"metric":true},{"config":[5,1,0,2,4,3],"metric":true},{"config":[5,1,3,4,2,0],"metric":true},{"config":[5,3,1,0,2,4],"metric":true},{"config":[5,3,4,2,0,1],"metric":true}]}, diff --git a/src/lib.rs b/src/lib.rs index 64c77b6f..32e04b53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,8 +45,8 @@ pub mod prelude { pub use crate::models::algebraic::{BMF, QUBO}; pub use crate::models::formula::{CNFClause, CircuitSAT, KSatisfiability, Satisfiability}; pub use crate::models::graph::{ - BicliqueCover, GraphPartitioning, HamiltonianPath, IsomorphicSpanningTree, SpinGlass, - SteinerTree, SubgraphIsomorphism, + BicliqueCover, DirectedTwoCommodityIntegralFlow, GraphPartitioning, HamiltonianPath, + IsomorphicSpanningTree, SpinGlass, SteinerTree, SubgraphIsomorphism, }; pub use crate::models::graph::{ KColoring, MaxCut, MaximalIS, MaximumClique, MaximumIndependentSet, MaximumMatching, diff --git a/src/models/graph/directed_two_commodity_integral_flow.rs b/src/models/graph/directed_two_commodity_integral_flow.rs new file mode 100644 index 00000000..5bc495fd --- /dev/null +++ b/src/models/graph/directed_two_commodity_integral_flow.rs @@ -0,0 +1,323 @@ +//! Directed Two-Commodity Integral Flow problem implementation. +//! +//! Given a directed graph with arc capacities and two source-sink pairs with +//! flow requirements, determine whether two integral flow functions exist that +//! jointly satisfy capacity, conservation, and requirement constraints. +//! +//! NP-complete even with unit capacities (Even, Itai, and Shamir, 1976). + +use crate::registry::{FieldInfo, ProblemSchemaEntry}; +use crate::topology::DirectedGraph; +use crate::traits::{Problem, SatisfactionProblem}; +use serde::{Deserialize, Serialize}; + +inventory::submit! { + ProblemSchemaEntry { + name: "DirectedTwoCommodityIntegralFlow", + display_name: "Directed Two-Commodity Integral Flow", + aliases: &[], + dimensions: &[], + module_path: module_path!(), + description: "Two-commodity integral flow feasibility on a directed graph", + fields: &[ + FieldInfo { name: "graph", type_name: "DirectedGraph", description: "Directed graph G = (V, A)" }, + FieldInfo { name: "capacities", type_name: "Vec", description: "Capacity c(a) for each arc" }, + FieldInfo { name: "source_1", type_name: "usize", description: "Source vertex s_1 for commodity 1" }, + FieldInfo { name: "sink_1", type_name: "usize", description: "Sink vertex t_1 for commodity 1" }, + FieldInfo { name: "source_2", type_name: "usize", description: "Source vertex s_2 for commodity 2" }, + FieldInfo { name: "sink_2", type_name: "usize", description: "Sink vertex t_2 for commodity 2" }, + FieldInfo { name: "requirement_1", type_name: "u64", description: "Flow requirement R_1 for commodity 1" }, + FieldInfo { name: "requirement_2", type_name: "u64", description: "Flow requirement R_2 for commodity 2" }, + ], + } +} + +/// Directed Two-Commodity Integral Flow problem. +/// +/// Given a directed graph G = (V, A) with arc capacities c(a), two source-sink +/// pairs (s_1, t_1) and (s_2, t_2), and requirements R_1, R_2, determine +/// whether two integral flow functions f_1, f_2: A -> Z_0^+ exist such that: +/// 1. Joint capacity: f_1(a) + f_2(a) <= c(a) for all a in A +/// 2. Flow conservation: for each commodity i, flow is conserved at every +/// vertex except the four terminals +/// 3. Requirements: net flow into t_i under f_i is at least R_i +/// +/// # Variables +/// +/// 2|A| variables: first |A| for commodity 1's flow on each arc, +/// next |A| for commodity 2's flow on each arc. Variable j for arc a +/// of commodity i ranges over {0, ..., c(a)}. +/// +/// # Example +/// +/// ``` +/// use problemreductions::models::graph::DirectedTwoCommodityIntegralFlow; +/// use problemreductions::topology::DirectedGraph; +/// use problemreductions::{Problem, Solver, BruteForce}; +/// +/// // 6-vertex network: s1=0, s2=1, t1=4, t2=5 +/// let graph = DirectedGraph::new(6, vec![ +/// (0, 2), (0, 3), (1, 2), (1, 3), +/// (2, 4), (2, 5), (3, 4), (3, 5), +/// ]); +/// let problem = DirectedTwoCommodityIntegralFlow::new( +/// graph, vec![1; 8], 0, 4, 1, 5, 1, 1, +/// ); +/// let solver = BruteForce::new(); +/// assert!(solver.find_satisfying(&problem).is_some()); +/// ``` +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DirectedTwoCommodityIntegralFlow { + /// The directed graph G = (V, A). + graph: DirectedGraph, + /// Capacity c(a) for each arc. + capacities: Vec, + /// Source vertex s_1 for commodity 1. + source_1: usize, + /// Sink vertex t_1 for commodity 1. + sink_1: usize, + /// Source vertex s_2 for commodity 2. + source_2: usize, + /// Sink vertex t_2 for commodity 2. + sink_2: usize, + /// Flow requirement R_1 for commodity 1. + requirement_1: u64, + /// Flow requirement R_2 for commodity 2. + requirement_2: u64, +} + +impl DirectedTwoCommodityIntegralFlow { + /// Create a new Directed Two-Commodity Integral Flow problem. + /// + /// # Panics + /// + /// Panics if: + /// - `capacities.len() != graph.num_arcs()` + /// - Any terminal vertex index >= `graph.num_vertices()` + #[allow(clippy::too_many_arguments)] + pub fn new( + graph: DirectedGraph, + capacities: Vec, + source_1: usize, + sink_1: usize, + source_2: usize, + sink_2: usize, + requirement_1: u64, + requirement_2: u64, + ) -> Self { + let n = graph.num_vertices(); + assert_eq!( + capacities.len(), + graph.num_arcs(), + "capacities length must match graph num_arcs" + ); + assert!(source_1 < n, "source_1 ({source_1}) >= num_vertices ({n})"); + assert!(sink_1 < n, "sink_1 ({sink_1}) >= num_vertices ({n})"); + assert!(source_2 < n, "source_2 ({source_2}) >= num_vertices ({n})"); + assert!(sink_2 < n, "sink_2 ({sink_2}) >= num_vertices ({n})"); + Self { + graph, + capacities, + source_1, + sink_1, + source_2, + sink_2, + requirement_1, + requirement_2, + } + } + + /// Get a reference to the underlying directed graph. + pub fn graph(&self) -> &DirectedGraph { + &self.graph + } + + /// Get a reference to the capacities. + pub fn capacities(&self) -> &[u64] { + &self.capacities + } + + /// Get source vertex for commodity 1. + pub fn source_1(&self) -> usize { + self.source_1 + } + + /// Get sink vertex for commodity 1. + pub fn sink_1(&self) -> usize { + self.sink_1 + } + + /// Get source vertex for commodity 2. + pub fn source_2(&self) -> usize { + self.source_2 + } + + /// Get sink vertex for commodity 2. + pub fn sink_2(&self) -> usize { + self.sink_2 + } + + /// Get requirement for commodity 1. + pub fn requirement_1(&self) -> u64 { + self.requirement_1 + } + + /// Get requirement for commodity 2. + pub fn requirement_2(&self) -> u64 { + self.requirement_2 + } + + /// Get the number of vertices. + pub fn num_vertices(&self) -> usize { + self.graph.num_vertices() + } + + /// Get the number of arcs. + pub fn num_arcs(&self) -> usize { + self.graph.num_arcs() + } + + /// Get the maximum capacity across all arcs. + pub fn max_capacity(&self) -> u64 { + self.capacities.iter().copied().max().unwrap_or(0) + } + + /// Check whether a flow assignment is feasible. + /// + /// `config` has 2*|A| entries: first |A| for commodity 1, next |A| for commodity 2. + pub fn is_feasible(&self, config: &[usize]) -> bool { + let m = self.graph.num_arcs(); + if config.len() != 2 * m { + return false; + } + let arcs = self.graph.arcs(); + let terminals = [self.source_1, self.sink_1, self.source_2, self.sink_2]; + + // (1) Joint capacity constraint + for a in 0..m { + let f1 = config[a] as u64; + let f2 = config[m + a] as u64; + if f1 + f2 > self.capacities[a] { + return false; + } + } + + // (2) Flow conservation for each commodity at non-terminal vertices + // Per the definition, conservation applies at every vertex EXCEPT + // the four terminals {s_1, s_2, t_1, t_2} for BOTH commodities. + let n = self.graph.num_vertices(); + for commodity in 0..2usize { + let offset = commodity * m; + for v in 0..n { + if terminals.contains(&v) { + continue; + } + let mut flow_in: i64 = 0; + let mut flow_out: i64 = 0; + for (a, &(u, w)) in arcs.iter().enumerate() { + if w == v { + flow_in += config[offset + a] as i64; + } + if u == v { + flow_out += config[offset + a] as i64; + } + } + if flow_in != flow_out { + return false; + } + } + } + + // (3) Requirement constraints + // Net flow into sink for commodity i = (total flow into sink) - (total flow out of sink) + for commodity in 0..2usize { + let offset = commodity * m; + let snk = if commodity == 0 { + self.sink_1 + } else { + self.sink_2 + }; + let req = if commodity == 0 { + self.requirement_1 + } else { + self.requirement_2 + }; + let mut net_flow_in: i64 = 0; + for (a, &(u, w)) in arcs.iter().enumerate() { + if w == snk { + net_flow_in += config[offset + a] as i64; + } + if u == snk { + net_flow_in -= config[offset + a] as i64; + } + } + if (net_flow_in as u64) < req { + return false; + } + } + + true + } +} + +impl Problem for DirectedTwoCommodityIntegralFlow { + const NAME: &'static str = "DirectedTwoCommodityIntegralFlow"; + type Metric = bool; + + fn dims(&self) -> Vec { + self.capacities + .iter() + .chain(self.capacities.iter()) + .map(|&c| (c as usize) + 1) + .collect() + } + + fn evaluate(&self, config: &[usize]) -> bool { + self.is_feasible(config) + } + + fn variant() -> Vec<(&'static str, &'static str)> { + crate::variant_params![] + } +} + +impl SatisfactionProblem for DirectedTwoCommodityIntegralFlow {} + +crate::declare_variants! { + default sat DirectedTwoCommodityIntegralFlow => "(max_capacity + 1)^(2 * num_arcs)", +} + +#[cfg(feature = "example-db")] +pub(crate) fn canonical_model_example_specs() -> Vec { + vec![crate::example_db::specs::ModelExampleSpec { + id: "directed_two_commodity_integral_flow", + build: || { + let graph = DirectedGraph::new( + 6, + vec![ + (0, 2), + (0, 3), + (1, 2), + (1, 3), + (2, 4), + (2, 5), + (3, 4), + (3, 5), + ], + ); + let problem = + DirectedTwoCommodityIntegralFlow::new(graph, vec![1; 8], 0, 4, 1, 5, 1, 1); + // Solution: commodity 1 path 0->2->4 (arcs 0,4), commodity 2 path 1->3->5 (arcs 3,7) + // config = [f1(a0)..f1(a7), f2(a0)..f2(a7)] + // = [1,0,0,0,1,0,0,0, 0,0,0,1,0,0,0,1] + crate::example_db::specs::satisfaction_example( + problem, + vec![vec![1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]], + ) + }, + }] +} + +#[cfg(test)] +#[path = "../../unit_tests/models/graph/directed_two_commodity_integral_flow.rs"] +mod tests; diff --git a/src/models/graph/mod.rs b/src/models/graph/mod.rs index a8ff8a4a..7f0264f9 100644 --- a/src/models/graph/mod.rs +++ b/src/models/graph/mod.rs @@ -22,8 +22,10 @@ //! - [`MinimumSumMulticenter`]: Min-sum multicenter (p-median) //! - [`RuralPostman`]: Rural Postman (circuit covering required edges) //! - [`SubgraphIsomorphism`]: Subgraph isomorphism (decision problem) +//! - [`DirectedTwoCommodityIntegralFlow`]: Directed two-commodity integral flow (satisfaction) pub(crate) mod biclique_cover; +pub(crate) mod directed_two_commodity_integral_flow; pub(crate) mod graph_partitioning; pub(crate) mod hamiltonian_path; pub(crate) mod isomorphic_spanning_tree; @@ -47,6 +49,7 @@ pub(crate) mod subgraph_isomorphism; pub(crate) mod traveling_salesman; pub use biclique_cover::BicliqueCover; +pub use directed_two_commodity_integral_flow::DirectedTwoCommodityIntegralFlow; pub use graph_partitioning::GraphPartitioning; pub use hamiltonian_path::HamiltonianPath; pub use isomorphic_spanning_tree::IsomorphicSpanningTree; @@ -89,5 +92,6 @@ pub(crate) fn canonical_model_example_specs() -> Vec DirectedTwoCommodityIntegralFlow { + let graph = DirectedGraph::new( + 6, + vec![ + (0, 2), + (0, 3), + (1, 2), + (1, 3), + (2, 4), + (2, 5), + (3, 4), + (3, 5), + ], + ); + DirectedTwoCommodityIntegralFlow::new(graph, vec![1; 8], 0, 4, 1, 5, 1, 1) +} + +/// NO instance: 4 vertices, 3 arcs (all capacity 1). +/// s1=0, t1=3, s2=1, t2=3, R1=1, R2=1. +/// Bottleneck at arc (2,3) with capacity 1. +fn no_instance() -> DirectedTwoCommodityIntegralFlow { + let graph = DirectedGraph::new(4, vec![(0, 2), (1, 2), (2, 3)]); + DirectedTwoCommodityIntegralFlow::new(graph, vec![1; 3], 0, 3, 1, 3, 1, 1) +} + +#[test] +fn test_directed_two_commodity_integral_flow_creation() { + let problem = yes_instance(); + assert_eq!(problem.num_vertices(), 6); + assert_eq!(problem.num_arcs(), 8); + assert_eq!(problem.dims().len(), 16); // 2 * 8 + assert!(problem.dims().iter().all(|&d| d == 2)); // capacity 1 -> domain {0,1} + assert_eq!(problem.source_1(), 0); + assert_eq!(problem.sink_1(), 4); + assert_eq!(problem.source_2(), 1); + assert_eq!(problem.sink_2(), 5); + assert_eq!(problem.requirement_1(), 1); + assert_eq!(problem.requirement_2(), 1); + assert_eq!(problem.max_capacity(), 1); +} + +#[test] +fn test_directed_two_commodity_integral_flow_evaluation_satisfying() { + let problem = yes_instance(); + // Commodity 1: path 0->2->4 (arcs 0,4) + // Commodity 2: path 1->3->5 (arcs 3,7) + // config = [f1(a0..a7), f2(a0..a7)] + let config = vec![1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]; + assert!(problem.evaluate(&config)); +} + +#[test] +fn test_directed_two_commodity_integral_flow_evaluation_unsatisfying() { + let problem = no_instance(); + // All zeros: no flow at all + let config = vec![0, 0, 0, 0, 0, 0]; + assert!(!problem.evaluate(&config)); +} + +#[test] +fn test_directed_two_commodity_integral_flow_capacity_violation() { + let problem = yes_instance(); + // Try sending both commodities through the same arc (arc 0: 0->2) + // f1(a0)=1, f2(a0)=1 -> violates capacity 1 + let mut config = vec![0; 16]; + config[0] = 1; // f1 on arc 0 + config[8] = 1; // f2 on arc 0 + assert!(!problem.evaluate(&config)); +} + +#[test] +fn test_directed_two_commodity_integral_flow_conservation_violation() { + let problem = yes_instance(); + // f1 sends flow into vertex 2 but not out + let mut config = vec![0; 16]; + config[0] = 1; // f1 on arc 0 (0->2): flow into vertex 2 + // No outgoing flow from vertex 2 for commodity 1 + assert!(!problem.evaluate(&config)); +} + +#[test] +fn test_directed_two_commodity_integral_flow_solver_yes() { + let problem = yes_instance(); + let solver = BruteForce::new(); + let solution = solver.find_satisfying(&problem); + assert!(solution.is_some()); + let sol = solution.unwrap(); + assert!(problem.evaluate(&sol)); +} + +#[test] +fn test_directed_two_commodity_integral_flow_solver_no() { + let problem = no_instance(); + let solver = BruteForce::new(); + let solution = solver.find_satisfying(&problem); + assert!(solution.is_none()); +} + +#[test] +fn test_directed_two_commodity_integral_flow_serialization() { + let problem = yes_instance(); + let json = serde_json::to_string(&problem).unwrap(); + let deserialized: DirectedTwoCommodityIntegralFlow = serde_json::from_str(&json).unwrap(); + assert_eq!(deserialized.num_vertices(), 6); + assert_eq!(deserialized.num_arcs(), 8); + assert_eq!(deserialized.source_1(), 0); + assert_eq!(deserialized.sink_1(), 4); + assert_eq!(deserialized.source_2(), 1); + assert_eq!(deserialized.sink_2(), 5); + assert_eq!(deserialized.requirement_1(), 1); + assert_eq!(deserialized.requirement_2(), 1); +} + +#[test] +fn test_directed_two_commodity_integral_flow_problem_name() { + assert_eq!( + ::NAME, + "DirectedTwoCommodityIntegralFlow" + ); +} + +#[test] +fn test_directed_two_commodity_integral_flow_accessors() { + let problem = yes_instance(); + assert_eq!(problem.graph().num_vertices(), 6); + assert_eq!(problem.graph().num_arcs(), 8); + assert_eq!(problem.capacities(), &[1, 1, 1, 1, 1, 1, 1, 1]); +} + +#[test] +fn test_directed_two_commodity_integral_flow_paper_example() { + let problem = yes_instance(); + let solver = BruteForce::new(); + + // Verify the known solution evaluates to true + let config = vec![1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1]; + assert!(problem.evaluate(&config)); + + // Find all satisfying solutions and verify count + let all_solutions = solver.find_all_satisfying(&problem); + assert!(!all_solutions.is_empty()); + + // Each solution must evaluate to true + for sol in &all_solutions { + assert!(problem.evaluate(sol)); + } +} + +#[test] +fn test_directed_two_commodity_integral_flow_higher_capacity() { + // Test with capacity 2: two paths can share an arc + let graph = DirectedGraph::new(3, vec![(0, 1), (1, 2)]); + let problem = DirectedTwoCommodityIntegralFlow::new( + graph, + vec![2, 2], // capacity 2 on both arcs + 0, + 2, + 0, + 2, + 1, + 1, + ); + assert_eq!(problem.dims(), vec![3, 3, 3, 3]); // each variable in {0,1,2} + + // Both commodities can share: f1=1, f2=1 on both arcs + let config = vec![1, 1, 1, 1]; + assert!(problem.evaluate(&config)); + + let solver = BruteForce::new(); + assert!(solver.find_satisfying(&problem).is_some()); +} diff --git a/src/unit_tests/trait_consistency.rs b/src/unit_tests/trait_consistency.rs index 122362ef..1ec69dbe 100644 --- a/src/unit_tests/trait_consistency.rs +++ b/src/unit_tests/trait_consistency.rs @@ -102,6 +102,19 @@ fn test_all_problems_implement_trait_correctly() { ), "MinimumFeedbackArcSet", ); + check_problem_trait( + &DirectedTwoCommodityIntegralFlow::new( + DirectedGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]), + vec![1; 3], + 0, + 3, + 0, + 3, + 1, + 1, + ), + "DirectedTwoCommodityIntegralFlow", + ); check_problem_trait( &MinimumSumMulticenter::new( SimpleGraph::new(3, vec![(0, 1), (1, 2)]), From f9da9d9f2c027e9de35bbf094a1c90ed05bc909f Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 18:30:17 +0800 Subject: [PATCH 3/6] chore: remove plan file after implementation --- ...16-directed-two-commodity-integral-flow.md | 107 ------------------ 1 file changed, 107 deletions(-) delete mode 100644 docs/plans/2026-03-16-directed-two-commodity-integral-flow.md diff --git a/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md b/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md deleted file mode 100644 index 0b92a36f..00000000 --- a/docs/plans/2026-03-16-directed-two-commodity-integral-flow.md +++ /dev/null @@ -1,107 +0,0 @@ -# Plan: Add DirectedTwoCommodityIntegralFlow Model - -**Issue:** #295 -**Type:** [Model] -**Category:** `graph/` (directed graph input) - -## Overview - -Implement the Directed Two-Commodity Integral Flow problem (Garey & Johnson A2 ND38). This is a satisfaction problem: given a directed graph with arc capacities and two source-sink pairs with flow requirements, determine whether two integral flow functions exist that satisfy joint capacity constraints, flow conservation, and requirement thresholds. - -## Batch 1: Implementation (Steps 1-5.5) - -### Step 1: Category = `graph/` - -The problem takes a directed graph as primary input, so it belongs in `src/models/graph/`. - -### Step 1.5: Size getters - -From the complexity expression `(max_capacity + 1)^(2 * num_arcs)`: -- `num_vertices()` -> from `graph.num_vertices()` -- `num_arcs()` -> from `graph.num_arcs()` -- `max_capacity()` -> from `capacities.iter().max().copied().unwrap_or(0)` - -### Step 2: Implement the model - -Create `src/models/graph/directed_two_commodity_integral_flow.rs`: - -**Struct fields:** -- `graph: DirectedGraph` — directed graph G = (V, A) -- `capacities: Vec` — capacity c(a) for each arc -- `source_1: usize` — source vertex s_1 -- `sink_1: usize` — sink vertex t_1 -- `source_2: usize` — source vertex s_2 -- `sink_2: usize` — sink vertex t_2 -- `requirement_1: u64` — flow requirement R_1 -- `requirement_2: u64` — flow requirement R_2 - -**Problem trait:** -- `NAME = "DirectedTwoCommodityIntegralFlow"` -- `Metric = bool` (satisfaction problem) -- `dims()` = for each arc a, the domain for commodity i's flow is {0, ..., c(a)}. Configuration is a flat vector of 2*|A| variables: first |A| for commodity 1, next |A| for commodity 2. `dims()` returns `capacities.iter().chain(capacities.iter()).map(|&c| (c as usize) + 1).collect()` -- `evaluate()`: check (1) joint capacity f_1(a)+f_2(a) <= c(a) for all arcs, (2) flow conservation for each commodity at non-terminal vertices, (3) net flow into sink >= requirement for each commodity -- `variant()` = `variant_params![]` (no type parameters) - -**Implement `SatisfactionProblem` (marker trait).** - -**`inventory::submit!` for `ProblemSchemaEntry`** — fields: graph, capacities, source_1, sink_1, source_2, sink_2, requirement_1, requirement_2. No aliases (name is too long for a standard abbreviation, and none exists in the literature). No dimensions. - -### Step 2.5: Register variant complexity - -```rust -crate::declare_variants! { - default sat DirectedTwoCommodityIntegralFlow => "(max_capacity + 1)^(2 * num_arcs)", -} -``` - -### Step 3: Register the model - -1. `src/models/graph/mod.rs` — add `pub(crate) mod directed_two_commodity_integral_flow;` and `pub use directed_two_commodity_integral_flow::DirectedTwoCommodityIntegralFlow;` -2. `src/models/mod.rs` — add `DirectedTwoCommodityIntegralFlow` to the `graph::` re-export line - -### Step 4: CLI discovery - -Add lowercase alias mapping in `problemreductions-cli/src/problem_name.rs` `resolve_alias()` — no action needed since aliases are now catalog-driven via `ProblemSchemaEntry`. The `ProblemSchemaEntry` with no aliases is sufficient. - -### Step 4.5: CLI create support - -Add a match arm in `problemreductions-cli/src/commands/create.rs` for `"DirectedTwoCommodityIntegralFlow"`: -- Requires: `--arcs`, `--capacities`, `--source-1`, `--sink-1`, `--source-2`, `--sink-2`, `--requirement-1`, `--requirement-2` -- Add new CLI flags to `CreateArgs` in `problemreductions-cli/src/cli.rs`: `capacities`, `source_1`, `sink_1`, `source_2`, `sink_2`, `requirement_1`, `requirement_2` -- Update `all_data_flags_empty()` to include the new flags -- Add entry to "Flags by problem type" help table - -### Step 4.6: Canonical model example - -Add builder function in `src/example_db/model_builders.rs` — use the YES instance from the issue: 6 vertices, 8 arcs (all capacity 1), source_1=0, sink_1=4, source_2=1, sink_2=5, R_1=1, R_2=1. Known satisfying solution: commodity 1 path 0->2->4, commodity 2 path 1->3->5. - -Register in `src/models/graph/mod.rs` `canonical_model_example_specs()`. - -### Step 5: Unit tests - -Create `src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs`: - -- `test_directed_two_commodity_integral_flow_creation` — construct the 6-vertex instance, verify dims -- `test_directed_two_commodity_integral_flow_evaluation_satisfying` — verify the YES instance evaluates to `true` -- `test_directed_two_commodity_integral_flow_evaluation_unsatisfying` — verify the NO instance evaluates to `false` -- `test_directed_two_commodity_integral_flow_solver` — use BruteForce::find_satisfying on the YES instance -- `test_directed_two_commodity_integral_flow_no_solution` — verify BruteForce::find_satisfying returns None on the NO instance -- `test_directed_two_commodity_integral_flow_serialization` — round-trip serde -- `test_directed_two_commodity_integral_flow_paper_example` — verify example from paper (same as YES instance), check solution count - -Link via `#[cfg(test)] #[path = "..."] mod tests;` - -### Step 5.5: Trait consistency - -Add `check_problem_trait(...)` call in `src/unit_tests/trait_consistency.rs` for `DirectedTwoCommodityIntegralFlow`. -No `test_direction` entry needed (satisfaction problem). - -## Batch 2: Paper Entry (Step 6) - -### Step 6: Document in paper - -Add to `docs/paper/reductions.typ`: -1. Display name: `"DirectedTwoCommodityIntegralFlow": [Directed Two-Commodity Integral Flow]` -2. `problem-def("DirectedTwoCommodityIntegralFlow")` with formal definition and body (background, example with CeTZ diagram showing the 6-vertex network with two commodity paths highlighted) - -Run `make paper` to verify compilation. From a8985945875abad60e5609b4ef027374273c6e6b Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 21:09:23 +0800 Subject: [PATCH 4/6] fix: address PR #660 review follow-ups --- problemreductions-cli/tests/cli_tests.rs | 42 +++++++++++++++ src/example_db/fixtures/examples.json | 26 +++++----- .../directed_two_commodity_integral_flow.rs | 52 ++++++------------- .../directed_two_commodity_integral_flow.rs | 10 ++++ 4 files changed, 82 insertions(+), 48 deletions(-) diff --git a/problemreductions-cli/tests/cli_tests.rs b/problemreductions-cli/tests/cli_tests.rs index d29ba247..a6acbaf5 100644 --- a/problemreductions-cli/tests/cli_tests.rs +++ b/problemreductions-cli/tests/cli_tests.rs @@ -594,6 +594,48 @@ fn test_create_x3c_alias() { std::fs::remove_file(&output_file).ok(); } +#[test] +fn test_create_d2cif_alias() { + let output_file = std::env::temp_dir().join("pred_test_create_d2cif.json"); + let output = pred() + .args([ + "-o", + output_file.to_str().unwrap(), + "create", + "D2CIF", + "--arcs", + "0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5", + "--capacities", + "1,1,1,1,1,1,1,1", + "--source-1", + "0", + "--sink-1", + "4", + "--source-2", + "1", + "--sink-2", + "5", + "--requirement-1", + "1", + "--requirement-2", + "1", + ]) + .output() + .unwrap(); + assert!( + output.status.success(), + "stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert!(output_file.exists()); + + let content = std::fs::read_to_string(&output_file).unwrap(); + let json: serde_json::Value = serde_json::from_str(&content).unwrap(); + assert_eq!(json["type"], "DirectedTwoCommodityIntegralFlow"); + + std::fs::remove_file(&output_file).ok(); +} + #[test] fn test_create_x3c_rejects_duplicate_subset_elements() { let output = pred() diff --git a/src/example_db/fixtures/examples.json b/src/example_db/fixtures/examples.json index a45520b5..fa0589f3 100644 --- a/src/example_db/fixtures/examples.json +++ b/src/example_db/fixtures/examples.json @@ -4,7 +4,7 @@ {"problem":"BicliqueCover","variant":{},"instance":{"graph":{"edges":[[0,0],[0,1],[1,1],[1,2]],"left_size":2,"right_size":3},"k":2},"samples":[{"config":[1,0,0,1,1,0,1,1,0,1],"metric":{"Valid":6}}],"optimal":[{"config":[0,1,0,1,0,1,0,1,0,1],"metric":{"Valid":5}},{"config":[1,0,1,0,1,0,1,0,1,0],"metric":{"Valid":5}}]}, {"problem":"CircuitSAT","variant":{},"instance":{"circuit":{"assignments":[{"expr":{"op":{"And":[{"op":{"Var":"x1"}},{"op":{"Var":"x2"}}]}},"outputs":["a"]},{"expr":{"op":{"Or":[{"op":{"Var":"x1"}},{"op":{"Var":"x2"}}]}},"outputs":["b"]},{"expr":{"op":{"Xor":[{"op":{"Var":"a"}},{"op":{"Var":"b"}}]}},"outputs":["c"]}]},"variables":["a","b","c","x1","x2"]},"samples":[{"config":[0,1,1,0,1],"metric":true},{"config":[0,1,1,1,0],"metric":true}],"optimal":[{"config":[0,0,0,0,0],"metric":true},{"config":[0,1,1,0,1],"metric":true},{"config":[0,1,1,1,0],"metric":true},{"config":[1,1,0,1,1],"metric":true}]}, {"problem":"ClosestVectorProblem","variant":{"weight":"i32"},"instance":{"basis":[[2,0],[1,2]],"bounds":[{"lower":-2,"upper":4},{"lower":-2,"upper":4}],"target":[2.8,1.5]},"samples":[{"config":[3,3],"metric":{"Valid":0.5385164807134505}}],"optimal":[{"config":[3,3],"metric":{"Valid":0.5385164807134505}}]}, - {"problem":"DirectedTwoCommodityIntegralFlow","variant":{},"instance":{"capacities":[1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"directed","edges":[[0,2,null],[0,3,null],[1,2,null],[1,3,null],[2,4,null],[2,5,null],[3,4,null],[3,5,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}},"requirement_1":1,"requirement_2":1,"sink_1":4,"sink_2":5,"source_1":0,"source_2":1},"samples":[{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true}],"optimal":[{"config":[0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1],"metric":true}]}, + {"problem":"DirectedTwoCommodityIntegralFlow","variant":{},"instance":{"capacities":[1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"directed","edges":[[0,2,null],[0,3,null],[1,2,null],[1,3,null],[2,4,null],[2,5,null],[3,4,null],[3,5,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}},"requirement_1":1,"requirement_2":1,"sink_1":4,"sink_2":5,"source_1":0,"source_2":1},"samples":[{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true}],"optimal":[{"config":[0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[0,0,0,1,0,0,1,0,0,1,1,0,0,1,0,1],"metric":true},{"config":[0,0,0,1,0,0,1,0,0,1,1,0,1,0,0,1],"metric":true},{"config":[0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,0,0,1,0,0,1,0,1,0,1,0,1,1,0,0],"metric":true},{"config":[0,0,0,1,0,0,1,0,1,1,0,0,0,1,0,1],"metric":true},{"config":[0,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1],"metric":true},{"config":[0,0,0,1,0,0,1,0,1,1,1,0,1,1,0,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,0,1,0,1,0,0,1,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,0,0,1,0,1,0,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,0,0,1,0,1,1,0],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,1,0,0,0,1,0,1],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,1,0,0,0,1,1,0],"metric":true},{"config":[0,0,1,0,1,0,0,0,1,1,0,1,0,1,1,1],"metric":true},{"config":[0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,1],"metric":true},{"config":[0,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0],"metric":true},{"config":[0,0,1,1,1,0,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[0,0,1,1,1,0,1,0,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,0,1,1,1,0,1,0,1,1,0,0,0,1,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,0,0,1,1,1,0,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,1,0,0,0,0,1,0,1,0,0,1,0,1,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,1,0,0,1,1,0,0,1],"metric":true},{"config":[0,1,0,0,0,0,1,0,1,0,1,0,1,1,0,0],"metric":true},{"config":[0,1,0,0,0,0,1,0,1,0,1,1,1,1,0,1],"metric":true},{"config":[0,1,0,1,0,0,1,1,0,0,1,0,0,1,0,0],"metric":true},{"config":[0,1,0,1,0,0,1,1,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,1,0,1,0,0,1,1,1,0,1,0,1,1,0,0],"metric":true},{"config":[0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,1,1,0,0,1,1,0,1,0,0,1,1,0,0,1],"metric":true},{"config":[0,1,1,0,1,0,0,1,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0],"metric":true},{"config":[0,1,1,0,1,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[0,1,1,0,1,0,1,0,1,0,0,0,0,1,0,0],"metric":true},{"config":[0,1,1,0,1,0,1,0,1,0,0,1,0,1,0,1],"metric":true},{"config":[0,1,1,1,1,0,1,1,1,0,0,0,0,1,0,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,1,1,0,0,1,0,1],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,1,1,0,0,1,1,0],"metric":true},{"config":[1,0,0,0,1,0,0,0,0,1,1,1,0,1,1,1],"metric":true},{"config":[1,0,0,1,0,1,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1],"metric":true},{"config":[1,0,0,1,1,0,0,1,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,0,0,1,1,0,0,1,0,1,1,0,0,1,1,0],"metric":true},{"config":[1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,0,0,1,1,0,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1],"metric":true},{"config":[1,0,1,0,1,1,0,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,0,1,0,1,1,0,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[1,0,1,0,1,1,0,0,0,1,0,1,0,0,1,1],"metric":true},{"config":[1,0,1,1,1,1,1,0,0,1,0,0,0,0,0,1],"metric":true},{"config":[1,1,0,0,0,1,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1],"metric":true},{"config":[1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,0,1,0,0,0,1],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1],"metric":true},{"config":[1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0],"metric":true},{"config":[1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,1],"metric":true}]}, {"problem":"ExactCoverBy3Sets","variant":{},"instance":{"subsets":[[0,1,2],[0,2,4],[3,4,5],[3,5,7],[6,7,8],[1,4,6],[2,5,8]],"universe_size":9},"samples":[{"config":[1,0,1,0,1,0,0],"metric":true}],"optimal":[{"config":[1,0,1,0,1,0,0],"metric":true}]}, {"problem":"Factoring","variant":{},"instance":{"m":2,"n":3,"target":15},"samples":[{"config":[1,1,1,0,1],"metric":{"Valid":0}}],"optimal":[{"config":[1,1,1,0,1],"metric":{"Valid":0}}]}, {"problem":"HamiltonianPath","variant":{"graph":"SimpleGraph"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,3,null],[2,3,null],[3,4,null],[3,5,null],[4,2,null],[5,1,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}}},"samples":[{"config":[0,2,4,3,1,5],"metric":true}],"optimal":[{"config":[0,1,5,3,2,4],"metric":true},{"config":[0,1,5,3,4,2],"metric":true},{"config":[0,2,4,3,1,5],"metric":true},{"config":[0,2,4,3,5,1],"metric":true},{"config":[1,0,2,4,3,5],"metric":true},{"config":[1,5,3,4,2,0],"metric":true},{"config":[2,0,1,5,3,4],"metric":true},{"config":[2,4,3,5,1,0],"metric":true},{"config":[3,4,2,0,1,5],"metric":true},{"config":[3,5,1,0,2,4],"metric":true},{"config":[4,2,0,1,3,5],"metric":true},{"config":[4,2,0,1,5,3],"metric":true},{"config":[4,2,3,5,1,0],"metric":true},{"config":[4,3,2,0,1,5],"metric":true},{"config":[4,3,5,1,0,2],"metric":true},{"config":[5,1,0,2,3,4],"metric":true},{"config":[5,1,0,2,4,3],"metric":true},{"config":[5,1,3,4,2,0],"metric":true},{"config":[5,3,1,0,2,4],"metric":true},{"config":[5,3,4,2,0,1],"metric":true}]}, @@ -44,18 +44,18 @@ {"source":{"problem":"KColoring","variant":{"graph":"SimpleGraph","k":"KN"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"num_colors":3}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Eq","rhs":1.0,"terms":[[0,1.0],[1,1.0],[2,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[3,1.0],[4,1.0],[5,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[6,1.0],[7,1.0],[8,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[9,1.0],[10,1.0],[11,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[12,1.0],[13,1.0],[14,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[15,1.0],[16,1.0],[17,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[18,1.0],[19,1.0],[20,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[21,1.0],[22,1.0],[23,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[24,1.0],[25,1.0],[26,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[27,1.0],[28,1.0],[29,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[3,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[4,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0],[5,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[12,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[13,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0],[14,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[15,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[16,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0],[17,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[3,1.0],[6,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[4,1.0],[7,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[5,1.0],[8,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[3,1.0],[18,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[4,1.0],[19,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[5,1.0],[20,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[6,1.0],[9,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[7,1.0],[10,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[8,1.0],[11,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[6,1.0],[21,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[7,1.0],[22,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[8,1.0],[23,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[9,1.0],[12,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[10,1.0],[13,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[11,1.0],[14,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[9,1.0],[24,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[10,1.0],[25,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[11,1.0],[26,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[12,1.0],[27,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[13,1.0],[28,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[14,1.0],[29,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[15,1.0],[21,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[16,1.0],[22,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[17,1.0],[23,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[15,1.0],[24,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[16,1.0],[25,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[17,1.0],[26,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[18,1.0],[24,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[19,1.0],[25,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[20,1.0],[26,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[18,1.0],[27,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[19,1.0],[28,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[20,1.0],[29,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[21,1.0],[27,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[22,1.0],[28,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[23,1.0],[29,1.0]]}],"num_vars":30,"objective":[],"sense":"Minimize"}},"solutions":[{"source_config":[0,2,0,1,2,1,1,2,0,0],"target_config":[1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,1,1,0,0,1,0,0]}]}, {"source":{"problem":"KColoring","variant":{"graph":"SimpleGraph","k":"KN"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,3,null],[2,3,null],[2,4,null],[3,4,null]],"node_holes":[],"nodes":[null,null,null,null,null]}},"num_colors":3}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-6.0,12.0,12.0,3.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,-6.0,12.0,0.0,3.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,-6.0,0.0,0.0,3.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,-6.0,12.0,12.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,-6.0,12.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,-6.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0,12.0,3.0,0.0,0.0,3.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0,0.0,3.0,0.0,0.0,3.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,0.0,0.0,3.0,0.0,0.0,3.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0,12.0,3.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0,0.0,3.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,0.0,0.0,3.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0,12.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,12.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0]],"num_vars":15}},"solutions":[{"source_config":[1,2,2,1,0],"target_config":[0,1,0,0,0,1,0,0,1,0,1,0,1,0,0]}]}, {"source":{"problem":"KSatisfiability","variant":{"k":"K2"},"instance":{"clauses":[{"literals":[1,2]},{"literals":[-1,3]},{"literals":[-2,4]},{"literals":[-3,-4]}],"num_vars":4}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[0.0,1.0,-1.0,0.0],[0.0,0.0,0.0,-1.0],[0.0,0.0,0.0,1.0],[0.0,0.0,0.0,0.0]],"num_vars":4}},"solutions":[{"source_config":[0,1,0,1],"target_config":[0,1,0,1]}]}, - {"source":{"problem":"KSatisfiability","variant":{"k":"K3"},"instance":{"clauses":[{"literals":[1,2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[-2,3,-5]},{"literals":[1,-3,5]},{"literals":[-1,-2,4]},{"literals":[3,-4,-5]}],"num_vars":5}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[0.0,4.0,-4.0,0.0,0.0,4.0,-4.0,0.0,0.0,4.0,-4.0,0.0],[0.0,0.0,-2.0,-2.0,0.0,4.0,0.0,4.0,-4.0,0.0,-4.0,0.0],[0.0,0.0,2.0,-2.0,0.0,1.0,4.0,0.0,4.0,-4.0,0.0,4.0],[0.0,0.0,0.0,4.0,0.0,0.0,-1.0,-4.0,0.0,0.0,-1.0,-4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,1.0,-1.0,0.0,1.0],[0.0,0.0,0.0,0.0,0.0,-2.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,7.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0]],"num_vars":12}},"solutions":[{"source_config":[0,0,0,0,0],"target_config":[0,0,0,0,0,1,0,0,0,0,0,0]}]}, + {"source":{"problem":"KSatisfiability","variant":{"k":"K3"},"instance":{"clauses":[{"literals":[1,2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[-2,3,-5]},{"literals":[1,-3,5]},{"literals":[-1,-2,4]},{"literals":[3,-4,-5]}],"num_vars":5}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[0.0,4.0,-4.0,0.0,0.0,4.0,-4.0,0.0,0.0,4.0,-4.0,0.0],[0.0,0.0,-2.0,-2.0,0.0,4.0,0.0,4.0,-4.0,0.0,-4.0,0.0],[0.0,0.0,2.0,-2.0,0.0,1.0,4.0,0.0,4.0,-4.0,0.0,4.0],[0.0,0.0,0.0,4.0,0.0,0.0,-1.0,-4.0,0.0,0.0,-1.0,-4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0,1.0,-1.0,0.0,1.0],[0.0,0.0,0.0,0.0,0.0,-2.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,3.0,0.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,7.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0]],"num_vars":12}},"solutions":[{"source_config":[1,1,1,1,1],"target_config":[1,1,1,1,1,0,0,0,0,0,1,0]}]}, {"source":{"problem":"KSatisfiability","variant":{"k":"K3"},"instance":{"clauses":[{"literals":[1,2,3]},{"literals":[-1,-2,3]}],"num_vars":3}},"target":{"problem":"SubsetSum","variant":{},"instance":{"sizes":["10010","10001","1010","1001","111","100","10","20","1","2"],"target":"11144"}},"solutions":[{"source_config":[0,0,1],"target_config":[0,1,0,1,1,0,1,1,1,0]}]}, {"source":{"problem":"KSatisfiability","variant":{"k":"KN"},"instance":{"clauses":[{"literals":[1,-2,3]},{"literals":[-1,3,4]},{"literals":[2,-3,-4]}],"num_vars":4}},"target":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1,-2,3]},{"literals":[-1,3,4]},{"literals":[2,-3,-4]}],"num_vars":4}},"solutions":[{"source_config":[1,1,1,0],"target_config":[1,1,1,0]}]}, {"source":{"problem":"Knapsack","variant":{},"instance":{"capacity":7,"values":[3,4,5,7],"weights":[2,3,4,5]}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-483.0,240.0,320.0,400.0,80.0,160.0,320.0],[0.0,-664.0,480.0,600.0,120.0,240.0,480.0],[0.0,0.0,-805.0,800.0,160.0,320.0,640.0],[0.0,0.0,0.0,-907.0,200.0,400.0,800.0],[0.0,0.0,0.0,0.0,-260.0,80.0,160.0],[0.0,0.0,0.0,0.0,0.0,-480.0,320.0],[0.0,0.0,0.0,0.0,0.0,0.0,-800.0]],"num_vars":7}},"solutions":[{"source_config":[1,0,0,1],"target_config":[1,0,0,1,0,0,0]}]}, {"source":{"problem":"LongestCommonSubsequence","variant":{},"instance":{"strings":[[65,66,65,67],[66,65,67,65]]}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[1,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[3,1.0],[4,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[5,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[3,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[5,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[4,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[2,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[2,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[3,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[5,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[4,1.0],[5,1.0]]}],"num_vars":6,"objective":[[0,1.0],[1,1.0],[2,1.0],[3,1.0],[4,1.0],[5,1.0]],"sense":"Maximize"}},"solutions":[{"source_config":[0,1,1,1],"target_config":[0,0,1,1,0,1]}]}, - {"source":{"problem":"MaxCut","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"couplings":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"fields":[0,0,0,0,0,0,0,0,0,0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"solutions":[{"source_config":[0,1,0,1,0,1,0,0,0,1],"target_config":[0,1,0,1,0,1,0,0,0,1]}]}, + {"source":{"problem":"MaxCut","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"couplings":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"fields":[0,0,0,0,0,0,0,0,0,0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"solutions":[{"source_config":[1,0,1,0,0,0,0,0,1,1],"target_config":[1,0,1,0,0,0,0,0,1,1]}]}, {"source":{"problem":"MaximumClique","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[0,3,null],[0,4,null],[1,2,null],[1,3,null],[1,5,null],[2,4,null],[2,5,null],[3,4,null],[3,5,null],[4,5,null]],"node_holes":[],"nodes":[null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1]}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[5,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[4,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0],[3,1.0]]}],"num_vars":6,"objective":[[0,1.0],[1,1.0],[2,1.0],[3,1.0],[4,1.0],[5,1.0]],"sense":"Maximize"}},"solutions":[{"source_config":[1,1,1,0,0,0],"target_config":[1,1,1,0,0,0]}]}, {"source":{"problem":"MaximumClique","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[1,2,null],[2,3,null]],"node_holes":[],"nodes":[null,null,null,null]}},"weights":[1,1,1,1]}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,2,null],[0,3,null],[1,3,null]],"node_holes":[],"nodes":[null,null,null,null]}},"weights":[1,1,1,1]}},"solutions":[{"source_config":[0,1,1,0],"target_config":[0,1,1,0]}]}, - {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"One"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumSetPacking","variant":{"weight":"One"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,0,1,0,0,1,1,0,0],"target_config":[1,0,0,1,0,0,1,1,0,0]}]}, + {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"One"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumSetPacking","variant":{"weight":"One"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,1,0,0,0,0,0,1,1],"target_config":[1,0,1,0,0,0,0,0,1,1]}]}, {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[1,2,null],[2,3,null],[3,4,null]],"node_holes":[],"nodes":[null,null,null,null,null]}},"weights":[1,1,1,1,1]}},"target":{"problem":"MaximumClique","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,2,null],[0,3,null],[0,4,null],[1,3,null],[1,4,null],[2,4,null]],"node_holes":[],"nodes":[null,null,null,null,null]}},"weights":[1,1,1,1,1]}},"solutions":[{"source_config":[1,0,1,0,1],"target_config":[1,0,1,0,1]}]}, - {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumSetPacking","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,0,1,0,0,1,1,0,0],"target_config":[1,0,0,1,0,0,1,1,0,0]}]}, - {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,0,1,0,0,1,1,0,0],"target_config":[0,1,1,0,1,1,0,0,1,1]}]}, + {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumSetPacking","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,1,0,0,0,0,0,1,1],"target_config":[1,0,1,0,0,0,0,0,1,1]}]}, + {"source":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,1,0,0,0,0,0,1,1],"target_config":[0,1,0,1,1,1,1,1,0,0]}]}, {"source":{"problem":"MaximumMatching","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[1,1.0],[2,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[0,1.0],[3,1.0],[4,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[3,1.0],[5,1.0],[6,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[5,1.0],[7,1.0],[8,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[1,1.0],[7,1.0],[9,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[2,1.0],[10,1.0],[11,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[4,1.0],[12,1.0],[13,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[6,1.0],[10,1.0],[14,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[8,1.0],[11,1.0],[12,1.0]]},{"cmp":"Le","rhs":1.0,"terms":[[9,1.0],[13,1.0],[14,1.0]]}],"num_vars":15,"objective":[[0,1.0],[1,1.0],[2,1.0],[3,1.0],[4,1.0],[5,1.0],[6,1.0],[7,1.0],[8,1.0],[9,1.0],[10,1.0],[11,1.0],[12,1.0],[13,1.0],[14,1.0]],"sense":"Maximize"}},"solutions":[{"source_config":[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1],"target_config":[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1]}]}, {"source":{"problem":"MaximumMatching","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"MaximumSetPacking","variant":{"weight":"i32"},"instance":{"sets":[[0,1],[0,4],[0,5],[1,2],[1,6],[2,3],[2,7],[3,4],[3,8],[4,9],[5,7],[5,8],[6,8],[6,9],[7,9]],"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1],"target_config":[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1]}]}, {"source":{"problem":"MaximumSetPacking","variant":{"weight":"One"},"instance":{"sets":[[0,1,2],[2,3],[4,5,6],[1,5,7],[3,6]],"weights":[1,1,1,1,1]}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"One"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,3,null],[1,4,null],[2,3,null],[2,4,null]],"node_holes":[],"nodes":[null,null,null,null,null]}},"weights":[1,1,1,1,1]}},"solutions":[{"source_config":[1,0,0,0,1],"target_config":[1,0,0,0,1]}]}, @@ -64,18 +64,18 @@ {"source":{"problem":"MaximumSetPacking","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[2,3],[4,5,6],[1,5,7],[3,6]],"weights":[1,1,1,1,1]}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,3,null],[1,4,null],[2,3,null],[2,4,null]],"node_holes":[],"nodes":[null,null,null,null,null]}},"weights":[1,1,1,1,1]}},"solutions":[{"source_config":[1,0,0,0,1],"target_config":[1,0,0,0,1]}]}, {"source":{"problem":"MinimumDominatingSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Ge","rhs":1.0,"terms":[[0,1.0],[5,1.0],[4,1.0],[1,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[1,1.0],[6,1.0],[2,1.0],[0,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[2,1.0],[7,1.0],[3,1.0],[1,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[3,1.0],[8,1.0],[4,1.0],[2,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[4,1.0],[9,1.0],[3,1.0],[0,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[5,1.0],[8,1.0],[7,1.0],[0,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[6,1.0],[9,1.0],[8,1.0],[1,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[7,1.0],[9,1.0],[5,1.0],[2,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[8,1.0],[6,1.0],[5,1.0],[3,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[9,1.0],[7,1.0],[6,1.0],[4,1.0]]}],"num_vars":10,"objective":[[0,1.0],[1,1.0],[2,1.0],[3,1.0],[4,1.0],[5,1.0],[6,1.0],[7,1.0],[8,1.0],[9,1.0]],"sense":"Minimize"}},"solutions":[{"source_config":[0,0,1,0,0,1,0,0,0,1],"target_config":[0,0,1,0,0,1,0,0,0,1]}]}, {"source":{"problem":"MinimumSetCovering","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[2,3,4],[4,5,6],[6,7,0],[1,3,5],[0,4,7]],"universe_size":8,"weights":[1,1,1,1,1,1]}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Ge","rhs":1.0,"terms":[[0,1.0],[3,1.0],[5,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[0,1.0],[4,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[0,1.0],[1,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[1,1.0],[4,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[1,1.0],[2,1.0],[5,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[2,1.0],[4,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[2,1.0],[3,1.0]]},{"cmp":"Ge","rhs":1.0,"terms":[[3,1.0],[5,1.0]]}],"num_vars":6,"objective":[[0,1.0],[1,1.0],[2,1.0],[3,1.0],[4,1.0],[5,1.0]],"sense":"Minimize"}},"solutions":[{"source_config":[0,1,0,1,1,0],"target_config":[0,1,0,1,1,0]}]}, - {"source":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[0,1,1,0,1,1,0,0,1,1],"target_config":[1,0,0,1,0,0,1,1,0,0]}]}, - {"source":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MinimumSetCovering","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"universe_size":15,"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[0,1,1,0,1,1,0,0,1,1],"target_config":[0,1,1,0,1,1,0,0,1,1]}]}, + {"source":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[0,1,0,1,1,1,1,1,0,0],"target_config":[1,0,1,0,0,0,0,0,1,1]}]}, + {"source":{"problem":"MinimumVertexCover","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1]}},"target":{"problem":"MinimumSetCovering","variant":{"weight":"i32"},"instance":{"sets":[[0,1,2],[0,3,4],[3,5,6],[5,7,8],[1,7,9],[2,10,11],[4,12,13],[6,10,14],[8,11,12],[9,13,14]],"universe_size":15,"weights":[1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[0,1,0,1,1,1,1,1,0,0],"target_config":[0,1,0,1,1,1,1,1,0,0]}]}, {"source":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-2.0,1.0,0.0,0.0],[0.0,-3.0,2.0,0.0],[0.0,0.0,-1.0,-1.0],[0.0,0.0,0.0,-4.0]],"num_vars":4}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Le","rhs":0.0,"terms":[[4,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[4,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[4,1.0],[0,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[5,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[5,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[5,1.0],[1,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[6,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[6,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[6,1.0],[2,-1.0],[3,-1.0]]}],"num_vars":7,"objective":[[0,-2.0],[1,-3.0],[2,-1.0],[3,-4.0],[4,1.0],[5,2.0],[6,-1.0]],"sense":"Minimize"}},"solutions":[{"source_config":[1,1,1,1],"target_config":[1,1,1,1,1,1,1]}]}, {"source":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-1.0,2.0,0.0,0.0,-1.5,2.0,0.0,0.0,0.0,0.0],[0.0,-0.8,-1.5,0.0,0.0,0.0,2.0,0.0,0.0,0.0],[0.0,0.0,-0.6,-1.5,0.0,0.0,0.0,2.0,0.0,0.0],[0.0,0.0,0.0,-0.3999999999999999,-1.5,0.0,0.0,0.0,2.0,0.0],[0.0,0.0,0.0,0.0,-0.19999999999999996,0.0,0.0,0.0,0.0,-1.5],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,-1.5,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.20000000000000018,0.0,2.0,-1.5],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.40000000000000013,0.0,2.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.6000000000000001,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8]],"num_vars":10}},"target":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"f64"},"instance":{"couplings":[0.5,-0.375,0.5,-0.375,0.5,-0.375,0.5,-0.375,0.5,-0.375,0.5,-0.375,0.5,-0.375,0.5],"fields":[0.125,0.22499999999999998,-0.55,-0.44999999999999996,-1.225,0.625,0.7250000000000001,1.7000000000000002,0.925,0.15000000000000002],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"solutions":[{"source_config":[1,0,1,1,1,0,1,0,0,1],"target_config":[1,0,1,1,1,0,1,0,0,1]}]}, {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1,-2,3]},{"literals":[-1,2]},{"literals":[2,3]}],"num_vars":3}},"target":{"problem":"CircuitSAT","variant":{},"instance":{"circuit":{"assignments":[{"expr":{"op":{"Or":[{"op":{"Var":"x1"}},{"op":{"Not":{"op":{"Var":"x2"}}}},{"op":{"Var":"x3"}}]}},"outputs":["__clause_0"]},{"expr":{"op":{"Or":[{"op":{"Not":{"op":{"Var":"x1"}}}},{"op":{"Var":"x2"}}]}},"outputs":["__clause_1"]},{"expr":{"op":{"Or":[{"op":{"Var":"x2"}},{"op":{"Var":"x3"}}]}},"outputs":["__clause_2"]},{"expr":{"op":{"And":[{"op":{"Var":"__clause_0"}},{"op":{"Var":"__clause_1"}},{"op":{"Var":"__clause_2"}}]}},"outputs":["__out"]},{"expr":{"op":{"Const":true}},"outputs":["__out"]}]},"variables":["__clause_0","__clause_1","__clause_2","__out","x1","x2","x3"]}},"solutions":[{"source_config":[1,1,1],"target_config":[1,1,1,1,1,1,1]}]}, {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1]},{"literals":[-3]},{"literals":[5]}],"num_vars":5}},"target":{"problem":"KColoring","variant":{"graph":"SimpleGraph","k":"K3"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,2,null],[3,2,null],[8,2,null],[3,8,null],[4,2,null],[9,2,null],[4,9,null],[5,2,null],[10,2,null],[5,10,null],[6,2,null],[11,2,null],[6,11,null],[7,2,null],[12,2,null],[7,12,null],[3,2,null],[3,1,null],[10,2,null],[10,1,null],[7,2,null],[7,1,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null,null,null,null]}},"num_colors":3}},"solutions":[{"source_config":[1,1,0,1,1],"target_config":[2,1,0,2,2,1,2,2,1,1,2,1,1]}]}, - {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1]},{"literals":[2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[1,-2,3,-5]},{"literals":[-1,2,-3,4,5]}],"num_vars":5}},"target":{"problem":"KSatisfiability","variant":{"k":"K3"},"instance":{"clauses":[{"literals":[1,6,7]},{"literals":[1,6,-7]},{"literals":[1,-6,8]},{"literals":[1,-6,-8]},{"literals":[2,-3,9]},{"literals":[2,-3,-9]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[1,-2,10]},{"literals":[-10,3,-5]},{"literals":[-1,2,11]},{"literals":[-11,-3,12]},{"literals":[-12,4,5]}],"num_vars":12}},"solutions":[{"source_config":[1,1,1,0,1],"target_config":[1,1,1,0,1,0,0,0,0,1,1,1]}]}, + {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1]},{"literals":[2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[1,-2,3,-5]},{"literals":[-1,2,-3,4,5]}],"num_vars":5}},"target":{"problem":"KSatisfiability","variant":{"k":"K3"},"instance":{"clauses":[{"literals":[1,6,7]},{"literals":[1,6,-7]},{"literals":[1,-6,8]},{"literals":[1,-6,-8]},{"literals":[2,-3,9]},{"literals":[2,-3,-9]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[1,-2,10]},{"literals":[-10,3,-5]},{"literals":[-1,2,11]},{"literals":[-11,-3,12]},{"literals":[-12,4,5]}],"num_vars":12}},"solutions":[{"source_config":[1,0,0,1,1],"target_config":[1,0,0,1,1,0,0,0,0,0,1,1]}]}, {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1,2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[-2,3,-5]},{"literals":[1,-3,5]},{"literals":[-1,-2,4]},{"literals":[3,-4,-5]}],"num_vars":5}},"target":{"problem":"MaximumIndependentSet","variant":{"graph":"SimpleGraph","weight":"One"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,2,null],[3,4,null],[3,5,null],[4,5,null],[6,7,null],[6,8,null],[7,8,null],[9,10,null],[9,11,null],[10,11,null],[12,13,null],[12,14,null],[13,14,null],[15,16,null],[15,17,null],[16,17,null],[18,19,null],[18,20,null],[19,20,null],[0,3,null],[0,15,null],[1,9,null],[1,16,null],[2,4,null],[2,10,null],[2,18,null],[3,12,null],[4,13,null],[5,7,null],[5,19,null],[6,9,null],[6,16,null],[7,17,null],[8,11,null],[8,20,null],[10,13,null],[11,14,null],[12,15,null],[13,18,null],[14,20,null],[17,19,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,1,1,1,0],"target_config":[1,0,0,0,1,0,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0]}]}, {"source":{"problem":"Satisfiability","variant":{},"instance":{"clauses":[{"literals":[1,2,-3]},{"literals":[-1,3,4]},{"literals":[2,-4,5]},{"literals":[-2,3,-5]},{"literals":[1,-3,5]},{"literals":[-1,-2,4]},{"literals":[3,-4,-5]}],"num_vars":5}},"target":{"problem":"MinimumDominatingSet","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,2,null],[3,4,null],[3,5,null],[4,5,null],[6,7,null],[6,8,null],[7,8,null],[9,10,null],[9,11,null],[10,11,null],[12,13,null],[12,14,null],[13,14,null],[0,15,null],[3,15,null],[7,15,null],[1,16,null],[6,16,null],[9,16,null],[3,17,null],[10,17,null],[12,17,null],[4,18,null],[6,18,null],[13,18,null],[0,19,null],[7,19,null],[12,19,null],[1,20,null],[4,20,null],[9,20,null],[6,21,null],[10,21,null],[13,21,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]}},"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}},"solutions":[{"source_config":[1,0,1,1,1],"target_config":[1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0]}]}, - {"source":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"f64"},"instance":{"couplings":[1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0],"fields":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-2.0,4.0,0.0,0.0,-4.0,4.0,0.0,0.0,0.0,0.0],[0.0,-2.0,-4.0,0.0,0.0,0.0,4.0,0.0,0.0,0.0],[0.0,0.0,2.0,-4.0,0.0,0.0,0.0,4.0,0.0,0.0],[0.0,0.0,0.0,2.0,-4.0,0.0,0.0,0.0,4.0,0.0],[0.0,0.0,0.0,0.0,6.0,0.0,0.0,0.0,0.0,-4.0],[0.0,0.0,0.0,0.0,0.0,-2.0,0.0,4.0,-4.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,-2.0,0.0,4.0,-4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,0.0,4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-2.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0]],"num_vars":10}},"solutions":[{"source_config":[1,0,1,1,1,0,1,0,0,1],"target_config":[1,0,1,1,1,0,1,0,0,1]}]}, - {"source":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"couplings":[1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1],"fields":[0,0,0,0,0,0,0,0,0,0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"MaxCut","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"solutions":[{"source_config":[1,0,1,1,1,0,1,0,0,1],"target_config":[1,0,1,1,1,0,1,0,0,1]}]}, - {"source":{"problem":"TravelingSalesman","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[10,15,20,35,25,30],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[0,3,null],[1,2,null],[1,3,null],[2,3,null]],"node_holes":[],"nodes":[null,null,null,null]}}}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Eq","rhs":1.0,"terms":[[0,1.0],[1,1.0],[2,1.0],[3,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[4,1.0],[5,1.0],[6,1.0],[7,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[8,1.0],[9,1.0],[10,1.0],[11,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[12,1.0],[13,1.0],[14,1.0],[15,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[0,1.0],[4,1.0],[8,1.0],[12,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[1,1.0],[5,1.0],[9,1.0],[13,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[2,1.0],[6,1.0],[10,1.0],[14,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[3,1.0],[7,1.0],[11,1.0],[15,1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[16,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[16,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[16,1.0],[0,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[17,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[17,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[17,1.0],[4,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[18,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[18,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[18,1.0],[1,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[19,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[19,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[19,1.0],[5,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[20,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[20,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[20,1.0],[2,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[21,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[21,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[21,1.0],[6,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[22,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[22,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[22,1.0],[3,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[23,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[23,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[23,1.0],[7,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[24,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[24,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[24,1.0],[0,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[25,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[25,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[25,1.0],[8,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[26,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[26,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[26,1.0],[1,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[27,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[27,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[27,1.0],[9,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[28,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[28,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[28,1.0],[2,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[29,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[29,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[29,1.0],[10,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[30,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[30,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[30,1.0],[3,-1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[31,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[31,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[31,1.0],[11,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[32,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[32,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[32,1.0],[0,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[33,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[33,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[33,1.0],[12,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[34,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[34,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[34,1.0],[1,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[35,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[35,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[35,1.0],[13,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[36,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[36,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[36,1.0],[2,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[37,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[37,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[37,1.0],[14,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[38,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[38,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[38,1.0],[3,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[39,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[39,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[39,1.0],[15,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[40,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[40,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[40,1.0],[4,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[41,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[41,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[41,1.0],[8,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[42,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[42,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[42,1.0],[5,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[43,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[43,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[43,1.0],[9,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[44,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[44,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[44,1.0],[6,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[45,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[45,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[45,1.0],[10,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[46,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[46,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[46,1.0],[7,-1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[47,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[47,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[47,1.0],[11,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[48,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[48,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[48,1.0],[4,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[49,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[49,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[49,1.0],[12,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[50,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[50,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[50,1.0],[5,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[51,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[51,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[51,1.0],[13,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[52,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[52,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[52,1.0],[6,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[53,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[53,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[53,1.0],[14,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[54,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[54,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[54,1.0],[7,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[55,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[55,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[55,1.0],[15,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[56,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[56,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[56,1.0],[8,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[57,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[57,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[57,1.0],[12,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[58,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[58,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[58,1.0],[9,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[59,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[59,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[59,1.0],[13,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[60,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[60,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[60,1.0],[10,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[61,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[61,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[61,1.0],[14,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[62,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[62,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[62,1.0],[11,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[63,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[63,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[63,1.0],[15,-1.0],[8,-1.0]]}],"num_vars":64,"objective":[[16,10.0],[17,10.0],[18,10.0],[19,10.0],[20,10.0],[21,10.0],[22,10.0],[23,10.0],[24,15.0],[25,15.0],[26,15.0],[27,15.0],[28,15.0],[29,15.0],[30,15.0],[31,15.0],[32,20.0],[33,20.0],[34,20.0],[35,20.0],[36,20.0],[37,20.0],[38,20.0],[39,20.0],[40,35.0],[41,35.0],[42,35.0],[43,35.0],[44,35.0],[45,35.0],[46,35.0],[47,35.0],[48,25.0],[49,25.0],[50,25.0],[51,25.0],[52,25.0],[53,25.0],[54,25.0],[55,25.0],[56,30.0],[57,30.0],[58,30.0],[59,30.0],[60,30.0],[61,30.0],[62,30.0],[63,30.0]],"sense":"Minimize"}},"solutions":[{"source_config":[1,1,0,0,1,1],"target_config":[1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0]}]}, - {"source":{"problem":"TravelingSalesman","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,2,3],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,2,null]],"node_holes":[],"nodes":[null,null,null]}}}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-14.0,14.0,14.0,14.0,1.0,1.0,14.0,2.0,2.0],[0.0,-14.0,14.0,1.0,14.0,1.0,2.0,14.0,2.0],[0.0,0.0,-14.0,1.0,1.0,14.0,2.0,2.0,14.0],[0.0,0.0,0.0,-14.0,14.0,14.0,14.0,3.0,3.0],[0.0,0.0,0.0,0.0,-14.0,14.0,3.0,14.0,3.0],[0.0,0.0,0.0,0.0,0.0,-14.0,3.0,3.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,-14.0,14.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-14.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-14.0]],"num_vars":9}},"solutions":[{"source_config":[1,1,1],"target_config":[0,0,1,1,0,0,0,1,0]}]} + {"source":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"f64"},"instance":{"couplings":[1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0,-1.0,1.0],"fields":[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-2.0,4.0,0.0,0.0,-4.0,4.0,0.0,0.0,0.0,0.0],[0.0,-2.0,-4.0,0.0,0.0,0.0,4.0,0.0,0.0,0.0],[0.0,0.0,2.0,-4.0,0.0,0.0,0.0,4.0,0.0,0.0],[0.0,0.0,0.0,2.0,-4.0,0.0,0.0,0.0,4.0,0.0],[0.0,0.0,0.0,0.0,6.0,0.0,0.0,0.0,0.0,-4.0],[0.0,0.0,0.0,0.0,0.0,-2.0,0.0,4.0,-4.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,-2.0,0.0,4.0,-4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-6.0,0.0,4.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-2.0,0.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0]],"num_vars":10}},"solutions":[{"source_config":[0,1,1,0,0,1,0,0,1,0],"target_config":[0,1,1,0,0,1,0,0,1,0]}]}, + {"source":{"problem":"SpinGlass","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"couplings":[1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1],"fields":[0,0,0,0,0,0,0,0,0,0],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"target":{"problem":"MaxCut","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,4,null],[0,5,null],[1,2,null],[1,6,null],[2,3,null],[2,7,null],[3,4,null],[3,8,null],[4,9,null],[5,7,null],[5,8,null],[6,8,null],[6,9,null],[7,9,null]],"node_holes":[],"nodes":[null,null,null,null,null,null,null,null,null,null]}}}},"solutions":[{"source_config":[0,1,1,0,0,1,0,0,1,0],"target_config":[0,1,1,0,0,1,0,0,1,0]}]}, + {"source":{"problem":"TravelingSalesman","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[10,15,20,35,25,30],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[0,3,null],[1,2,null],[1,3,null],[2,3,null]],"node_holes":[],"nodes":[null,null,null,null]}}}},"target":{"problem":"ILP","variant":{"variable":"bool"},"instance":{"constraints":[{"cmp":"Eq","rhs":1.0,"terms":[[0,1.0],[1,1.0],[2,1.0],[3,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[4,1.0],[5,1.0],[6,1.0],[7,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[8,1.0],[9,1.0],[10,1.0],[11,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[12,1.0],[13,1.0],[14,1.0],[15,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[0,1.0],[4,1.0],[8,1.0],[12,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[1,1.0],[5,1.0],[9,1.0],[13,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[2,1.0],[6,1.0],[10,1.0],[14,1.0]]},{"cmp":"Eq","rhs":1.0,"terms":[[3,1.0],[7,1.0],[11,1.0],[15,1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[16,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[16,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[16,1.0],[0,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[17,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[17,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[17,1.0],[4,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[18,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[18,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[18,1.0],[1,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[19,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[19,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[19,1.0],[5,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[20,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[20,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[20,1.0],[2,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[21,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[21,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[21,1.0],[6,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[22,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[22,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[22,1.0],[3,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[23,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[23,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[23,1.0],[7,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[24,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[24,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[24,1.0],[0,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[25,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[25,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[25,1.0],[8,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[26,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[26,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[26,1.0],[1,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[27,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[27,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[27,1.0],[9,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[28,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[28,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[28,1.0],[2,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[29,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[29,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[29,1.0],[10,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[30,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[30,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[30,1.0],[3,-1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[31,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[31,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[31,1.0],[11,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[32,1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[32,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[32,1.0],[0,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[33,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[33,1.0],[1,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[33,1.0],[12,-1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[34,1.0],[1,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[34,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[34,1.0],[1,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[35,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[35,1.0],[2,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[35,1.0],[13,-1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[36,1.0],[2,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[36,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[36,1.0],[2,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[37,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[37,1.0],[3,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[37,1.0],[14,-1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[38,1.0],[3,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[38,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[38,1.0],[3,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[39,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[39,1.0],[0,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[39,1.0],[15,-1.0],[0,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[40,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[40,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[40,1.0],[4,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[41,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[41,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[41,1.0],[8,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[42,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[42,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[42,1.0],[5,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[43,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[43,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[43,1.0],[9,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[44,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[44,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[44,1.0],[6,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[45,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[45,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[45,1.0],[10,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[46,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[46,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[46,1.0],[7,-1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[47,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[47,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[47,1.0],[11,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[48,1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[48,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[48,1.0],[4,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[49,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[49,1.0],[5,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[49,1.0],[12,-1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[50,1.0],[5,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[50,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[50,1.0],[5,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[51,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[51,1.0],[6,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[51,1.0],[13,-1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[52,1.0],[6,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[52,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[52,1.0],[6,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[53,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[53,1.0],[7,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[53,1.0],[14,-1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[54,1.0],[7,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[54,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[54,1.0],[7,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[55,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[55,1.0],[4,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[55,1.0],[15,-1.0],[4,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[56,1.0],[8,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[56,1.0],[13,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[56,1.0],[8,-1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[57,1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[57,1.0],[9,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[57,1.0],[12,-1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[58,1.0],[9,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[58,1.0],[14,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[58,1.0],[9,-1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[59,1.0],[13,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[59,1.0],[10,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[59,1.0],[13,-1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[60,1.0],[10,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[60,1.0],[15,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[60,1.0],[10,-1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[61,1.0],[14,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[61,1.0],[11,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[61,1.0],[14,-1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[62,1.0],[11,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[62,1.0],[12,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[62,1.0],[11,-1.0],[12,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[63,1.0],[15,-1.0]]},{"cmp":"Le","rhs":0.0,"terms":[[63,1.0],[8,-1.0]]},{"cmp":"Ge","rhs":-1.0,"terms":[[63,1.0],[15,-1.0],[8,-1.0]]}],"num_vars":64,"objective":[[16,10.0],[17,10.0],[18,10.0],[19,10.0],[20,10.0],[21,10.0],[22,10.0],[23,10.0],[24,15.0],[25,15.0],[26,15.0],[27,15.0],[28,15.0],[29,15.0],[30,15.0],[31,15.0],[32,20.0],[33,20.0],[34,20.0],[35,20.0],[36,20.0],[37,20.0],[38,20.0],[39,20.0],[40,35.0],[41,35.0],[42,35.0],[43,35.0],[44,35.0],[45,35.0],[46,35.0],[47,35.0],[48,25.0],[49,25.0],[50,25.0],[51,25.0],[52,25.0],[53,25.0],[54,25.0],[55,25.0],[56,30.0],[57,30.0],[58,30.0],[59,30.0],[60,30.0],[61,30.0],[62,30.0],[63,30.0]],"sense":"Minimize"}},"solutions":[{"source_config":[1,1,0,0,1,1],"target_config":[0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0]}]}, + {"source":{"problem":"TravelingSalesman","variant":{"graph":"SimpleGraph","weight":"i32"},"instance":{"edge_weights":[1,2,3],"graph":{"inner":{"edge_property":"undirected","edges":[[0,1,null],[0,2,null],[1,2,null]],"node_holes":[],"nodes":[null,null,null]}}}},"target":{"problem":"QUBO","variant":{"weight":"f64"},"instance":{"matrix":[[-14.0,14.0,14.0,14.0,1.0,1.0,14.0,2.0,2.0],[0.0,-14.0,14.0,1.0,14.0,1.0,2.0,14.0,2.0],[0.0,0.0,-14.0,1.0,1.0,14.0,2.0,2.0,14.0],[0.0,0.0,0.0,-14.0,14.0,14.0,14.0,3.0,3.0],[0.0,0.0,0.0,0.0,-14.0,14.0,3.0,14.0,3.0],[0.0,0.0,0.0,0.0,0.0,-14.0,3.0,3.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,-14.0,14.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,-14.0,14.0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-14.0]],"num_vars":9}},"solutions":[{"source_config":[1,1,1],"target_config":[0,0,1,0,1,0,1,0,0]}]} ] } diff --git a/src/models/graph/directed_two_commodity_integral_flow.rs b/src/models/graph/directed_two_commodity_integral_flow.rs index 5bc495fd..ea6f8962 100644 --- a/src/models/graph/directed_two_commodity_integral_flow.rs +++ b/src/models/graph/directed_two_commodity_integral_flow.rs @@ -15,7 +15,7 @@ inventory::submit! { ProblemSchemaEntry { name: "DirectedTwoCommodityIntegralFlow", display_name: "Directed Two-Commodity Integral Flow", - aliases: &[], + aliases: &["D2CIF"], dimensions: &[], module_path: module_path!(), description: "Two-commodity integral flow feasibility on a directed graph", @@ -203,35 +203,25 @@ impl DirectedTwoCommodityIntegralFlow { } // (2) Flow conservation for each commodity at non-terminal vertices - // Per the definition, conservation applies at every vertex EXCEPT - // the four terminals {s_1, s_2, t_1, t_2} for BOTH commodities. let n = self.graph.num_vertices(); - for commodity in 0..2usize { - let offset = commodity * m; - for v in 0..n { - if terminals.contains(&v) { - continue; - } - let mut flow_in: i64 = 0; - let mut flow_out: i64 = 0; - for (a, &(u, w)) in arcs.iter().enumerate() { - if w == v { - flow_in += config[offset + a] as i64; - } - if u == v { - flow_out += config[offset + a] as i64; - } - } - if flow_in != flow_out { + let mut balances = [vec![0_i128; n], vec![0_i128; n]]; + for (a, &(u, w)) in arcs.iter().enumerate() { + let flow_1 = config[a] as i128; + let flow_2 = config[m + a] as i128; + + balances[0][u] -= flow_1; + balances[0][w] += flow_1; + balances[1][u] -= flow_2; + balances[1][w] += flow_2; + } + + for (commodity, commodity_balances) in balances.iter().enumerate() { + for (v, &balance) in commodity_balances.iter().enumerate() { + if !terminals.contains(&v) && balance != 0 { return false; } } - } - // (3) Requirement constraints - // Net flow into sink for commodity i = (total flow into sink) - (total flow out of sink) - for commodity in 0..2usize { - let offset = commodity * m; let snk = if commodity == 0 { self.sink_1 } else { @@ -242,16 +232,8 @@ impl DirectedTwoCommodityIntegralFlow { } else { self.requirement_2 }; - let mut net_flow_in: i64 = 0; - for (a, &(u, w)) in arcs.iter().enumerate() { - if w == snk { - net_flow_in += config[offset + a] as i64; - } - if u == snk { - net_flow_in -= config[offset + a] as i64; - } - } - if (net_flow_in as u64) < req { + + if commodity_balances[snk] < i128::from(req) { return false; } } diff --git a/src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs b/src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs index 94d9d9b1..f8f91dc0 100644 --- a/src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs +++ b/src/unit_tests/models/graph/directed_two_commodity_integral_flow.rs @@ -85,6 +85,16 @@ fn test_directed_two_commodity_integral_flow_conservation_violation() { assert!(!problem.evaluate(&config)); } +#[test] +fn test_directed_two_commodity_integral_flow_negative_net_flow_at_sink_is_infeasible() { + let graph = DirectedGraph::new(3, vec![(1, 2)]); + let problem = DirectedTwoCommodityIntegralFlow::new(graph, vec![1], 0, 1, 2, 2, 1, 0); + + // Commodity 1 sends flow out of its sink with no incoming flow. + let config = vec![1, 0]; + assert!(!problem.evaluate(&config)); +} + #[test] fn test_directed_two_commodity_integral_flow_solver_yes() { let problem = yes_instance(); From 900b87a19302d00f84bfe405a272a2d02a64f0f6 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Mon, 16 Mar 2026 21:16:26 +0800 Subject: [PATCH 5/6] fix: improve D2CIF CLI guidance --- README.md | 9 +++- docs/src/cli.md | 12 +++++- problemreductions-cli/src/dispatch.rs | 8 +++- problemreductions-cli/tests/cli_tests.rs | 52 ++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 94d4cb1f..97416c1e 100644 --- a/README.md +++ b/README.md @@ -37,11 +37,18 @@ Or build from source: ```bash git clone https://github.com/CodingThrust/problem-reductions cd problem-reductions -make cli # builds target/release/pred +make cli # installs/updates ~/.cargo/bin/pred ``` See the [Getting Started](https://codingthrust.github.io/problem-reductions/getting-started.html) guide for usage examples, the reduction workflow, and [CLI usage](https://codingthrust.github.io/problem-reductions/cli.html). +Example: create and solve a directed two-commodity integral flow instance from the CLI: + +```bash +pred create D2CIF --arcs "0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5" --capacities 1,1,1,1,1,1,1,1 --source-1 0 --sink-1 4 --source-2 1 --sink-2 5 --requirement-1 1 --requirement-2 1 -o d2cif.json +pred solve d2cif.json --solver brute-force +``` + ## MCP Server (AI Integration) The `pred` CLI includes a built-in [MCP](https://modelcontextprotocol.io/) server for AI assistant integration (Claude Code, Cursor, Windsurf, OpenCode, etc.). diff --git a/docs/src/cli.md b/docs/src/cli.md index 8166cfd6..7bbd4a0d 100644 --- a/docs/src/cli.md +++ b/docs/src/cli.md @@ -15,7 +15,7 @@ Or build from source: ```bash git clone https://github.com/CodingThrust/problem-reductions cd problem-reductions -make cli # builds target/release/pred +make cli # installs/updates ~/.cargo/bin/pred ``` Verify the installation: @@ -48,6 +48,14 @@ pred create MIS --graph 0-1,1-2,2-3 --weights 3,1,2,1 -o weighted.json # Create a Steiner Tree instance pred create SteinerTree --graph 0-1,0-3,1-2,1-3,2-3,2-4,3-4 --edge-weights 2,5,2,1,5,6,1 --terminals 0,2,4 -o steiner.json +# Create a directed two-commodity flow instance via the short alias +pred create D2CIF --arcs "0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5" --capacities 1,1,1,1,1,1,1,1 --source-1 0 --sink-1 4 --source-2 1 --sink-2 5 --requirement-1 1 --requirement-2 1 -o d2cif.json +pred solve d2cif.json --solver brute-force + +# Evaluate a known satisfying configuration. +# Config layout: [f1(a0)..f1(a7), f2(a0)..f2(a7)] +pred evaluate d2cif.json --config 1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1 + # Or start from a canonical model example pred create --example MIS/SimpleGraph/i32 -o example.json @@ -418,7 +426,7 @@ Source evaluation: Valid(2) ``` > **Note:** The ILP solver requires a reduction path from the target problem to ILP. -> Some problems (e.g., QUBO, SpinGlass, MaxCut, CircuitSAT) do not have this path yet. +> Some problems (e.g., QUBO, SpinGlass, MaxCut, CircuitSAT, DirectedTwoCommodityIntegralFlow) do not have this path yet. > Use `--solver brute-force` for these, or reduce to a problem that supports ILP first. ## Shell Completions diff --git a/problemreductions-cli/src/dispatch.rs b/problemreductions-cli/src/dispatch.rs index 659bba48..938d8643 100644 --- a/problemreductions-cli/src/dispatch.rs +++ b/problemreductions-cli/src/dispatch.rs @@ -79,8 +79,12 @@ impl LoadedProblem { } } - let reduction_path = - best_path.ok_or_else(|| anyhow::anyhow!("No reduction path from {} to ILP", name))?; + let reduction_path = best_path.ok_or_else(|| { + anyhow::anyhow!( + "No reduction path from {} to ILP. Try `--solver brute-force`, or reduce to a problem that supports ILP.", + name + ) + })?; let chain = graph .reduce_along_path(&reduction_path, self.as_any()) diff --git a/problemreductions-cli/tests/cli_tests.rs b/problemreductions-cli/tests/cli_tests.rs index a6acbaf5..6cb0eec2 100644 --- a/problemreductions-cli/tests/cli_tests.rs +++ b/problemreductions-cli/tests/cli_tests.rs @@ -636,6 +636,58 @@ fn test_create_d2cif_alias() { std::fs::remove_file(&output_file).ok(); } +#[test] +fn test_solve_d2cif_default_solver_suggests_bruteforce() { + let output_file = std::env::temp_dir().join("pred_test_solve_d2cif.json"); + let create_output = pred() + .args([ + "-o", + output_file.to_str().unwrap(), + "create", + "D2CIF", + "--arcs", + "0>2,0>3,1>2,1>3,2>4,2>5,3>4,3>5", + "--capacities", + "1,1,1,1,1,1,1,1", + "--source-1", + "0", + "--sink-1", + "4", + "--source-2", + "1", + "--sink-2", + "5", + "--requirement-1", + "1", + "--requirement-2", + "1", + ]) + .output() + .unwrap(); + assert!( + create_output.status.success(), + "stderr: {}", + String::from_utf8_lossy(&create_output.stderr) + ); + + let solve_output = pred() + .args(["solve", output_file.to_str().unwrap()]) + .output() + .unwrap(); + assert!( + !solve_output.status.success(), + "stdout: {}", + String::from_utf8_lossy(&solve_output.stdout) + ); + let stderr = String::from_utf8_lossy(&solve_output.stderr); + assert!( + stderr.contains("--solver brute-force"), + "expected brute-force hint, got: {stderr}" + ); + + std::fs::remove_file(&output_file).ok(); +} + #[test] fn test_create_x3c_rejects_duplicate_subset_elements() { let output = pred() From 2dfd9a2976b7f974abcc4b97a6fb6a63598254f2 Mon Sep 17 00:00:00 2001 From: zazabap Date: Mon, 16 Mar 2026 14:36:44 +0000 Subject: [PATCH 6/6] fix: remove duplicate CLI fields from merge (capacities, source/sink, requirements) Both DirectedTwoCommodityIntegralFlow and UndirectedTwoCommodityIntegralFlow share the same CLI fields. The merge with main created duplicates. Co-Authored-By: Claude Opus 4.6 (1M context) --- problemreductions-cli/src/cli.rs | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/problemreductions-cli/src/cli.rs b/problemreductions-cli/src/cli.rs index 76aa1668..32d58428 100644 --- a/problemreductions-cli/src/cli.rs +++ b/problemreductions-cli/src/cli.rs @@ -443,27 +443,6 @@ pub struct CreateArgs { /// Alphabet size for SCS (optional; inferred from max symbol + 1 if omitted) #[arg(long)] pub alphabet_size: Option, - /// Arc capacities for DirectedTwoCommodityIntegralFlow (comma-separated, e.g., "1,1,1") - #[arg(long)] - pub capacities: Option, - /// Source vertex for commodity 1 - #[arg(long)] - pub source_1: Option, - /// Sink vertex for commodity 1 - #[arg(long)] - pub sink_1: Option, - /// Source vertex for commodity 2 - #[arg(long)] - pub source_2: Option, - /// Sink vertex for commodity 2 - #[arg(long)] - pub sink_2: Option, - /// Flow requirement for commodity 1 - #[arg(long)] - pub requirement_1: Option, - /// Flow requirement for commodity 2 - #[arg(long)] - pub requirement_2: Option, } #[derive(clap::Args)]