diff --git a/Makefile b/Makefile index 08cb517a..ba8af969 100644 --- a/Makefile +++ b/Makefile @@ -176,9 +176,9 @@ run-plan: @NL=$$'\n'; \ BRANCH=$$(git branch --show-current); \ if [ "$(AGENT_TYPE)" = "claude" ]; then \ - PROCESS="1. Read the plan file$${NL}2. Use /subagent-driven-development to execute tasks$${NL}3. Push: git push origin $$BRANCH$${NL}4. Post summary"; \ + PROCESS="1. Read the plan file$${NL}2. Use /subagent-driven-development to execute tasks$${NL}3. Push: git push origin $$BRANCH$${NL}4. Create a pull request"; \ else \ - PROCESS="1. Read the plan file$${NL}2. Execute the tasks step by step. For each task, implement and test before moving on.$${NL}3. Push: git push origin $$BRANCH$${NL}4. Post summary"; \ + PROCESS="1. Read the plan file$${NL}2. Execute the tasks step by step. For each task, implement and test before moving on.$${NL}3. Push: git push origin $$BRANCH$${NL}4. Create a pull request"; \ fi; \ PROMPT="Execute the plan in '$${PLAN_FILE}'."; \ if [ -n "$(INSTRUCTIONS)" ]; then \ diff --git a/docs/src/design.md b/docs/src/design.md index af92f855..024ef636 100644 --- a/docs/src/design.md +++ b/docs/src/design.md @@ -46,9 +46,7 @@ Every problem implements `Problem`. Optimization problems additionally implement ## Variant System -A single problem name like `MaximumIndependentSet` can have multiple **variants** — carrying weights on vertices, or defined on a restricted topology (e.g., king's subgraph). Some variants are more specific than others: the king's subgraph is a special case of the unit-disk graph, which is a special case of the simple graph. - -In **set** language, variants form **subsets**: independent sets on king's subgraphs are a subset of independent sets on unit-disk graphs. The reduction from a more specific variant to a less specific one is a **variant cast** — an identity mapping where vertex/element indices are preserved. Each such cast is explicitly declared as a `#[reduction]` registration using the `impl_variant_reduction!` macro. +A single problem name like `MaximumIndependentSet` can have multiple **variants** — carrying weights on vertices, or defined on a restricted topology (e.g., king's subgraph). Variants form a subtype hierarchy: independent sets on king's subgraphs are a subset of independent sets on unit-disk graphs. The reduction from a more specific variant to a less specific one is a **variant cast** — an identity mapping where indices are preserved.
@@ -61,7 +59,7 @@ In **set** language, variants form **subsets**: independent sets on king's subgr
-Arrows indicate the **subset** (subtype) direction. Variant types fall into three categories: +Variant types fall into three categories: - **Graph type** — `HyperGraph` (root), `SimpleGraph`, `PlanarGraph`, `BipartiteGraph`, `UnitDiskGraph`, `KingsSubgraph`, `TriangularSubgraph`. - **Weight type** — `One` (unweighted), `i32`, `f64`. @@ -78,6 +76,9 @@ Arrows indicate the **subset** (subtype) direction. Variant types fall into thre +
+Implementation details: VariantParam trait and macros + ### VariantParam trait Each variant parameter type implements `VariantParam`, which declares its category, value, and optional parent: @@ -123,7 +124,7 @@ impl_variant_param!(K3, "k", parent: KN, cast: |_| KN, k: Some(3)); ### Variant cast reductions with `impl_variant_reduction!` -When a more specific variant (e.g., `KingsSubgraph`) needs to be treated as a less specific one (e.g., `UnitDiskGraph`), an explicit variant cast reduction is declared using `impl_variant_reduction!`. This generates a `ReduceTo` impl with `#[reduction]` registration and identity overhead: +When a more specific variant needs to be treated as a less specific one, an explicit variant cast reduction is declared: ```rust impl_variant_reduction!( @@ -135,8 +136,6 @@ impl_variant_reduction!( ); ``` -The problem name appears once, followed by ` => `. This works with any number of type parameters. All variant casts use `ReductionAutoCast` for identity solution mapping (vertex/element indices are preserved) and `ReductionOverhead::identity()` for the overhead fields. - ### Composing `Problem::variant()` The `variant_params!` macro composes the `Problem::variant()` body from type parameter names: @@ -150,13 +149,13 @@ fn variant() -> Vec<(&'static str, &'static str)> { } ``` +
+ ## Reduction Rules A reduction requires two pieces: a **result struct** and a **`ReduceTo` impl**. -### Result struct - -Holds the target problem and the logic to map solutions back: +The result struct holds the target problem and the logic to map solutions back: ```rust #[derive(Debug, Clone)] @@ -175,7 +174,7 @@ impl ReductionResult for ReductionISToVC { } ``` -### `ReduceTo` impl with the `#[reduction]` macro +The `#[reduction]` macro on the `ReduceTo` impl registers the reduction in the compile-time graph: ```rust #[reduction( @@ -194,7 +193,8 @@ impl ReduceTo> } ``` -### What the macro generates +
+What the #[reduction] macro generates The `#[reduction]` attribute expands to the original `impl` block plus an `inventory::submit!` call: @@ -220,106 +220,69 @@ inventory::submit! { This `ReductionEntry` is collected at compile time by `inventory`, making the reduction discoverable by the `ReductionGraph` without any manual registration. The `reduce_fn` field provides a type-erased executor that enables runtime-discovered paths to chain reductions automatically. -## Reduction Graph - -The `ReductionGraph` is the central runtime data structure. It collects all registered reductions to enable path finding and overhead evaluation. - -### Construction +
-`ReductionGraph::new()` scans `inventory::iter::` and builds a variant-level `petgraph::DiGraph`: - -- **Nodes** are unique `(problem_name, variant)` pairs — e.g., `("MaximumIndependentSet", {graph: "KingsSubgraph", weight: "i32"})`. Different variants of the same problem are separate nodes. -- **Edges** come exclusively from `#[reduction]` registrations. This includes both cross-problem reductions (e.g., MIS → QUBO) and variant casts (e.g., MIS on KingsSubgraph → MIS on UnitDiskGraph). - -There are no auto-generated edges. Every edge in the graph corresponds to an explicit `ReduceTo` impl in the source code. - -### JSON export - -`ReductionGraph::to_json()` produces a `ReductionGraphJson` with all variant nodes and reduction edges: - -- [reduction_graph.json](reductions/reduction_graph.json) — all problem variants and reduction edges -- [problem_schemas.json](reductions/problem_schemas.json) — field definitions for each problem type - -## Path Finding - -Path finding operates on the variant-level graph. Since each node is a `(name, variant)` pair, the graph directly encodes which variant transitions are possible. - -### Name-level paths - -`find_paths_by_name(src, dst)` enumerates all simple paths between any variant of the source and any variant of the target, deduplicating consecutive same-name nodes to produce name-level paths. `find_shortest_path_by_name()` returns the one with fewest hops. - -### Dijkstra with cost functions +## Reduction Graph -For cost-aware routing, `find_cheapest_path()` uses **Dijkstra's algorithm** over the variant-level graph: +`ReductionGraph::new()` scans `inventory::iter::` and builds a variant-level directed graph: -```rust -pub fn find_cheapest_path( - &self, - source: &str, // problem name - source_variant: &BTreeMap, // exact variant - target: &str, - target_variant: &BTreeMap, - input_size: &ProblemSize, - cost_fn: &C, -) -> Option -``` +- **Nodes** are unique `(problem_name, variant)` pairs — e.g., `("MaximumIndependentSet", {graph: "KingsSubgraph", weight: "i32"})`. +- **Edges** come exclusively from `#[reduction]` registrations — both cross-problem reductions and variant casts. There are no auto-generated edges. -The variant maps specify the exact source and target nodes in the variant-level graph. Use `ReductionGraph::variant_to_map(&T::variant())` to convert a `Problem::variant()` slice into the required `BTreeMap`. Since variant casts are explicit edges with identity overhead, Dijkstra naturally traverses them when they appear on the cheapest path. +### Path finding -### Cost functions +All path-finding operates on **exact variant nodes**. Use `ReductionGraph::variant_to_map(&T::variant())` to convert a `Problem::variant()` into the required `BTreeMap`. -The `PathCostFn` trait computes edge cost from overhead and current problem size: +| Method | Algorithm | Use case | +|--------|-----------|----------| +| `find_cheapest_path(src, src_var, dst, dst_var, input_size, cost_fn)` | Dijkstra | Optimal path under a cost function | +| `find_all_paths(src, src_var, dst, dst_var)` | All simple paths | Enumerate every route | -```rust -pub trait PathCostFn { - fn edge_cost(&self, overhead: &ReductionOverhead, current_size: &ProblemSize) -> f64; -} -``` +Use `find_cheapest_path` with `MinimizeSteps` for fewest-hops search. -Built-in implementations: +The `PathCostFn` trait (used by `find_cheapest_path`) computes edge cost from overhead and current problem size: | Cost function | Strategy | |--------------|----------| -| `Minimize("field")` | Minimize a single output field | -| `MinimizeWeighted([(field, w)])` | Weighted sum of output fields | -| `MinimizeMax([fields])` | Minimize the maximum of fields | -| `MinimizeLexicographic([fields])` | Lexicographic: minimize first, break ties with rest | | `MinimizeSteps` | Minimize number of hops (unit edge cost) | +| `Minimize("field")` | Minimize a single output field | | `CustomCost(closure)` | User-defined cost function | -### Example: MIS on KingsSubgraph to MinimumVertexCover - -Finding a path from `MIS{KingsSubgraph, i32}` to `VC{SimpleGraph, i32}`: +**Example:** Finding a path from `MIS{KingsSubgraph, i32}` to `VC{SimpleGraph, i32}`: ``` MIS{KingsSubgraph,i32} -> MIS{UnitDiskGraph,i32} -> MIS{SimpleGraph,i32} -> VC{SimpleGraph,i32} variant cast variant cast reduction ``` -Each variant cast is an explicit edge registered via `impl_variant_reduction!`, so the path finder treats all edges uniformly. +### Executable paths -## Overhead Evaluation +Convert a `ReductionPath` into a typed `ExecutablePath` via `make_executable()`, then call `reduce()`: -Each reduction declares how the output problem size relates to the input size, expressed as polynomials. +```rust +let rpath = graph.find_cheapest_path("Factoring", &src_var, + "SpinGlass", &dst_var, &ProblemSize::new(vec![]), &MinimizeSteps).unwrap(); +let path = graph.make_executable::>(&rpath).unwrap(); -### ProblemSize +let reduction = path.reduce(&factoring_instance); +let target = reduction.target_problem(); +let solution = reduction.extract_solution(&target_solution); +``` -A `ProblemSize` holds named size components — the dimensions that characterize a problem instance: +Internally, `ExecutablePath` holds a type-erased executor per edge. `ChainedReduction` stores intermediate results and extracts solutions back through the chain in reverse. -```rust -let size = ProblemSize::new(vec![("num_vertices", 10), ("num_edges", 15)]); -assert_eq!(size.get("num_vertices"), Some(10)); -``` +For full type control, you can also chain `ReduceTo::reduce_to()` calls manually at each step. -### Polynomials +
+Overhead evaluation -Output size formulas use `Polynomial` (a sum of `Monomial` terms). The `poly!` macro provides a concise syntax: +Each reduction declares how the output problem size relates to the input, expressed as polynomials. The `poly!` macro provides concise syntax: ```rust poly!(num_vertices) // p(x) = num_vertices -poly!(num_vertices ^ 2) // p(x) = num_vertices^2 -poly!(3 * num_edges) // p(x) = 3 * num_edges -poly!(num_vertices * num_edges) // p(x) = num_vertices * num_edges +poly!(num_vertices ^ 2) // p(x) = num_vertices² +poly!(3 * num_edges) // p(x) = 3 × num_edges +poly!(num_vertices * num_edges) // p(x) = num_vertices × num_edges ``` A `ReductionOverhead` pairs output field names with their polynomials: @@ -331,60 +294,16 @@ ReductionOverhead::new(vec![ ]) ``` -### Evaluating overhead - -`ReductionOverhead::evaluate_output_size(input)` substitutes input values into the polynomials and returns a new `ProblemSize`: +`evaluate_output_size(input)` substitutes input values: ``` Input: ProblemSize { num_vertices: 10, num_edges: 15 } Output: ProblemSize { num_vars: 25, num_clauses: 45 } ``` -### Composing through a path - -For a multi-step reduction path, overhead composes: the output of step $N$ becomes the input of step $N+1$. Each edge carries its own `ReductionOverhead`, so the total output size is computed by chaining `evaluate_output_size` calls through the path. Variant cast edges use `ReductionOverhead::identity()`, passing through all fields unchanged. - -## Reduction Execution - -The library provides two approaches to executing reductions: **manual chaining** for full type control, and **executable paths** for automatic multi-step reduction. - -### Executable paths (automatic) - -First find a `ReductionPath` with exact variant matching, then convert it to an `ExecutablePath` via `make_executable()`. Call `reduce()` to execute the path: - -```rust -let graph = ReductionGraph::new(); -let src_var = ReductionGraph::variant_to_map(&KSatisfiability::::variant()); -let dst_var = ReductionGraph::variant_to_map( - &MaximumIndependentSet::::variant()); -let rpath = graph - .find_cheapest_path("KSatisfiability", &src_var, - "MaximumIndependentSet", &dst_var, - &ProblemSize::new(vec![]), &MinimizeSteps) - .unwrap(); -let path = graph - .make_executable::, MaximumIndependentSet>(&rpath) - .unwrap(); - -let reduction = path.reduce(&ksat_instance); -let target = reduction.target_problem(); // &MaximumIndependentSet -let solution = reduction.extract_solution(&target_solution); -``` +For multi-step paths, overhead composes: the output of step N becomes the input of step N+1. Variant cast edges use `ReductionOverhead::identity()`, passing through all fields unchanged. -Internally, `ExecutablePath` holds a `Vec Box>` — one type-erased executor per edge. `make_executable` looks up each edge's `reduce_fn` along the `ReductionPath` steps. Each `reduce_fn` is generated by the `#[reduction]` macro and downcasts the source, calls `ReduceTo::reduce_to()`, and boxes the result. `ChainedReduction` stores the intermediate results and extracts solutions back through the chain in reverse. - -### Manual chaining - -For full type control, call `ReduceTo::reduce_to()` at each step manually: - -```rust -let r0 = ReduceTo::>::reduce_to(&ksat); -let r1 = ReduceTo::::reduce_to(r0.target_problem()); -let r2 = ReduceTo::>::reduce_to(r1.target_problem()); -// ... solve r2.target_problem(), then extract in reverse -``` - -Both cross-problem reductions and variant casts are dispatched uniformly through `ReduceTo`. Variant cast reductions use `ReductionAutoCast`, which passes indices through unchanged (identity mapping). +
## Solvers @@ -397,18 +316,10 @@ pub trait Solver { } ``` -### BruteForce - -Enumerates every configuration in the space defined by `dims()`. Suitable for small instances (<20 variables). In addition to the `Solver` trait methods, provides: - -- `find_all_best(problem)` — returns all tied-optimal configurations. -- `find_all_satisfying(problem)` — returns all satisfying configurations. - -Primarily used for **testing and verification** of reductions via closed-loop tests. - -### ILPSolver - -Feature-gated behind `ilp`. Uses the HiGHS solver via the `good_lp` crate. Additionally provides `solve_reduced()` for problems that implement `ReduceTo` — it reduces, solves the ILP, and extracts the solution in one call. +| Solver | Description | +|--------|-------------| +| **BruteForce** | Enumerates all configurations. Also provides `find_all_best()` and `find_all_satisfying()`. Used for testing and verification. | +| **ILPSolver** | Feature-gated (`ilp`). Uses HiGHS via `good_lp`. Also provides `solve_reduced()` for problems that implement `ReduceTo`. | ## JSON Serialization @@ -421,17 +332,12 @@ let json = to_json(&problem)?; let restored: MaximumIndependentSet = from_json(&json)?; ``` -**Exported JSON files:** +Exported files: + - [reduction_graph.json](reductions/reduction_graph.json) — all problem variants and reduction edges - [problem_schemas.json](reductions/problem_schemas.json) — field definitions for each problem type -Regenerate exports: - -```bash -cargo run --example export_graph # docs/src/reductions/reduction_graph.json (default) -cargo run --example export_graph -- output.json # custom output path -cargo run --example export_schemas # docs/src/reductions/problem_schemas.json -``` +Regenerate with `cargo run --example export_graph` and `cargo run --example export_schemas`. ## Contributing diff --git a/docs/src/reductions/reduction_graph.json b/docs/src/reductions/reduction_graph.json index 6a47ddb8..01d93b98 100644 --- a/docs/src/reductions/reduction_graph.json +++ b/docs/src/reductions/reduction_graph.json @@ -757,6 +757,17 @@ ], "doc_path": "rules/spinglass_qubo/index.html" }, + { + "source": 21, + "target": 0, + "overhead": [ + { + "field": "num_variables", + "formula": "num_variables + num_clauses + 1" + } + ], + "doc_path": "rules/sat_circuitsat/index.html" + }, { "source": 21, "target": 3, diff --git a/examples/chained_reduction_factoring_to_spinglass.rs b/examples/chained_reduction_factoring_to_spinglass.rs new file mode 100644 index 00000000..fe6dfa3e --- /dev/null +++ b/examples/chained_reduction_factoring_to_spinglass.rs @@ -0,0 +1,51 @@ +// # Chained Reduction: Factoring -> SpinGlass +// +// Mirrors Julia's examples/Ising.jl — reduces a Factoring problem +// to SpinGlass via the reduction graph, then solves and extracts the factors. +// Uses ILPSolver for the solve step (Julia uses GenericTensorNetworks). + +// ANCHOR: imports +use problemreductions::prelude::*; +use problemreductions::rules::{MinimizeSteps, ReductionGraph}; +use problemreductions::solvers::ILPSolver; +use problemreductions::topology::SimpleGraph; +use problemreductions::types::ProblemSize; +// ANCHOR_END: imports + +pub fn run() { + // ANCHOR: example + let graph = ReductionGraph::new(); + + // Find reduction path: Factoring -> ... -> SpinGlass + let src_var = ReductionGraph::variant_to_map(&Factoring::variant()); + let dst_var = + ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let rpath = graph + .find_cheapest_path( + "Factoring", + &src_var, + "SpinGlass", + &dst_var, + &ProblemSize::new(vec![]), + &MinimizeSteps, + ) + .unwrap(); + println!("Reduction path: {:?}", rpath.type_names()); + + // Create: factor 6 = p × q with 2-bit factors (mirrors Julia's Factoring(2, 2, 6)) + let factoring = Factoring::new(2, 2, 6); + + // Solve Factoring via ILP + let solver = ILPSolver::new(); + let solution = solver.solve_reduced(&factoring).unwrap(); + + // Extract and display the factors + let (p, q) = factoring.read_factors(&solution); + println!("{} = {} × {}", factoring.target(), p, q); + assert_eq!(p * q, 6, "Factors should multiply to 6"); + // ANCHOR_END: example +} + +fn main() { + run() +} diff --git a/scripts/jl/generate_testdata.jl b/scripts/jl/generate_testdata.jl index d66e24e3..c15f02eb 100644 --- a/scripts/jl/generate_testdata.jl +++ b/scripts/jl/generate_testdata.jl @@ -2,7 +2,7 @@ # Generate JSON test fixtures from ProblemReductions.jl for Rust parity testing. # Run: cd scripts/jl && julia --project=. generate_testdata.jl -using ProblemReductions, Graphs, JSON +using ProblemReductions, Graphs, JSON, Random const OUTDIR = joinpath(@__DIR__, "..", "..", "tests", "data", "jl") mkpath(OUTDIR) @@ -274,6 +274,165 @@ function export_setcovering(sc, label) return make_instance(label, inst, sc) end +"""Evaluate BicliqueCover with flat binary config (matching Rust convention). + +Config layout: for each vertex v (0-based) and biclique b (0-based), +config[v*k + b + 1] == 1 means vertex v is in biclique b. +Returns (is_valid, size) where is_valid means all edges covered, +and size is the total number of 1s in the config. +""" +function biclique_cover_evaluate(left_size, right_size, edges_0based, k, config) + n = left_size + right_size + # Check all edges are covered + for (l, r) in edges_0based + covered = false + for b in 0:k-1 + l_in = config[l * k + b + 1] == 1 + r_in = config[r * k + b + 1] == 1 + if l_in && r_in + covered = true + break + end + end + if !covered + return (false, 0) + end + end + return (true, sum(config)) +end + +function export_biclique_cover(graph, left_part, k, label) + left_size = length(left_part) + right_size = nv(graph) - left_size + edges_0 = graph_to_edges(graph) + n = nv(graph) + num_vars = n * k + + inst = Dict( + "num_vertices" => n, + "edges" => edges_0, + "left_size" => left_size, + "right_size" => right_size, + "k" => k, + ) + + # Sample configs + configs = Set{Vector{Int}}() + push!(configs, zeros(Int, num_vars)) + push!(configs, ones(Int, num_vars)) + while length(configs) < min(10, 2^num_vars) + push!(configs, [rand(0:1) for _ in 1:num_vars]) + end + configs = collect(configs) + + # Evaluate configs + evals = [] + for cfg in configs + (valid, sz) = biclique_cover_evaluate(left_size, right_size, edges_0, k, cfg) + push!(evals, Dict("config" => cfg, "is_valid" => valid, "size" => valid ? sz : 0)) + end + + # Brute force: find all best (minimize size among valid covers) + best_size = typemax(Int) + best_configs = Vector{Int}[] + for bits in 0:(2^num_vars - 1) + cfg = [(bits >> i) & 1 for i in 0:num_vars-1] + (valid, sz) = biclique_cover_evaluate(left_size, right_size, edges_0, k, cfg) + if valid + if sz < best_size + best_size = sz + best_configs = [cfg] + elseif sz == best_size + push!(best_configs, cfg) + end + end + end + + return Dict( + "label" => label, + "instance" => inst, + "evaluations" => evals, + "best_solutions" => best_configs, + ) +end + +"""Evaluate BMF with flat binary config (matching Rust convention). + +Config layout: first m*k bits are B (row-major), next k*n bits are C (row-major). +Returns hamming distance between A and boolean_product(B, C). +All configs are valid. +""" +function bmf_evaluate(A, m, n, k, config) + # Extract B (m x k) + B = zeros(Bool, m, k) + for i in 1:m, j in 1:k + B[i,j] = config[(i-1)*k + j] == 1 + end + b_size = m * k + # Extract C (k x n) + C = zeros(Bool, k, n) + for i in 1:k, j in 1:n + C[i,j] = config[b_size + (i-1)*n + j] == 1 + end + # Boolean product + product = zeros(Bool, m, n) + for i in 1:m, j in 1:n + product[i,j] = any(kk -> B[i,kk] && C[kk,j], 1:k) + end + # Hamming distance + return sum(A .!= product) +end + +function export_bmf(A, k, label) + m, n = size(A) + num_vars = m * k + k * n + + inst = Dict( + "matrix" => [[Int(A[i,j]) for j in 1:n] for i in 1:m], + "m" => m, + "n" => n, + "k" => k, + ) + + # Sample configs + configs = Set{Vector{Int}}() + push!(configs, zeros(Int, num_vars)) + push!(configs, ones(Int, num_vars)) + while length(configs) < min(10, 2^num_vars) + push!(configs, [rand(0:1) for _ in 1:num_vars]) + end + configs = collect(configs) + + # Evaluate configs + evals = [] + for cfg in configs + dist = bmf_evaluate(A, m, n, k, cfg) + # All configs are valid for BMF; size = hamming distance + push!(evals, Dict("config" => cfg, "is_valid" => true, "size" => dist)) + end + + # Brute force: find all best (minimize hamming distance) + best_dist = typemax(Int) + best_configs = Vector{Int}[] + for bits in 0:(2^num_vars - 1) + cfg = [(bits >> i) & 1 for i in 0:num_vars-1] + dist = bmf_evaluate(A, m, n, k, cfg) + if dist < best_dist + best_dist = dist + best_configs = [cfg] + elseif dist == best_dist + push!(best_configs, cfg) + end + end + + return Dict( + "label" => label, + "instance" => inst, + "evaluations" => evals, + "best_solutions" => best_configs, + ) +end + # ── reduction exports ──────────────────────────────────────────────── function export_reduction(source, target_type, source_label) @@ -306,6 +465,7 @@ end # ── main ───────────────────────────────────────────────────────────── function main() + Random.seed!(42) # pin seed so re-runs produce identical fixtures println("Generating Julia parity test data...") # ── Build test instances (matching Julia test/rules/rules.jl) ── @@ -370,6 +530,16 @@ function main() # SetCovering docstring doc_sc = SetCovering([[1, 2, 3], [2, 4], [1, 4]], [1, 2, 3]) + # BicliqueCover: 6-vertex bipartite graph, 2 bicliques (from Julia test) + doc_bc_graph = SimpleGraph(6) + for (i,j) in [(1,5), (1,4), (2,5), (2,4), (3,6)] + add_edge!(doc_bc_graph, i, j) + end + doc_bc = BicliqueCover(doc_bc_graph, [1,2,3], 2) + + # BMF: 3x3 all-ones matrix, rank 2 (from Julia test) + doc_bmf = BinaryMatrixFactorization(trues(3, 3), 2) + # ── Individual rule test instances (from test/rules/*.jl) ── rule_graph4 = SimpleGraph(Graphs.SimpleEdge.([(1, 2), (1, 3), (3, 4), (2, 3)])) @@ -547,6 +717,16 @@ function main() export_setcovering(doc_sc, "doc_3subsets"), ])) + # BicliqueCover + write_fixture("biclique_cover.json", model_fixture("BicliqueCover", [ + export_biclique_cover(doc_bc_graph, [1,2,3], 2, "doc_6vertex"), + ])) + + # BMF + write_fixture("bmf.json", model_fixture("BMF", [ + export_bmf(trues(3, 3), 2, "doc_3x3_ones"), + ])) + # ── Export reduction fixtures ── println("Exporting reduction fixtures...") @@ -622,6 +802,62 @@ function main() write_fixture(filename, data) end + # ── Export reduction path fixtures (deterministic, skip if already exist) ── + println("Exporting reduction path fixtures...") + + g = reduction_graph() + + if !isfile(joinpath(OUTDIR, "path_maxcut_to_spinglass.json")) + # MaxCut → SpinGlass path + mc_source = MaxCut(smallgraph(:petersen)) + mc_paths = reduction_paths(g, MaxCut, SpinGlass) + mc_res = reduceto(mc_paths[1], mc_source) + mc_best_source = findbest(mc_source, BruteForce()) + mc_best_target = findbest(target_problem(mc_res), BruteForce()) + mc_extracted = sort(unique(extract_solution.(Ref(mc_res), mc_best_target))) + + write_fixture("path_maxcut_to_spinglass.json", Dict( + "path" => string.(typeof.(mc_paths[1].nodes)), + "best_source" => mc_best_source, + "best_target" => mc_best_target, + "extracted" => mc_extracted, + )) + + # MaxCut → QUBO path (uses same mc_source/mc_best_source) + mc_qubo_paths = reduction_paths(g, MaxCut, QUBO) + mc_qubo_res = reduceto(mc_qubo_paths[1], mc_source) + mc_qubo_best_target = findbest(target_problem(mc_qubo_res), BruteForce()) + mc_qubo_extracted = sort(unique(extract_solution.(Ref(mc_qubo_res), mc_qubo_best_target))) + + write_fixture("path_maxcut_to_qubo.json", Dict( + "path" => string.(typeof.(mc_qubo_paths[1].nodes)), + "best_source" => mc_best_source, + "extracted" => mc_qubo_extracted, + )) + else + println(" skipping path_maxcut_to_*.json (already exist)") + end + + if !isfile(joinpath(OUTDIR, "path_factoring_to_spinglass.json")) + # Factoring → SpinGlass path (slow BruteForce on SpinGlass target) + fact = Factoring(2, 1, 3) + fact_paths = reduction_paths(g, Factoring, SpinGlass) + fact_res = reduceto(fact_paths[1], fact) + fact_best_target = findbest(target_problem(fact_res), BruteForce()) + fact_extracted = sort(unique(filter( + sol -> solution_size(fact, sol) == SolutionSize(0, true), + extract_solution.(Ref(fact_res), fact_best_target) + ))) + + write_fixture("path_factoring_to_spinglass.json", Dict( + "path" => string.(typeof.(fact_paths[1].nodes)), + "best_source" => findbest(fact, BruteForce()), + "extracted" => fact_extracted, + )) + else + println(" skipping path_factoring_to_spinglass.json (already exists)") + end + println("Done! Generated fixtures in $OUTDIR") end diff --git a/src/rules/cost.rs b/src/rules/cost.rs index 66588877..0cbf1bf1 100644 --- a/src/rules/cost.rs +++ b/src/rules/cost.rs @@ -18,48 +18,6 @@ impl PathCostFn for Minimize { } } -/// Minimize weighted sum of output fields. -pub struct MinimizeWeighted(pub Vec<(&'static str, f64)>); - -impl PathCostFn for MinimizeWeighted { - fn edge_cost(&self, overhead: &ReductionOverhead, size: &ProblemSize) -> f64 { - let output = overhead.evaluate_output_size(size); - self.0 - .iter() - .map(|(field, weight)| weight * output.get(field).unwrap_or(0) as f64) - .sum() - } -} - -/// Minimize the maximum of specified fields. -pub struct MinimizeMax(pub Vec<&'static str>); - -impl PathCostFn for MinimizeMax { - fn edge_cost(&self, overhead: &ReductionOverhead, size: &ProblemSize) -> f64 { - let output = overhead.evaluate_output_size(size); - self.0 - .iter() - .map(|field| output.get(field).unwrap_or(0) as f64) - .fold(0.0, f64::max) - } -} - -/// Lexicographic: minimize first field, break ties with subsequent. -pub struct MinimizeLexicographic(pub Vec<&'static str>); - -impl PathCostFn for MinimizeLexicographic { - fn edge_cost(&self, overhead: &ReductionOverhead, size: &ProblemSize) -> f64 { - let output = overhead.evaluate_output_size(size); - let mut cost = 0.0; - let mut scale = 1.0; - for field in &self.0 { - cost += scale * output.get(field).unwrap_or(0) as f64; - scale *= 1e-10; - } - cost - } -} - /// Minimize number of reduction steps. pub struct MinimizeSteps; diff --git a/src/rules/graph.rs b/src/rules/graph.rs index a297da3e..fdd6fadd 100644 --- a/src/rules/graph.rs +++ b/src/rules/graph.rs @@ -381,71 +381,36 @@ impl ReductionGraph { ReductionPath { steps } } - /// Find all paths from source to target type. + /// Find all simple paths between two specific problem variants. /// - /// Uses `Problem::NAME` for lookup. With variant-level nodes, this finds - /// paths between any variant of S and any variant of T. - pub fn find_paths( + /// Uses `all_simple_paths` on the variant-level graph from the exact + /// source variant node to the exact target variant node. + pub fn find_all_paths( &self, + source: &str, + source_variant: &BTreeMap, + target: &str, + target_variant: &BTreeMap, ) -> Vec { - self.find_paths_by_name(S::NAME, T::NAME) - } - - /// Find all paths between problem types by name. - pub fn find_paths_by_name(&self, src: &str, dst: &str) -> Vec { - let src_nodes = match self.name_to_nodes.get(src) { - Some(nodes) => nodes.clone(), + let src = match self.lookup_node(source, source_variant) { + Some(idx) => idx, None => return vec![], }; - let dst_nodes = match self.name_to_nodes.get(dst) { - Some(nodes) => nodes.clone(), + let dst = match self.lookup_node(target, target_variant) { + Some(idx) => idx, None => return vec![], }; - let mut all_paths = Vec::new(); - - for &src_idx in &src_nodes { - for &dst_idx in &dst_nodes { - let paths: Vec> = all_simple_paths::< - Vec, - _, - std::hash::RandomState, - >( - &self.graph, src_idx, dst_idx, 0, None - ) - .collect(); - - for path in paths { - let steps: Vec = path - .iter() - .map(|&idx| { - let node = &self.nodes[self.graph[idx]]; - ReductionStep { - name: node.name.to_string(), - variant: node.variant.clone(), - } - }) - .collect(); - all_paths.push(ReductionPath { steps }); - } - } - } - - all_paths - } - - /// Find the shortest path from source to target type. - pub fn find_shortest_path( - &self, - ) -> Option { - let paths = self.find_paths::(); - paths.into_iter().min_by_key(|p| p.len()) - } + let paths: Vec> = + all_simple_paths::, _, std::hash::RandomState>( + &self.graph, src, dst, 0, None, + ) + .collect(); - /// Find the shortest path by name. - pub fn find_shortest_path_by_name(&self, src: &str, dst: &str) -> Option { - let paths = self.find_paths_by_name(src, dst); - paths.into_iter().min_by_key(|p| p.len()) + paths + .iter() + .map(|p| self.node_path_to_reduction_path(p)) + .collect() } /// Check if a direct reduction exists from S to T. @@ -825,3 +790,7 @@ impl ReductionGraph { #[cfg(test)] #[path = "../unit_tests/rules/graph.rs"] mod tests; + +#[cfg(test)] +#[path = "../unit_tests/rules/reduction_path_parity.rs"] +mod reduction_path_parity_tests; diff --git a/src/rules/mod.rs b/src/rules/mod.rs index e2ce2a7c..48113302 100644 --- a/src/rules/mod.rs +++ b/src/rules/mod.rs @@ -2,10 +2,7 @@ pub mod cost; pub mod registry; -pub use cost::{ - CustomCost, Minimize, MinimizeLexicographic, MinimizeMax, MinimizeSteps, MinimizeWeighted, - PathCostFn, -}; +pub use cost::{CustomCost, Minimize, MinimizeSteps, PathCostFn}; pub use registry::{ReductionEntry, ReductionOverhead}; mod circuit_spinglass; @@ -26,6 +23,7 @@ mod maximumsetpacking_qubo; mod minimumvertexcover_maximumindependentset; mod minimumvertexcover_minimumsetcovering; mod minimumvertexcover_qubo; +mod sat_circuitsat; mod sat_coloring; mod sat_ksat; mod sat_maximumindependentset; @@ -80,6 +78,7 @@ pub use maximumsetpacking_qubo::ReductionSPToQUBO; pub use minimumvertexcover_maximumindependentset::{ReductionISToVC, ReductionVCToIS}; pub use minimumvertexcover_minimumsetcovering::ReductionVCToSC; pub use minimumvertexcover_qubo::ReductionVCToQUBO; +pub use sat_circuitsat::ReductionSATToCircuit; pub use sat_coloring::ReductionSATToColoring; pub use sat_ksat::{ReductionKSATToSAT, ReductionSATToKSAT}; pub use sat_maximumindependentset::{BoolVar, ReductionSATToIS}; diff --git a/src/rules/sat_circuitsat.rs b/src/rules/sat_circuitsat.rs new file mode 100644 index 00000000..a7a39597 --- /dev/null +++ b/src/rules/sat_circuitsat.rs @@ -0,0 +1,125 @@ +//! Reduction from Satisfiability to CircuitSAT. +//! +//! Converts a CNF formula into a boolean circuit by creating +//! an OR gate for each clause and a final AND gate. + +use crate::models::satisfiability::Satisfiability; +use crate::models::specialized::{Assignment, BooleanExpr, Circuit, CircuitSAT}; +use crate::poly; +use crate::reduction; +use crate::rules::registry::ReductionOverhead; +use crate::rules::traits::{ReduceTo, ReductionResult}; +use crate::traits::Problem; + +/// Result of reducing SAT to CircuitSAT. +#[derive(Debug, Clone)] +pub struct ReductionSATToCircuit { + target: CircuitSAT, + /// Indices of original SAT variables in the CircuitSAT variable list. + source_var_indices: Vec, +} + +impl ReductionResult for ReductionSATToCircuit { + type Source = Satisfiability; + type Target = CircuitSAT; + + fn target_problem(&self) -> &CircuitSAT { + &self.target + } + + fn extract_solution(&self, target_solution: &[usize]) -> Vec { + self.source_var_indices + .iter() + .map(|&idx| target_solution[idx]) + .collect() + } +} + +#[reduction( + overhead = { + ReductionOverhead::new(vec![ + ("num_variables", poly!(num_variables) + poly!(num_clauses) + poly!(1)), + ]) + } +)] +impl ReduceTo for Satisfiability { + type Result = ReductionSATToCircuit; + + fn reduce_to(&self) -> Self::Result { + let num_vars = self.num_variables(); + let clauses = self.clauses(); + + let mut assignments = Vec::new(); + let mut clause_outputs = Vec::new(); + + for (i, clause) in clauses.iter().enumerate() { + let clause_output = format!("__clause_{}", i); + let literal_exprs: Vec = clause + .literals + .iter() + .map(|&lit| { + let var_name = format!("x{}", lit.unsigned_abs()); + let var_expr = BooleanExpr::var(&var_name); + if lit < 0 { + BooleanExpr::not(var_expr) + } else { + var_expr + } + }) + .collect(); + + let clause_expr = if literal_exprs.len() == 1 { + literal_exprs.into_iter().next().unwrap() + } else { + BooleanExpr::or(literal_exprs) + }; + + assignments.push(Assignment::new(vec![clause_output.clone()], clause_expr)); + clause_outputs.push(clause_output); + } + + // Final AND gate + let final_output = "__out".to_string(); + let and_expr = if clause_outputs.len() == 1 { + BooleanExpr::var(&clause_outputs[0]) + } else { + BooleanExpr::and( + clause_outputs + .iter() + .map(|name| BooleanExpr::var(name)) + .collect(), + ) + }; + assignments.push(Assignment::new(vec![final_output.clone()], and_expr)); + + // Constrain the final output to be true + assignments.push(Assignment::new( + vec![final_output], + BooleanExpr::constant(true), + )); + + let circuit = Circuit::new(assignments); + let target = CircuitSAT::new(circuit); + + // Map SAT variable indices to CircuitSAT variable indices + let var_names = target.variable_names(); + let source_var_indices: Vec = (1..=num_vars) + .map(|i| { + let name = format!("x{}", i); + var_names + .iter() + .position(|n| n == &name) + .unwrap_or_else(|| panic!("Variable {} not found in CircuitSAT", name)) + }) + .collect(); + + ReductionSATToCircuit { + target, + source_var_indices, + } + } +} + +#[cfg(test)] +#[path = "../unit_tests/rules/sat_circuitsat.rs"] +mod tests; diff --git a/src/unit_tests/models/specialized/biclique_cover.rs b/src/unit_tests/models/specialized/biclique_cover.rs index 034179bb..c9412e0c 100644 --- a/src/unit_tests/models/specialized/biclique_cover.rs +++ b/src/unit_tests/models/specialized/biclique_cover.rs @@ -3,6 +3,8 @@ use crate::solvers::BruteForce; use crate::traits::{OptimizationProblem, Problem}; use crate::types::{Direction, SolutionSize}; +include!("../../jl_helpers.rs"); + #[test] fn test_biclique_cover_creation() { let problem = BicliqueCover::new(2, 2, vec![(0, 2), (0, 3), (1, 2)], 2); @@ -171,3 +173,43 @@ fn test_biclique_problem() { SolutionSize::Valid(0) ); } + +#[test] +fn test_jl_parity_evaluation() { + let data: serde_json::Value = + serde_json::from_str(include_str!("../../../../tests/data/jl/biclique_cover.json")) + .unwrap(); + for instance in data["instances"].as_array().unwrap() { + let left_size = instance["instance"]["left_size"].as_u64().unwrap() as usize; + let right_size = instance["instance"]["right_size"].as_u64().unwrap() as usize; + let edges = jl_parse_edges(&instance["instance"]); + let k = instance["instance"]["k"].as_u64().unwrap() as usize; + let problem = BicliqueCover::new(left_size, right_size, edges, k); + for eval in instance["evaluations"].as_array().unwrap() { + let config = jl_parse_config(&eval["config"]); + let result = problem.evaluate(&config); + let jl_valid = eval["is_valid"].as_bool().unwrap(); + let jl_size = eval["size"].as_i64().unwrap() as i32; + if jl_valid { + assert_eq!( + result, + SolutionSize::Valid(jl_size), + "BicliqueCover: valid config mismatch" + ); + } else { + assert_eq!( + result, + SolutionSize::Invalid, + "BicliqueCover: invalid config should be Invalid" + ); + } + } + let best = BruteForce::new().find_all_best(&problem); + let jl_best = jl_parse_configs_set(&instance["best_solutions"]); + let rust_best: HashSet> = best.into_iter().collect(); + assert_eq!( + rust_best, jl_best, + "BicliqueCover best solutions mismatch" + ); + } +} diff --git a/src/unit_tests/models/specialized/bmf.rs b/src/unit_tests/models/specialized/bmf.rs index f147dc10..f7e4627e 100644 --- a/src/unit_tests/models/specialized/bmf.rs +++ b/src/unit_tests/models/specialized/bmf.rs @@ -3,6 +3,8 @@ use crate::solvers::BruteForce; use crate::traits::{OptimizationProblem, Problem}; use crate::types::{Direction, SolutionSize}; +include!("../../jl_helpers.rs"); + #[test] fn test_bmf_creation() { let matrix = vec![vec![true, false], vec![false, true]]; @@ -204,3 +206,40 @@ fn test_bmf_problem() { assert_eq!(Problem::evaluate(&problem, &[1, 1]), SolutionSize::Valid(0)); // Exact assert_eq!(Problem::evaluate(&problem, &[0, 0]), SolutionSize::Valid(1)); // Distance 1 } + +#[test] +fn test_jl_parity_evaluation() { + let data: serde_json::Value = + serde_json::from_str(include_str!("../../../../tests/data/jl/bmf.json")).unwrap(); + for instance in data["instances"].as_array().unwrap() { + let matrix_json = instance["instance"]["matrix"].as_array().unwrap(); + let matrix: Vec> = matrix_json + .iter() + .map(|row| { + row.as_array() + .unwrap() + .iter() + .map(|v| v.as_u64().unwrap() != 0) + .collect() + }) + .collect(); + let k = instance["instance"]["k"].as_u64().unwrap() as usize; + let problem = BMF::new(matrix, k); + for eval in instance["evaluations"].as_array().unwrap() { + let config = jl_parse_config(&eval["config"]); + let result = problem.evaluate(&config); + let jl_size = eval["size"].as_i64().unwrap() as i32; + // BMF always returns Valid(hamming_distance) + assert_eq!( + result, + SolutionSize::Valid(jl_size), + "BMF: size mismatch for config {:?}", + config + ); + } + let best = BruteForce::new().find_all_best(&problem); + let jl_best = jl_parse_configs_set(&instance["best_solutions"]); + let rust_best: HashSet> = best.into_iter().collect(); + assert_eq!(rust_best, jl_best, "BMF best solutions mismatch"); + } +} diff --git a/src/unit_tests/reduction_graph.rs b/src/unit_tests/reduction_graph.rs index b2c79049..5fdc7562 100644 --- a/src/unit_tests/reduction_graph.rs +++ b/src/unit_tests/reduction_graph.rs @@ -71,8 +71,10 @@ fn test_find_path_with_cost_function() { fn test_multi_step_path() { let graph = ReductionGraph::new(); - // Factoring -> CircuitSAT -> SpinGlass is a 2-step path - let path = graph.find_shortest_path_by_name("Factoring", "SpinGlass"); + // Factoring -> CircuitSAT -> SpinGlass is a 2-step path + let src = ReductionGraph::variant_to_map(&crate::models::specialized::Factoring::variant()); + let dst = ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let path = graph.find_cheapest_path("Factoring", &src, "SpinGlass", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!( path.is_some(), @@ -105,7 +107,9 @@ fn test_problem_size_propagation() { assert!(path.is_some()); - let path2 = graph.find_shortest_path_by_name("MaximumIndependentSet", "MaximumSetPacking"); + let src2 = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst2 = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); + let path2 = graph.find_cheapest_path("MaximumIndependentSet", &src2, "MaximumSetPacking", &dst2, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(path2.is_some()); } @@ -124,7 +128,7 @@ fn test_json_export() { assert!(categories.len() >= 3, "Should have multiple categories"); } -// ---- Path finding (typed API) ---- +// ---- Path finding (variant-level API) ---- #[test] fn test_direct_reduction_exists() { @@ -141,8 +145,10 @@ fn test_direct_reduction_exists() { #[test] fn test_find_direct_path() { let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); - let paths = graph.find_paths::, MinimumVertexCover>(); + let paths = graph.find_all_paths("MaximumIndependentSet", &src, "MinimumVertexCover", &dst); assert!(!paths.is_empty()); assert!( paths.iter().any(|p| p.len() == 1), @@ -154,13 +160,14 @@ fn test_find_direct_path() { #[test] fn test_find_indirect_path() { let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); // MaximumSetPacking -> MaximumIndependentSet -> MinimumVertexCover - let paths = graph.find_paths::, MinimumVertexCover>(); + let paths = graph.find_all_paths("MaximumSetPacking", &src, "MinimumVertexCover", &dst); assert!(!paths.is_empty()); - let shortest = - graph.find_shortest_path::, MinimumVertexCover>(); + let shortest = graph.find_cheapest_path("MaximumSetPacking", &src, "MinimumVertexCover", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(shortest.is_some()); assert_eq!(shortest.unwrap().len(), 2); } @@ -168,26 +175,24 @@ fn test_find_indirect_path() { #[test] fn test_no_path_exists() { let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&QUBO::::variant()); + let dst = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); - let paths = graph.find_paths::, MaximumSetPacking>(); + let paths = graph.find_all_paths("QUBO", &src, "MaximumSetPacking", &dst); assert!(paths.is_empty()); } #[test] fn test_bidirectional_paths() { let graph = ReductionGraph::new(); + let is_var = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let vc_var = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); + let sg_var = ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let qubo_var = ReductionGraph::variant_to_map(&QUBO::::variant()); + + assert!(!graph.find_all_paths("MaximumIndependentSet", &is_var, "MinimumVertexCover", &vc_var).is_empty()); + assert!(!graph.find_all_paths("MinimumVertexCover", &vc_var, "MaximumIndependentSet", &is_var).is_empty()); - assert!(!graph - .find_paths::, MinimumVertexCover>() - .is_empty()); - assert!(!graph - .find_paths::, MaximumIndependentSet>() - .is_empty()); - - assert!(!graph - .find_paths::, QUBO>() - .is_empty()); - assert!(!graph - .find_paths::, SpinGlass>() - .is_empty()); + assert!(!graph.find_all_paths("SpinGlass", &sg_var, "QUBO", &qubo_var).is_empty()); + assert!(!graph.find_all_paths("QUBO", &qubo_var, "SpinGlass", &sg_var).is_empty()); } diff --git a/src/unit_tests/rules/cost.rs b/src/unit_tests/rules/cost.rs index 571d5cb3..8f3fdb22 100644 --- a/src/unit_tests/rules/cost.rs +++ b/src/unit_tests/rules/cost.rs @@ -17,17 +17,6 @@ fn test_minimize_single() { assert_eq!(cost_fn.edge_cost(&overhead, &size), 20.0); // 2 * 10 } -#[test] -fn test_minimize_weighted() { - let cost_fn = MinimizeWeighted(vec![("n", 1.0), ("m", 2.0)]); - let size = ProblemSize::new(vec![("n", 10), ("m", 5)]); - let overhead = test_overhead(); - - // output n = 20, output m = 5 - // cost = 1.0 * 20 + 2.0 * 5 = 30 - assert_eq!(cost_fn.edge_cost(&overhead, &size), 30.0); -} - #[test] fn test_minimize_steps() { let cost_fn = MinimizeSteps; @@ -37,29 +26,6 @@ fn test_minimize_steps() { assert_eq!(cost_fn.edge_cost(&overhead, &size), 1.0); } -#[test] -fn test_minimize_max() { - let cost_fn = MinimizeMax(vec!["n", "m"]); - let size = ProblemSize::new(vec![("n", 10), ("m", 5)]); - let overhead = test_overhead(); - - // output n = 20, output m = 5 - // max(20, 5) = 20 - assert_eq!(cost_fn.edge_cost(&overhead, &size), 20.0); -} - -#[test] -fn test_minimize_lexicographic() { - let cost_fn = MinimizeLexicographic(vec!["n", "m"]); - let size = ProblemSize::new(vec![("n", 10), ("m", 5)]); - let overhead = test_overhead(); - - // output n = 20, output m = 5 - // cost = 20 * 1.0 + 5 * 1e-10 = 20.0000000005 - let cost = cost_fn.edge_cost(&overhead, &size); - assert!(cost > 20.0 && cost < 20.001); -} - #[test] fn test_custom_cost() { let cost_fn = CustomCost(|overhead: &ReductionOverhead, size: &ProblemSize| { @@ -83,11 +49,3 @@ fn test_minimize_missing_field() { assert_eq!(cost_fn.edge_cost(&overhead, &size), 0.0); } -#[test] -fn test_minimize_max_empty() { - let cost_fn = MinimizeMax(vec![]); - let size = ProblemSize::new(vec![("n", 10)]); - let overhead = test_overhead(); - - assert_eq!(cost_fn.edge_cost(&overhead, &size), 0.0); -} diff --git a/src/unit_tests/rules/graph.rs b/src/unit_tests/rules/graph.rs index 56d0a625..7420ad44 100644 --- a/src/unit_tests/rules/graph.rs +++ b/src/unit_tests/rules/graph.rs @@ -6,11 +6,15 @@ use crate::rules::cost::MinimizeSteps; use crate::rules::graph::{classify_problem_category, ReductionStep}; use crate::topology::SimpleGraph; use crate::traits::Problem; +use crate::types::ProblemSize; +use std::collections::BTreeMap; #[test] fn test_find_direct_path() { let graph = ReductionGraph::new(); - let paths = graph.find_paths::, MinimumVertexCover>(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); + let paths = graph.find_all_paths("MaximumIndependentSet", &src, "MinimumVertexCover", &dst); assert!(!paths.is_empty()); // At least one path should be a direct reduction (1 edge = 2 steps) let shortest = paths.iter().min_by_key(|p| p.len()).unwrap(); @@ -21,17 +25,18 @@ fn test_find_direct_path() { #[test] fn test_find_indirect_path() { let graph = ReductionGraph::new(); - // IS -> SP directly - let paths = - graph.find_paths::, MaximumSetPacking>(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); + let paths = graph.find_all_paths("MaximumIndependentSet", &src, "MaximumSetPacking", &dst); assert!(!paths.is_empty()); } #[test] fn test_find_shortest_path() { let graph = ReductionGraph::new(); - let path = graph - .find_shortest_path::, MaximumSetPacking>(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); + let path = graph.find_cheapest_path("MaximumIndependentSet", &src, "MaximumSetPacking", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(path.is_some()); let path = path.unwrap(); assert_eq!(path.len(), 1); // Direct path exists @@ -47,44 +52,45 @@ fn test_has_direct_reduction() { #[test] fn test_is_to_qubo_path() { let graph = ReductionGraph::new(); - // IS -> QUBO should now have a direct path - let path = - graph.find_shortest_path::, crate::models::optimization::QUBO>(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&QUBO::::variant()); + let path = graph.find_cheapest_path("MaximumIndependentSet", &src, "QUBO", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(path.is_some()); assert_eq!(path.unwrap().len(), 1); // Direct path } #[test] -fn test_type_erased_paths() { +fn test_variant_level_paths() { let graph = ReductionGraph::new(); - // With variant-level nodes, same-name different-variant are different nodes. - // But find_paths searches all variants of a given name, so both should find paths. - let paths_i32 = graph.find_paths::< - crate::models::graph::MaxCut, - crate::models::optimization::SpinGlass, - >(); - let paths_f64 = graph.find_paths::< - crate::models::graph::MaxCut, - crate::models::optimization::SpinGlass, - >(); + // Variant-level path: MaxCut -> SpinGlass + let src = ReductionGraph::variant_to_map(&crate::models::graph::MaxCut::::variant()); + let dst = ReductionGraph::variant_to_map(&crate::models::optimization::SpinGlass::::variant()); + let paths = graph.find_all_paths("MaxCut", &src, "SpinGlass", &dst); + assert!(!paths.is_empty()); + assert_eq!(paths[0].type_names(), vec!["MaxCut", "SpinGlass"]); - // Both should find paths - assert!(!paths_i32.is_empty()); - assert!(!paths_f64.is_empty()); - // Name-level paths should be the same (MaxCut -> SpinGlass) - assert_eq!(paths_i32[0].type_names(), paths_f64[0].type_names()); + // Unregistered variant pair returns no paths + let src_f64 = ReductionGraph::variant_to_map(&crate::models::graph::MaxCut::::variant()); + let dst_f64 = ReductionGraph::variant_to_map(&crate::models::optimization::SpinGlass::::variant()); + let paths_f64 = graph.find_all_paths("MaxCut", &src_f64, "SpinGlass", &dst_f64); + // No direct MaxCut -> SpinGlass reduction registered + assert!(paths_f64.is_empty()); } #[test] -fn test_find_paths_by_name() { +fn test_find_shortest_path_variants() { let graph = ReductionGraph::new(); - let shortest = graph.find_shortest_path_by_name("MaxCut", "SpinGlass"); + let src = ReductionGraph::variant_to_map(&crate::models::graph::MaxCut::::variant()); + let dst = ReductionGraph::variant_to_map(&crate::models::optimization::SpinGlass::::variant()); + let shortest = graph.find_cheapest_path("MaxCut", &src, "SpinGlass", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(shortest.is_some()); assert_eq!(shortest.unwrap().len(), 1); // Direct path - let shortest = graph.find_shortest_path_by_name("Factoring", "SpinGlass"); + let src = ReductionGraph::variant_to_map(&crate::models::specialized::Factoring::variant()); + let dst = ReductionGraph::variant_to_map(&crate::models::optimization::SpinGlass::::variant()); + let shortest = graph.find_cheapest_path("Factoring", &src, "SpinGlass", &dst, &ProblemSize::new(vec![]), &MinimizeSteps); assert!(shortest.is_some()); assert_eq!(shortest.unwrap().len(), 2); // Factoring -> CircuitSAT -> SpinGlass } @@ -110,8 +116,10 @@ fn test_graph_statistics() { #[test] fn test_reduction_path_methods() { let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); let path = graph - .find_shortest_path::, MinimumVertexCover>() + .find_cheapest_path("MaximumIndependentSet", &src, "MinimumVertexCover", &dst, &ProblemSize::new(vec![]), &MinimizeSteps) .unwrap(); assert!(!path.is_empty()); @@ -122,13 +130,15 @@ fn test_reduction_path_methods() { #[test] fn test_bidirectional_paths() { let graph = ReductionGraph::new(); + let is_var = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let vc_var = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); // Forward path - let forward = graph.find_paths::, MinimumVertexCover>(); + let forward = graph.find_all_paths("MaximumIndependentSet", &is_var, "MinimumVertexCover", &vc_var); assert!(!forward.is_empty()); // Backward path - let backward = graph.find_paths::, MaximumIndependentSet>(); + let backward = graph.find_all_paths("MinimumVertexCover", &vc_var, "MaximumIndependentSet", &is_var); assert!(!backward.is_empty()); } @@ -263,12 +273,12 @@ fn test_circuit_reductions() { // CircuitSAT -> SpinGlass assert!(graph.has_direct_reduction::>()); - // Find path from Factoring to SpinGlass - let paths = graph.find_paths::>(); + // Find path from Factoring to SpinGlass + let src = ReductionGraph::variant_to_map(&Factoring::variant()); + let dst = ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let paths = graph.find_all_paths("Factoring", &src, "SpinGlass", &dst); assert!(!paths.is_empty()); - let shortest = graph - .find_shortest_path::>() - .unwrap(); + let shortest = graph.find_cheapest_path("Factoring", &src, "SpinGlass", &dst, &ProblemSize::new(vec![]), &MinimizeSteps).unwrap(); assert_eq!(shortest.len(), 2); // Factoring -> CircuitSAT -> SpinGlass } @@ -377,6 +387,8 @@ fn test_to_json_file() { #[test] fn test_unknown_name_returns_empty() { let graph = ReductionGraph::new(); + let unknown = BTreeMap::new(); + let is_var = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); // Unknown source assert!(!graph.has_direct_reduction_by_name("UnknownProblem", "MaximumIndependentSet")); @@ -385,17 +397,17 @@ fn test_unknown_name_returns_empty() { // Both unknown assert!(!graph.has_direct_reduction_by_name("UnknownA", "UnknownB")); - // find_paths with unknown name + // find_all_paths with unknown name assert!(graph - .find_paths_by_name("UnknownProblem", "MaximumIndependentSet") + .find_all_paths("UnknownProblem", &unknown, "MaximumIndependentSet", &is_var) .is_empty()); assert!(graph - .find_paths_by_name("MaximumIndependentSet", "UnknownProblem") + .find_all_paths("MaximumIndependentSet", &is_var, "UnknownProblem", &unknown) .is_empty()); // find_shortest_path with unknown name assert!(graph - .find_shortest_path_by_name("UnknownProblem", "MaximumIndependentSet") + .find_cheapest_path("UnknownProblem", &unknown, "MaximumIndependentSet", &is_var, &ProblemSize::new(vec![]), &MinimizeSteps) .is_none()); } @@ -702,11 +714,10 @@ fn test_classify_problem_category() { #[test] fn test_make_executable_direct() { let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); let rpath = graph - .find_shortest_path::< - MaximumIndependentSet, - MinimumVertexCover, - >() + .find_cheapest_path("MaximumIndependentSet", &src, "MinimumVertexCover", &dst, &ProblemSize::new(vec![]), &MinimizeSteps) .unwrap(); let path = graph.make_executable::< MaximumIndependentSet, @@ -721,11 +732,10 @@ fn test_chained_reduction_direct() { use crate::traits::Problem; let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); let rpath = graph - .find_shortest_path::< - MaximumIndependentSet, - MinimumVertexCover, - >() + .find_cheapest_path("MaximumIndependentSet", &src, "MinimumVertexCover", &dst, &ProblemSize::new(vec![]), &MinimizeSteps) .unwrap(); let path = graph .make_executable::< @@ -751,11 +761,10 @@ fn test_chained_reduction_multi_step() { use crate::traits::Problem; let graph = ReductionGraph::new(); + let src = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); + let dst = ReductionGraph::variant_to_map(&MaximumSetPacking::::variant()); let rpath = graph - .find_shortest_path::< - MaximumIndependentSet, - MaximumSetPacking, - >() + .find_cheapest_path("MaximumIndependentSet", &src, "MaximumSetPacking", &dst, &ProblemSize::new(vec![]), &MinimizeSteps) .unwrap(); let path = graph .make_executable::< @@ -787,7 +796,7 @@ fn test_chained_reduction_with_variant_casts() { let graph = ReductionGraph::new(); // MIS -> MIS (variant cast) -> MVC - // Use find_cheapest_path for exact variant matching (not name-based find_shortest_path) + // Use find_cheapest_path for exact variant matching (not name-based) let src_var = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); let dst_var = ReductionGraph::variant_to_map(&MinimumVertexCover::::variant()); let rpath = graph.find_cheapest_path( @@ -827,7 +836,7 @@ fn test_chained_reduction_with_variant_casts() { assert!(metric.is_valid()); // Also test the KSat -> Sat -> MIS multi-step path - // Use find_cheapest_path for exact variant matching (find_shortest_path is name-based + // Use find_cheapest_path for exact variant matching (not name-based // and may pick a path through a different KSat variant) let ksat_src = ReductionGraph::variant_to_map(&KSatisfiability::::variant()); let ksat_dst = ReductionGraph::variant_to_map(&MaximumIndependentSet::::variant()); diff --git a/src/unit_tests/rules/reduction_path_parity.rs b/src/unit_tests/rules/reduction_path_parity.rs new file mode 100644 index 00000000..90989d53 --- /dev/null +++ b/src/unit_tests/rules/reduction_path_parity.rs @@ -0,0 +1,173 @@ +//! Reduction path parity tests — mirrors Julia's test/reduction_path.jl. +//! Verifies that chained reductions via `find_cheapest_path` + `make_executable` +//! produce correct solutions matching direct source solves. + +use crate::models::graph::MaxCut; +use crate::models::optimization::{SpinGlass, QUBO}; +use crate::models::specialized::Factoring; +use crate::rules::{MinimizeSteps, ReductionGraph}; +use crate::solvers::{BruteForce, Solver}; +use crate::topology::SimpleGraph; +use crate::traits::Problem; +use crate::types::ProblemSize; +use std::collections::HashSet; + +/// Julia: paths = reduction_paths(MaxCut, SpinGlass) +/// Julia: res = reduceto(paths[1], MaxCut(smallgraph(:petersen))) +#[test] +fn test_jl_parity_maxcut_to_spinglass_path() { + let graph = ReductionGraph::new(); + let src_var = ReductionGraph::variant_to_map(&MaxCut::::variant()); + let dst_var = ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let rpath = graph + .find_cheapest_path( + "MaxCut", + &src_var, + "SpinGlass", + &dst_var, + &ProblemSize::new(vec![]), + &MinimizeSteps, + ) + .expect("Should find path MaxCut -> SpinGlass"); + let path = graph + .make_executable::, SpinGlass>(&rpath) + .expect("Should make executable path"); + + // Petersen graph: 10 vertices, 15 edges + let petersen_edges = vec![ + (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), + ]; + let source = + MaxCut::::unweighted(SimpleGraph::new(10, petersen_edges)); + let reduction = path.reduce(&source); + let target = reduction.target_problem(); + + // Verify target is SpinGlass + assert_eq!(SpinGlass::::NAME, "SpinGlass"); + + let solver = BruteForce::new(); + let target_solution = solver.find_best(target).unwrap(); + let source_solution = reduction.extract_solution(&target_solution); + + // Source solution should be valid + let metric = source.evaluate(&source_solution); + assert!(metric.is_valid()); +} + +/// Julia: paths = reduction_paths(MaxCut, QUBO) +/// Julia: sort(extract_solution.(Ref(res), best2)) == sort(best1) +#[test] +fn test_jl_parity_maxcut_to_qubo_path() { + let graph = ReductionGraph::new(); + let src_var = ReductionGraph::variant_to_map(&MaxCut::::variant()); + let dst_var = ReductionGraph::variant_to_map(&QUBO::::variant()); + let rpath = graph + .find_cheapest_path( + "MaxCut", + &src_var, + "QUBO", + &dst_var, + &ProblemSize::new(vec![]), + &MinimizeSteps, + ) + .expect("Should find path MaxCut -> QUBO"); + let path = graph + .make_executable::, QUBO>(&rpath) + .expect("Should make executable path"); + + // Use a small graph for brute-force feasibility + let petersen_edges = vec![ + (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), + ]; + let source = + MaxCut::::unweighted(SimpleGraph::new(10, petersen_edges)); + let reduction = path.reduce(&source); + + let solver = BruteForce::new(); + let best_source: HashSet> = solver.find_all_best(&source).into_iter().collect(); + let best_target = solver.find_all_best(reduction.target_problem()); + + // Julia: sort(extract_solution.(Ref(res), best2)) == sort(best1) + let extracted: HashSet> = best_target + .iter() + .map(|t| reduction.extract_solution(t)) + .collect(); + assert_eq!( + extracted, best_source, + "MaxCut->QUBO path: extracted solutions should match direct source solutions" + ); +} + +/// Julia: factoring = Factoring(2, 1, 3) +/// Julia: paths = reduction_paths(Factoring, SpinGlass) +/// Julia: all(solution_size.(Ref(factoring), extract_solution.(Ref(res), sol)) .== Ref(SolutionSize(0, true))) +#[test] +fn test_jl_parity_factoring_to_spinglass_path() { + let graph = ReductionGraph::new(); + let src_var = ReductionGraph::variant_to_map(&Factoring::variant()); + let dst_var = ReductionGraph::variant_to_map(&SpinGlass::::variant()); + let rpath = graph + .find_cheapest_path( + "Factoring", + &src_var, + "SpinGlass", + &dst_var, + &ProblemSize::new(vec![]), + &MinimizeSteps, + ) + .expect("Should find path Factoring -> SpinGlass"); + let path = graph + .make_executable::>(&rpath) + .expect("Should make executable path"); + + // Julia: Factoring(2, 1, 3) — factor 3 with 2-bit x 1-bit + let factoring = Factoring::new(2, 1, 3); + let reduction = path.reduce(&factoring); + let target = reduction.target_problem(); + + let solver = BruteForce::new(); + let best_target = solver.find_all_best(target); + + // Every extracted solution should satisfy factoring (distance = 0) + for sol in &best_target { + let source_sol = reduction.extract_solution(sol); + let metric = factoring.evaluate(&source_sol); + assert_eq!( + metric.unwrap(), + 0, + "Factoring->SpinGlass path: extracted solution should have distance 0" + ); + } + assert!( + !best_target.is_empty(), + "Should find at least one SpinGlass solution" + ); +} diff --git a/src/unit_tests/rules/sat_circuitsat.rs b/src/unit_tests/rules/sat_circuitsat.rs new file mode 100644 index 00000000..11c28432 --- /dev/null +++ b/src/unit_tests/rules/sat_circuitsat.rs @@ -0,0 +1,97 @@ +use super::*; +use crate::models::satisfiability::{CNFClause, Satisfiability}; +use crate::models::specialized::CircuitSAT; +use crate::rules::ReduceTo; +use crate::solvers::BruteForce; +use crate::traits::Problem; +use std::collections::HashSet; + +#[test] +fn test_sat_to_circuitsat_closed_loop() { + // 3-variable SAT: (x1 v !x2 v x3) & (!x1 v x2 v !x3) + let sat = Satisfiability::new( + 3, + vec![ + CNFClause::new(vec![1, -2, 3]), + CNFClause::new(vec![-1, 2, -3]), + ], + ); + let result = ReduceTo::::reduce_to(&sat); + let solver = BruteForce::new(); + + // All satisfying assignments of the circuit should map back to SAT solutions + let best_target = solver.find_all_satisfying(result.target_problem()); + assert!(!best_target.is_empty(), "CircuitSAT should have solutions"); + + let extracted: HashSet> = best_target + .iter() + .map(|t| result.extract_solution(t)) + .collect(); + let sat_solutions: HashSet> = + solver.find_all_satisfying(&sat).into_iter().collect(); + + // Every extracted solution must satisfy the original SAT + for sol in &extracted { + assert!(sat.evaluate(sol), "Extracted solution must satisfy SAT"); + } + // The extracted set should equal all SAT solutions + assert_eq!(extracted, sat_solutions); +} + +#[test] +fn test_sat_to_circuitsat_unsatisfiable() { + // Unsatisfiable: (x1) & (!x1) + let sat = Satisfiability::new( + 1, + vec![CNFClause::new(vec![1]), CNFClause::new(vec![-1])], + ); + let result = ReduceTo::::reduce_to(&sat); + let solver = BruteForce::new(); + let best_target = solver.find_all_satisfying(result.target_problem()); + assert!( + best_target.is_empty(), + "Unsatisfiable SAT -> CircuitSAT should have no solutions" + ); +} + +#[test] +fn test_sat_to_circuitsat_single_clause() { + // Single clause: (x1 v x2) + let sat = Satisfiability::new(2, vec![CNFClause::new(vec![1, 2])]); + let result = ReduceTo::::reduce_to(&sat); + let solver = BruteForce::new(); + + let best_target = solver.find_all_satisfying(result.target_problem()); + let extracted: HashSet> = best_target + .iter() + .map(|t| result.extract_solution(t)) + .collect(); + let sat_solutions: HashSet> = + solver.find_all_satisfying(&sat).into_iter().collect(); + + assert_eq!(extracted, sat_solutions); +} + +#[test] +fn test_sat_to_circuitsat_single_literal_clause() { + // Single literal clause: (x1) & (x2) + let sat = Satisfiability::new( + 2, + vec![CNFClause::new(vec![1]), CNFClause::new(vec![2])], + ); + let result = ReduceTo::::reduce_to(&sat); + let solver = BruteForce::new(); + + let best_target = solver.find_all_satisfying(result.target_problem()); + let extracted: HashSet> = best_target + .iter() + .map(|t| result.extract_solution(t)) + .collect(); + let sat_solutions: HashSet> = + solver.find_all_satisfying(&sat).into_iter().collect(); + + // Only solution should be x1=1, x2=1 + assert_eq!(extracted, sat_solutions); + assert_eq!(sat_solutions.len(), 1); + assert!(sat_solutions.contains(&vec![1, 1])); +} diff --git a/tests/data/jl/biclique_cover.json b/tests/data/jl/biclique_cover.json new file mode 100644 index 00000000..06054b5c --- /dev/null +++ b/tests/data/jl/biclique_cover.json @@ -0,0 +1 @@ +{"instances":[{"label":"doc_6vertex","instance":{"left_size":3,"k":2,"num_vertices":6,"right_size":3,"edges":[[0,3],[0,4],[1,3],[1,4],[2,5]]},"evaluations":[{"is_valid":false,"config":[1,0,0,0,1,1,1,1,0,1,1,0],"size":0},{"is_valid":false,"config":[0,1,1,0,0,1,0,1,0,1,1,0],"size":0},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1,1,1],"size":12},{"is_valid":false,"config":[1,1,1,1,0,1,0,0,0,1,1,1],"size":0},{"is_valid":false,"config":[0,0,0,0,0,0,1,0,1,1,0,0],"size":0},{"is_valid":false,"config":[0,0,0,1,1,1,1,0,1,1,0,1],"size":0},{"is_valid":false,"config":[1,1,0,1,0,0,1,0,0,1,1,0],"size":0},{"is_valid":false,"config":[0,1,1,0,1,1,1,0,1,0,1,1],"size":0},{"is_valid":false,"config":[0,0,0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[0,0,1,0,0,1,0,1,0,0,0,0],"size":0}],"best_solutions":[[1,0,1,0,1,0,1,0,1,0,1,0],[0,1,0,1,1,0,0,1,0,1,1,0],[1,0,1,0,0,1,1,0,1,0,0,1],[0,1,0,1,0,1,0,1,0,1,0,1]]}],"problem_type":"BicliqueCover"} \ No newline at end of file diff --git a/tests/data/jl/bmf.json b/tests/data/jl/bmf.json new file mode 100644 index 00000000..e92047bd --- /dev/null +++ b/tests/data/jl/bmf.json @@ -0,0 +1 @@ +{"instances":[{"label":"doc_3x3_ones","instance":{"m":3,"k":2,"matrix":[[1,1,1],[1,1,1],[1,1,1]],"n":3},"evaluations":[{"is_valid":true,"config":[1,1,0,1,0,0,1,0,1,1,1,0],"size":4},{"is_valid":true,"config":[0,1,1,0,1,0,1,1,0,1,1,1],"size":2},{"is_valid":true,"config":[1,0,0,0,0,1,0,1,0,0,1,1],"size":6},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1,1,1],"size":0},{"is_valid":true,"config":[1,0,1,0,0,0,0,1,0,0,0,1],"size":7},{"is_valid":true,"config":[0,1,0,0,0,1,0,1,0,1,0,0],"size":7},{"is_valid":true,"config":[1,1,0,0,0,1,0,1,0,0,0,1],"size":6},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0,0,0],"size":9},{"is_valid":true,"config":[0,1,1,1,0,0,0,0,0,1,0,0],"size":7},{"is_valid":true,"config":[1,0,1,0,0,1,1,0,0,0,0,0],"size":7}],"best_solutions":[[1,0,1,0,1,0,1,1,1,0,0,0],[1,1,1,0,1,0,1,1,1,0,0,0],[1,0,1,1,1,0,1,1,1,0,0,0],[1,1,1,1,1,0,1,1,1,0,0,0],[1,0,1,0,1,1,1,1,1,0,0,0],[1,1,1,0,1,1,1,1,1,0,0,0],[1,0,1,1,1,1,1,1,1,0,0,0],[1,1,1,1,1,1,1,1,1,0,0,0],[1,1,1,1,1,1,0,1,1,1,0,0],[1,0,1,0,1,0,1,1,1,1,0,0],[1,1,1,0,1,0,1,1,1,1,0,0],[1,0,1,1,1,0,1,1,1,1,0,0],[1,1,1,1,1,0,1,1,1,1,0,0],[1,0,1,0,1,1,1,1,1,1,0,0],[1,1,1,0,1,1,1,1,1,1,0,0],[1,0,1,1,1,1,1,1,1,1,0,0],[1,1,1,1,1,1,1,1,1,1,0,0],[1,1,1,1,1,1,1,0,1,0,1,0],[1,0,1,0,1,0,1,1,1,0,1,0],[1,1,1,0,1,0,1,1,1,0,1,0],[1,0,1,1,1,0,1,1,1,0,1,0],[1,1,1,1,1,0,1,1,1,0,1,0],[1,0,1,0,1,1,1,1,1,0,1,0],[1,1,1,0,1,1,1,1,1,0,1,0],[1,0,1,1,1,1,1,1,1,0,1,0],[1,1,1,1,1,1,1,1,1,0,1,0],[1,1,1,1,1,1,0,0,1,1,1,0],[1,1,1,1,1,1,1,0,1,1,1,0],[1,1,1,1,1,1,0,1,1,1,1,0],[1,0,1,0,1,0,1,1,1,1,1,0],[1,1,1,0,1,0,1,1,1,1,1,0],[1,0,1,1,1,0,1,1,1,1,1,0],[1,1,1,1,1,0,1,1,1,1,1,0],[1,0,1,0,1,1,1,1,1,1,1,0],[1,1,1,0,1,1,1,1,1,1,1,0],[1,0,1,1,1,1,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,1,1,1,0],[1,1,1,1,1,1,1,1,0,0,0,1],[1,0,1,0,1,0,1,1,1,0,0,1],[1,1,1,0,1,0,1,1,1,0,0,1],[1,0,1,1,1,0,1,1,1,0,0,1],[1,1,1,1,1,0,1,1,1,0,0,1],[1,0,1,0,1,1,1,1,1,0,0,1],[1,1,1,0,1,1,1,1,1,0,0,1],[1,0,1,1,1,1,1,1,1,0,0,1],[1,1,1,1,1,1,1,1,1,0,0,1],[1,1,1,1,1,1,0,1,0,1,0,1],[1,1,1,1,1,1,1,1,0,1,0,1],[1,1,1,1,1,1,0,1,1,1,0,1],[1,0,1,0,1,0,1,1,1,1,0,1],[1,1,1,0,1,0,1,1,1,1,0,1],[1,0,1,1,1,0,1,1,1,1,0,1],[1,1,1,1,1,0,1,1,1,1,0,1],[1,0,1,0,1,1,1,1,1,1,0,1],[1,1,1,0,1,1,1,1,1,1,0,1],[1,0,1,1,1,1,1,1,1,1,0,1],[1,1,1,1,1,1,1,1,1,1,0,1],[1,1,1,1,1,1,1,0,0,0,1,1],[1,1,1,1,1,1,1,1,0,0,1,1],[1,1,1,1,1,1,1,0,1,0,1,1],[1,0,1,0,1,0,1,1,1,0,1,1],[1,1,1,0,1,0,1,1,1,0,1,1],[1,0,1,1,1,0,1,1,1,0,1,1],[1,1,1,1,1,0,1,1,1,0,1,1],[1,0,1,0,1,1,1,1,1,0,1,1],[1,1,1,0,1,1,1,1,1,0,1,1],[1,0,1,1,1,1,1,1,1,0,1,1],[1,1,1,1,1,1,1,1,1,0,1,1],[0,1,0,1,0,1,0,0,0,1,1,1],[1,1,0,1,0,1,0,0,0,1,1,1],[0,1,1,1,0,1,0,0,0,1,1,1],[1,1,1,1,0,1,0,0,0,1,1,1],[0,1,0,1,1,1,0,0,0,1,1,1],[1,1,0,1,1,1,0,0,0,1,1,1],[0,1,1,1,1,1,0,0,0,1,1,1],[1,1,1,1,1,1,0,0,0,1,1,1],[0,1,0,1,0,1,1,0,0,1,1,1],[1,1,0,1,0,1,1,0,0,1,1,1],[0,1,1,1,0,1,1,0,0,1,1,1],[1,1,1,1,0,1,1,0,0,1,1,1],[0,1,0,1,1,1,1,0,0,1,1,1],[1,1,0,1,1,1,1,0,0,1,1,1],[0,1,1,1,1,1,1,0,0,1,1,1],[1,1,1,1,1,1,1,0,0,1,1,1],[0,1,0,1,0,1,0,1,0,1,1,1],[1,1,0,1,0,1,0,1,0,1,1,1],[0,1,1,1,0,1,0,1,0,1,1,1],[1,1,1,1,0,1,0,1,0,1,1,1],[0,1,0,1,1,1,0,1,0,1,1,1],[1,1,0,1,1,1,0,1,0,1,1,1],[0,1,1,1,1,1,0,1,0,1,1,1],[1,1,1,1,1,1,0,1,0,1,1,1],[0,1,0,1,0,1,1,1,0,1,1,1],[1,1,0,1,0,1,1,1,0,1,1,1],[0,1,1,1,0,1,1,1,0,1,1,1],[1,1,1,1,0,1,1,1,0,1,1,1],[0,1,0,1,1,1,1,1,0,1,1,1],[1,1,0,1,1,1,1,1,0,1,1,1],[0,1,1,1,1,1,1,1,0,1,1,1],[1,1,1,1,1,1,1,1,0,1,1,1],[0,1,0,1,0,1,0,0,1,1,1,1],[1,1,0,1,0,1,0,0,1,1,1,1],[0,1,1,1,0,1,0,0,1,1,1,1],[1,1,1,1,0,1,0,0,1,1,1,1],[0,1,0,1,1,1,0,0,1,1,1,1],[1,1,0,1,1,1,0,0,1,1,1,1],[0,1,1,1,1,1,0,0,1,1,1,1],[1,1,1,1,1,1,0,0,1,1,1,1],[0,1,0,1,0,1,1,0,1,1,1,1],[1,1,0,1,0,1,1,0,1,1,1,1],[0,1,1,1,0,1,1,0,1,1,1,1],[1,1,1,1,0,1,1,0,1,1,1,1],[0,1,0,1,1,1,1,0,1,1,1,1],[1,1,0,1,1,1,1,0,1,1,1,1],[0,1,1,1,1,1,1,0,1,1,1,1],[1,1,1,1,1,1,1,0,1,1,1,1],[0,1,0,1,0,1,0,1,1,1,1,1],[1,1,0,1,0,1,0,1,1,1,1,1],[0,1,1,1,0,1,0,1,1,1,1,1],[1,1,1,1,0,1,0,1,1,1,1,1],[0,1,0,1,1,1,0,1,1,1,1,1],[1,1,0,1,1,1,0,1,1,1,1,1],[0,1,1,1,1,1,0,1,1,1,1,1],[1,1,1,1,1,1,0,1,1,1,1,1],[1,0,1,0,1,0,1,1,1,1,1,1],[0,1,1,0,1,0,1,1,1,1,1,1],[1,1,1,0,1,0,1,1,1,1,1,1],[1,0,0,1,1,0,1,1,1,1,1,1],[0,1,0,1,1,0,1,1,1,1,1,1],[1,1,0,1,1,0,1,1,1,1,1,1],[1,0,1,1,1,0,1,1,1,1,1,1],[0,1,1,1,1,0,1,1,1,1,1,1],[1,1,1,1,1,0,1,1,1,1,1,1],[1,0,1,0,0,1,1,1,1,1,1,1],[0,1,1,0,0,1,1,1,1,1,1,1],[1,1,1,0,0,1,1,1,1,1,1,1],[1,0,0,1,0,1,1,1,1,1,1,1],[0,1,0,1,0,1,1,1,1,1,1,1],[1,1,0,1,0,1,1,1,1,1,1,1],[1,0,1,1,0,1,1,1,1,1,1,1],[0,1,1,1,0,1,1,1,1,1,1,1],[1,1,1,1,0,1,1,1,1,1,1,1],[1,0,1,0,1,1,1,1,1,1,1,1],[0,1,1,0,1,1,1,1,1,1,1,1],[1,1,1,0,1,1,1,1,1,1,1,1],[1,0,0,1,1,1,1,1,1,1,1,1],[0,1,0,1,1,1,1,1,1,1,1,1],[1,1,0,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,1,1,1,1,1],[0,1,1,1,1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1,1,1]]}],"problem_type":"BMF"} \ No newline at end of file diff --git a/tests/data/jl/coloring.json b/tests/data/jl/coloring.json index fb46f99a..2678cb23 100644 --- a/tests/data/jl/coloring.json +++ b/tests/data/jl/coloring.json @@ -1 +1 @@ -{"instances":[{"label":"doc_petersen_3color","instance":{"k":3,"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":true,"config":[1,2,0,1,0,0,2,2,0,0],"size":12},{"is_valid":true,"config":[0,1,2,2,0,2,0,1,2,1],"size":10},{"is_valid":true,"config":[1,1,1,1,1,2,0,0,1,2],"size":9},{"is_valid":true,"config":[2,0,1,1,1,2,1,2,0,0],"size":11},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":true,"config":[1,0,0,1,0,1,0,0,0,1],"size":10},{"is_valid":true,"config":[0,0,0,0,2,2,2,1,1,0],"size":12},{"is_valid":true,"config":[1,0,0,0,0,2,1,0,0,0],"size":8},{"is_valid":true,"config":[2,1,1,0,0,2,0,2,1,1],"size":11},{"is_valid":true,"config":[0,0,2,0,0,0,0,0,0,1],"size":6}],"best_solutions":[[0,2,0,2,1,2,1,1,0,0],[0,2,0,1,2,2,1,1,0,0],[1,2,0,1,2,2,1,1,0,0],[1,0,2,1,2,2,1,1,0,0],[0,1,0,2,1,2,2,1,0,0],[0,1,0,1,2,2,2,1,0,0],[1,0,2,1,2,2,2,1,0,0],[0,1,2,1,2,2,2,1,0,0],[0,2,0,2,1,1,1,2,0,0],[2,0,1,2,1,1,1,2,0,0],[0,2,1,2,1,1,1,2,0,0],[0,2,0,1,2,1,1,2,0,0],[0,1,0,2,1,1,2,2,0,0],[2,1,0,2,1,1,2,2,0,0],[2,0,1,2,1,1,2,2,0,0],[0,1,0,1,2,1,2,2,0,0],[2,0,2,0,1,0,2,1,1,0],[2,1,2,0,1,0,2,1,1,0],[2,1,0,2,1,0,2,1,1,0],[1,0,2,0,2,0,2,1,1,0],[0,1,2,0,1,2,2,1,1,0],[0,1,0,2,1,2,2,1,1,0],[1,0,2,0,2,2,2,1,1,0],[0,1,2,0,2,2,2,1,1,0],[2,0,1,0,1,0,2,2,1,0],[2,1,0,2,1,0,2,2,1,0],[2,0,1,2,1,0,2,2,1,0],[1,0,1,0,2,0,2,2,1,0],[2,0,2,0,1,0,1,1,2,0],[1,0,2,0,2,0,1,1,2,0],[1,2,0,1,2,0,1,1,2,0],[1,0,2,1,2,0,1,1,2,0],[2,0,1,0,1,0,1,2,2,0],[1,0,1,0,2,0,1,2,2,0],[1,2,1,0,2,0,1,2,2,0],[1,2,0,1,2,0,1,2,2,0],[2,0,1,0,1,1,1,2,2,0],[0,2,1,0,1,1,1,2,2,0],[0,2,1,0,2,1,1,2,2,0],[0,2,0,1,2,1,1,2,2,0],[2,0,2,1,0,1,2,0,0,1],[2,1,2,1,0,1,2,0,0,1],[2,0,1,2,0,1,2,0,0,1],[0,1,2,1,2,1,2,0,0,1],[1,0,2,1,0,2,2,0,0,1],[1,0,1,2,0,2,2,0,0,1],[1,0,2,1,2,2,2,0,0,1],[0,1,2,1,2,2,2,0,0,1],[2,1,0,1,0,1,2,2,0,1],[2,1,0,2,0,1,2,2,0,1],[2,0,1,2,0,1,2,2,0,1],[0,1,0,1,2,1,2,2,0,1],[1,2,1,2,0,2,0,0,1,1],[0,2,1,0,2,2,0,0,1,1],[1,2,1,0,2,2,0,0,1,1],[0,1,2,0,2,2,0,0,1,1],[1,0,1,2,0,2,2,0,1,1],[1,0,1,0,2,2,2,0,1,1],[1,0,2,0,2,2,2,0,1,1],[0,1,2,0,2,2,2,0,1,1],[2,1,0,2,0,0,0,2,1,1],[1,2,0,2,0,0,0,2,1,1],[1,2,1,2,0,0,0,2,1,1],[1,2,1,0,2,0,0,2,1,1],[2,1,0,2,0,0,2,2,1,1],[1,0,1,2,0,0,2,2,1,1],[2,0,1,2,0,0,2,2,1,1],[1,0,1,0,2,0,2,2,1,1],[2,1,2,1,0,1,0,0,2,1],[0,2,1,0,2,1,0,0,2,1],[0,1,2,0,2,1,0,0,2,1],[0,1,2,1,2,1,0,0,2,1],[2,1,0,1,0,0,0,2,2,1],[1,2,0,1,0,0,0,2,2,1],[1,2,1,0,2,0,0,2,2,1],[1,2,0,1,2,0,0,2,2,1],[2,1,0,1,0,1,0,2,2,1],[0,2,1,0,2,1,0,2,2,1],[0,1,0,1,2,1,0,2,2,1],[0,2,0,1,2,1,0,2,2,1],[2,0,2,1,0,1,1,0,0,2],[2,0,1,2,0,1,1,0,0,2],[2,0,1,2,1,1,1,0,0,2],[0,2,1,2,1,1,1,0,0,2],[1,0,2,1,0,2,1,0,0,2],[1,0,1,2,0,2,1,0,0,2],[1,2,1,2,0,2,1,0,0,2],[0,2,1,2,1,2,1,0,0,2],[1,2,0,1,0,2,1,1,0,2],[1,0,2,1,0,2,1,1,0,2],[1,2,0,2,0,2,1,1,0,2],[0,2,0,2,1,2,1,1,0,2],[1,2,1,2,0,2,0,0,1,2],[0,2,1,0,1,2,0,0,1,2],[0,1,2,0,1,2,0,0,1,2],[0,2,1,2,1,2,0,0,1,2],[2,1,0,2,0,0,0,1,1,2],[1,2,0,2,0,0,0,1,1,2],[2,1,2,0,1,0,0,1,1,2],[2,1,0,2,1,0,0,1,1,2],[1,2,0,2,0,2,0,1,1,2],[0,1,2,0,1,2,0,1,1,2],[0,1,0,2,1,2,0,1,1,2],[0,2,0,2,1,2,0,1,1,2],[2,1,2,1,0,1,0,0,2,2],[0,2,1,0,1,1,0,0,2,2],[0,1,2,0,1,1,0,0,2,2],[2,1,2,0,1,1,0,0,2,2],[2,0,2,1,0,1,1,0,2,2],[2,0,1,0,1,1,1,0,2,2],[0,2,1,0,1,1,1,0,2,2],[2,0,2,0,1,1,1,0,2,2],[2,1,0,1,0,0,0,1,2,2],[1,2,0,1,0,0,0,1,2,2],[2,1,2,1,0,0,0,1,2,2],[2,1,2,0,1,0,0,1,2,2],[1,2,0,1,0,0,1,1,2,2],[1,0,2,1,0,0,1,1,2,2],[2,0,2,1,0,0,1,1,2,2],[2,0,2,0,1,0,1,1,2,2]]}],"problem_type":"Coloring"} \ No newline at end of file +{"instances":[{"label":"doc_petersen_3color","instance":{"k":3,"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":true,"config":[1,1,0,1,1,0,1,2,1,1],"size":7},{"is_valid":true,"config":[0,0,2,0,0,0,1,1,0,0],"size":8},{"is_valid":true,"config":[1,2,1,2,0,0,2,0,0,0],"size":10},{"is_valid":true,"config":[2,1,0,2,2,1,1,2,1,0],"size":10},{"is_valid":true,"config":[0,0,1,2,1,1,2,0,1,0],"size":12},{"is_valid":true,"config":[0,2,2,1,0,0,1,1,0,2],"size":11},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":true,"config":[2,2,0,0,0,1,2,0,2,2],"size":8},{"is_valid":true,"config":[0,2,0,1,2,0,1,1,2,2],"size":13},{"is_valid":true,"config":[1,0,0,1,2,2,0,2,1,1],"size":11}],"best_solutions":[[0,2,0,2,1,2,1,1,0,0],[0,2,0,1,2,2,1,1,0,0],[1,2,0,1,2,2,1,1,0,0],[1,0,2,1,2,2,1,1,0,0],[0,1,0,2,1,2,2,1,0,0],[0,1,0,1,2,2,2,1,0,0],[1,0,2,1,2,2,2,1,0,0],[0,1,2,1,2,2,2,1,0,0],[0,2,0,2,1,1,1,2,0,0],[2,0,1,2,1,1,1,2,0,0],[0,2,1,2,1,1,1,2,0,0],[0,2,0,1,2,1,1,2,0,0],[0,1,0,2,1,1,2,2,0,0],[2,1,0,2,1,1,2,2,0,0],[2,0,1,2,1,1,2,2,0,0],[0,1,0,1,2,1,2,2,0,0],[2,0,2,0,1,0,2,1,1,0],[2,1,2,0,1,0,2,1,1,0],[2,1,0,2,1,0,2,1,1,0],[1,0,2,0,2,0,2,1,1,0],[0,1,2,0,1,2,2,1,1,0],[0,1,0,2,1,2,2,1,1,0],[1,0,2,0,2,2,2,1,1,0],[0,1,2,0,2,2,2,1,1,0],[2,0,1,0,1,0,2,2,1,0],[2,1,0,2,1,0,2,2,1,0],[2,0,1,2,1,0,2,2,1,0],[1,0,1,0,2,0,2,2,1,0],[2,0,2,0,1,0,1,1,2,0],[1,0,2,0,2,0,1,1,2,0],[1,2,0,1,2,0,1,1,2,0],[1,0,2,1,2,0,1,1,2,0],[2,0,1,0,1,0,1,2,2,0],[1,0,1,0,2,0,1,2,2,0],[1,2,1,0,2,0,1,2,2,0],[1,2,0,1,2,0,1,2,2,0],[2,0,1,0,1,1,1,2,2,0],[0,2,1,0,1,1,1,2,2,0],[0,2,1,0,2,1,1,2,2,0],[0,2,0,1,2,1,1,2,2,0],[2,0,2,1,0,1,2,0,0,1],[2,1,2,1,0,1,2,0,0,1],[2,0,1,2,0,1,2,0,0,1],[0,1,2,1,2,1,2,0,0,1],[1,0,2,1,0,2,2,0,0,1],[1,0,1,2,0,2,2,0,0,1],[1,0,2,1,2,2,2,0,0,1],[0,1,2,1,2,2,2,0,0,1],[2,1,0,1,0,1,2,2,0,1],[2,1,0,2,0,1,2,2,0,1],[2,0,1,2,0,1,2,2,0,1],[0,1,0,1,2,1,2,2,0,1],[1,2,1,2,0,2,0,0,1,1],[0,2,1,0,2,2,0,0,1,1],[1,2,1,0,2,2,0,0,1,1],[0,1,2,0,2,2,0,0,1,1],[1,0,1,2,0,2,2,0,1,1],[1,0,1,0,2,2,2,0,1,1],[1,0,2,0,2,2,2,0,1,1],[0,1,2,0,2,2,2,0,1,1],[2,1,0,2,0,0,0,2,1,1],[1,2,0,2,0,0,0,2,1,1],[1,2,1,2,0,0,0,2,1,1],[1,2,1,0,2,0,0,2,1,1],[2,1,0,2,0,0,2,2,1,1],[1,0,1,2,0,0,2,2,1,1],[2,0,1,2,0,0,2,2,1,1],[1,0,1,0,2,0,2,2,1,1],[2,1,2,1,0,1,0,0,2,1],[0,2,1,0,2,1,0,0,2,1],[0,1,2,0,2,1,0,0,2,1],[0,1,2,1,2,1,0,0,2,1],[2,1,0,1,0,0,0,2,2,1],[1,2,0,1,0,0,0,2,2,1],[1,2,1,0,2,0,0,2,2,1],[1,2,0,1,2,0,0,2,2,1],[2,1,0,1,0,1,0,2,2,1],[0,2,1,0,2,1,0,2,2,1],[0,1,0,1,2,1,0,2,2,1],[0,2,0,1,2,1,0,2,2,1],[2,0,2,1,0,1,1,0,0,2],[2,0,1,2,0,1,1,0,0,2],[2,0,1,2,1,1,1,0,0,2],[0,2,1,2,1,1,1,0,0,2],[1,0,2,1,0,2,1,0,0,2],[1,0,1,2,0,2,1,0,0,2],[1,2,1,2,0,2,1,0,0,2],[0,2,1,2,1,2,1,0,0,2],[1,2,0,1,0,2,1,1,0,2],[1,0,2,1,0,2,1,1,0,2],[1,2,0,2,0,2,1,1,0,2],[0,2,0,2,1,2,1,1,0,2],[1,2,1,2,0,2,0,0,1,2],[0,2,1,0,1,2,0,0,1,2],[0,1,2,0,1,2,0,0,1,2],[0,2,1,2,1,2,0,0,1,2],[2,1,0,2,0,0,0,1,1,2],[1,2,0,2,0,0,0,1,1,2],[2,1,2,0,1,0,0,1,1,2],[2,1,0,2,1,0,0,1,1,2],[1,2,0,2,0,2,0,1,1,2],[0,1,2,0,1,2,0,1,1,2],[0,1,0,2,1,2,0,1,1,2],[0,2,0,2,1,2,0,1,1,2],[2,1,2,1,0,1,0,0,2,2],[0,2,1,0,1,1,0,0,2,2],[0,1,2,0,1,1,0,0,2,2],[2,1,2,0,1,1,0,0,2,2],[2,0,2,1,0,1,1,0,2,2],[2,0,1,0,1,1,1,0,2,2],[0,2,1,0,1,1,1,0,2,2],[2,0,2,0,1,1,1,0,2,2],[2,1,0,1,0,0,0,1,2,2],[1,2,0,1,0,0,0,1,2,2],[2,1,2,1,0,0,0,1,2,2],[2,1,2,0,1,0,0,1,2,2],[1,2,0,1,0,0,1,1,2,2],[1,0,2,1,0,0,1,1,2,2],[2,0,2,1,0,0,1,1,2,2],[2,0,2,0,1,0,1,1,2,2]]}],"problem_type":"Coloring"} \ No newline at end of file diff --git a/tests/data/jl/dominatingset.json b/tests/data/jl/dominatingset.json index d9735f67..26992291 100644 --- a/tests/data/jl/dominatingset.json +++ b/tests/data/jl/dominatingset.json @@ -1 +1 @@ -{"instances":[{"label":"doc_path5","instance":{"weights":[1,1,1,1,1],"num_vertices":5,"edges":[[0,1],[1,2],[2,3],[3,4]]},"evaluations":[{"is_valid":false,"config":[0,0,0,0,1],"size":1},{"is_valid":false,"config":[0,0,0,0,0],"size":0},{"is_valid":false,"config":[0,0,1,0,0],"size":1},{"is_valid":true,"config":[0,1,1,0,1],"size":3},{"is_valid":true,"config":[1,0,0,1,1],"size":3},{"is_valid":false,"config":[0,1,1,0,0],"size":2},{"is_valid":true,"config":[1,0,1,1,1],"size":4},{"is_valid":true,"config":[1,1,1,1,1],"size":5},{"is_valid":false,"config":[1,0,1,0,0],"size":2},{"is_valid":false,"config":[1,0,0,0,0],"size":1}],"best_solutions":[[1,0,0,1,0],[0,1,0,1,0],[0,1,0,0,1]]}],"problem_type":"DominatingSet"} \ No newline at end of file +{"instances":[{"label":"doc_path5","instance":{"weights":[1,1,1,1,1],"num_vertices":5,"edges":[[0,1],[1,2],[2,3],[3,4]]},"evaluations":[{"is_valid":false,"config":[0,0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,0,1],"size":3},{"is_valid":false,"config":[1,1,0,0,0],"size":2},{"is_valid":true,"config":[1,1,1,1,1],"size":5},{"is_valid":false,"config":[0,1,0,0,0],"size":1},{"is_valid":true,"config":[1,1,1,1,0],"size":4},{"is_valid":true,"config":[1,1,0,1,1],"size":4},{"is_valid":true,"config":[1,1,0,1,0],"size":3},{"is_valid":true,"config":[0,1,1,1,0],"size":3},{"is_valid":false,"config":[0,0,1,0,0],"size":1}],"best_solutions":[[1,0,0,1,0],[0,1,0,1,0],[0,1,0,0,1]]}],"problem_type":"DominatingSet"} \ No newline at end of file diff --git a/tests/data/jl/factoring.json b/tests/data/jl/factoring.json index 03606810..36910ef4 100644 --- a/tests/data/jl/factoring.json +++ b/tests/data/jl/factoring.json @@ -1 +1 @@ -{"instances":[{"label":"1x1_factor_1","instance":{"m":1,"input":1,"n":1},"evaluations":[{"is_valid":false,"config":[0,0],"size":0},{"is_valid":true,"config":[1,1],"size":0},{"is_valid":false,"config":[1,0],"size":0},{"is_valid":false,"config":[0,1],"size":0}],"best_solutions":[[1,1]]},{"label":"2x1_factor_2","instance":{"m":2,"input":2,"n":1},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":0},{"is_valid":false,"config":[1,0,1],"size":0},{"is_valid":false,"config":[1,0,0],"size":0},{"is_valid":false,"config":[0,0,1],"size":0},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":false,"config":[1,1,1],"size":0},{"is_valid":true,"config":[0,1,1],"size":0},{"is_valid":false,"config":[1,1,0],"size":0}],"best_solutions":[[0,1,1]]},{"label":"2x1_factor_3","instance":{"m":2,"input":3,"n":1},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":0},{"is_valid":false,"config":[1,0,1],"size":0},{"is_valid":false,"config":[0,0,1],"size":0},{"is_valid":false,"config":[1,0,0],"size":0},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":false,"config":[1,1,0],"size":0},{"is_valid":false,"config":[0,1,1],"size":0}],"best_solutions":[[1,1,1]]},{"label":"doc_factor6","instance":{"m":2,"input":6,"n":2},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":0},{"is_valid":false,"config":[1,0,1,1],"size":0},{"is_valid":false,"config":[1,0,1,0],"size":0},{"is_valid":false,"config":[0,1,0,1],"size":0},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[0,1,1,1],"size":0},{"is_valid":true,"config":[1,1,0,1],"size":0},{"is_valid":false,"config":[1,0,0,1],"size":0},{"is_valid":false,"config":[1,0,0,0],"size":0},{"is_valid":false,"config":[1,1,1,1],"size":0}],"best_solutions":[[1,1,0,1],[0,1,1,1]]}],"problem_type":"Factoring"} \ No newline at end of file +{"instances":[{"label":"1x1_factor_1","instance":{"m":1,"input":1,"n":1},"evaluations":[{"is_valid":false,"config":[0,0],"size":0},{"is_valid":true,"config":[1,1],"size":0},{"is_valid":false,"config":[1,0],"size":0},{"is_valid":false,"config":[0,1],"size":0}],"best_solutions":[[1,1]]},{"label":"2x1_factor_2","instance":{"m":2,"input":2,"n":1},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":0},{"is_valid":false,"config":[1,0,1],"size":0},{"is_valid":false,"config":[0,0,1],"size":0},{"is_valid":false,"config":[1,0,0],"size":0},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":false,"config":[1,1,1],"size":0},{"is_valid":true,"config":[0,1,1],"size":0},{"is_valid":false,"config":[1,1,0],"size":0}],"best_solutions":[[0,1,1]]},{"label":"2x1_factor_3","instance":{"m":2,"input":3,"n":1},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":0},{"is_valid":false,"config":[1,0,1],"size":0},{"is_valid":false,"config":[1,0,0],"size":0},{"is_valid":false,"config":[0,0,1],"size":0},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":false,"config":[1,1,0],"size":0},{"is_valid":false,"config":[0,1,1],"size":0}],"best_solutions":[[1,1,1]]},{"label":"doc_factor6","instance":{"m":2,"input":6,"n":2},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":0},{"is_valid":false,"config":[0,0,0,1],"size":0},{"is_valid":false,"config":[0,1,0,0],"size":0},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,1],"size":0},{"is_valid":false,"config":[0,1,1,0],"size":0},{"is_valid":false,"config":[0,0,1,1],"size":0},{"is_valid":false,"config":[0,0,1,0],"size":0},{"is_valid":false,"config":[1,0,0,0],"size":0},{"is_valid":false,"config":[1,1,1,1],"size":0}],"best_solutions":[[1,1,0,1],[0,1,1,1]]}],"problem_type":"Factoring"} \ No newline at end of file diff --git a/tests/data/jl/independentset.json b/tests/data/jl/independentset.json index 95789eac..713b1354 100644 --- a/tests/data/jl/independentset.json +++ b/tests/data/jl/independentset.json @@ -1 +1 @@ -{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[0,1,0,1,0,0,1,0,1,1],"size":5},{"is_valid":false,"config":[0,0,0,1,1,1,0,0,1,0],"size":4},{"is_valid":false,"config":[0,0,0,1,0,0,1,1,1,0],"size":4},{"is_valid":false,"config":[1,0,0,0,1,0,0,0,0,0],"size":2},{"is_valid":false,"config":[1,0,1,1,1,1,0,0,0,0],"size":5},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[1,0,1,1,1,0,0,0,0,0],"size":4},{"is_valid":false,"config":[1,1,1,1,1,0,0,1,1,1],"size":8},{"is_valid":false,"config":[1,1,1,1,1,1,1,1,1,1],"size":10},{"is_valid":false,"config":[0,1,1,0,0,0,0,0,0,0],"size":2}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,0,0,0,0,0,1,1]]},{"label":"doc_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":true,"config":[0,0,0,1],"size":1},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[0,1,1,1],"size":3},{"is_valid":true,"config":[1,0,0,1],"size":2},{"is_valid":false,"config":[0,0,1,1],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":true,"config":[0,0,1,0],"size":1},{"is_valid":false,"config":[1,1,1,1],"size":4},{"is_valid":false,"config":[0,1,1,0],"size":2}],"best_solutions":[[1,0,0,1],[0,1,0,1]]},{"label":"doc_diamond","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[1,3],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,0,1,1],"size":3},{"is_valid":false,"config":[1,0,1,0],"size":2},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[0,1,1,1],"size":3},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":false,"config":[0,1,1,0],"size":2},{"is_valid":false,"config":[0,0,1,1],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":1},{"is_valid":true,"config":[1,0,0,1],"size":2},{"is_valid":false,"config":[1,1,1,1],"size":4}],"best_solutions":[[1,0,0,1]]}],"problem_type":"IndependentSet"} \ No newline at end of file +{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[1,0,0,1,1,1,0,0,0,1],"size":5},{"is_valid":false,"config":[0,1,0,1,0,0,0,1,0,1],"size":4},{"is_valid":false,"config":[0,0,1,1,0,0,0,1,1,0],"size":4},{"is_valid":false,"config":[1,1,0,0,1,0,0,0,0,0],"size":3},{"is_valid":false,"config":[1,0,1,0,0,1,0,1,1,1],"size":6},{"is_valid":false,"config":[1,0,0,1,1,0,1,1,0,0],"size":5},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[0,0,1,0,0,0,1,0,1,0],"size":3},{"is_valid":false,"config":[1,1,1,1,1,1,1,1,1,1],"size":10},{"is_valid":false,"config":[0,1,1,1,0,1,0,1,1,0],"size":6}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,0,0,0,0,0,1,1]]},{"label":"doc_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":true,"config":[0,1,0,1],"size":2},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":false,"config":[1,1,0,0],"size":2},{"is_valid":false,"config":[0,1,1,0],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":true,"config":[1,0,0,1],"size":2},{"is_valid":false,"config":[1,1,1,1],"size":4},{"is_valid":false,"config":[0,0,1,1],"size":2}],"best_solutions":[[1,0,0,1],[0,1,0,1]]},{"label":"doc_diamond","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[1,3],[2,3]]},"evaluations":[{"is_valid":false,"config":[0,1,0,1],"size":2},{"is_valid":false,"config":[1,0,1,0],"size":2},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":false,"config":[1,1,0,0],"size":2},{"is_valid":false,"config":[0,0,1,1],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":false,"config":[0,1,1,0],"size":2},{"is_valid":false,"config":[1,1,1,1],"size":4},{"is_valid":true,"config":[1,0,0,1],"size":2}],"best_solutions":[[1,0,0,1]]}],"problem_type":"IndependentSet"} \ No newline at end of file diff --git a/tests/data/jl/matching.json b/tests/data/jl/matching.json index f4dc3d65..e8924f62 100644 --- a/tests/data/jl/matching.json +++ b/tests/data/jl/matching.json @@ -1 +1 @@ -{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[0,1,0,1,1,1,1,1,0,1,1,1,0,0,0],"size":9},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[1,0,1,0,0,0,1,1,0,0,1,1,1,0,0],"size":7},{"is_valid":false,"config":[0,0,1,0,0,1,0,0,1,1,1,1,0,1,0],"size":7},{"is_valid":false,"config":[0,0,1,1,1,1,0,0,0,1,0,1,0,0,0],"size":6},{"is_valid":false,"config":[0,1,1,1,0,0,1,0,0,0,0,0,1,0,0],"size":5},{"is_valid":false,"config":[1,0,0,0,0,1,0,1,0,1,1,1,1,1,1],"size":9},{"is_valid":false,"config":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"size":15},{"is_valid":false,"config":[1,1,0,1,0,0,1,1,0,0,1,0,1,0,0],"size":7},{"is_valid":false,"config":[1,0,1,0,0,1,1,0,1,1,0,1,1,1,1],"size":10}],"best_solutions":[[0,0,1,0,1,0,1,0,1,1,0,0,0,0,0],[1,0,0,0,0,1,0,0,0,1,1,0,1,0,0],[0,1,0,1,0,0,0,0,1,0,1,0,0,1,0],[1,0,0,0,0,0,1,1,0,0,0,1,0,1,0],[0,1,0,0,1,1,0,0,0,0,0,1,0,0,1],[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1]]},{"label":"rule_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":false,"config":[1,0,1,0],"size":2},{"is_valid":false,"config":[0,1,0,1],"size":2},{"is_valid":true,"config":[0,0,0,1],"size":1},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":false,"config":[0,1,1,1],"size":3},{"is_valid":true,"config":[1,0,0,1],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":1},{"is_valid":false,"config":[1,1,1,1],"size":4}],"best_solutions":[[1,0,0,1]]},{"label":"rule_4vertex_weighted","instance":{"weights":[1,2,3,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":6},{"is_valid":false,"config":[1,0,1,1],"size":8},{"is_valid":false,"config":[0,1,0,1],"size":6},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[0,1,1,1],"size":9},{"is_valid":false,"config":[1,1,0,1],"size":7},{"is_valid":false,"config":[0,1,1,0],"size":5},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":true,"config":[0,0,1,0],"size":3},{"is_valid":false,"config":[1,1,1,1],"size":10}],"best_solutions":[[1,0,0,1]]}],"problem_type":"Matching"} \ No newline at end of file +{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[1,0,0,0,0,1,0,1,1,0,0,0,0,1,1],"size":6},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[0,1,1,1,1,0,0,0,1,0,1,1,0,1,0],"size":8},{"is_valid":false,"config":[1,1,1,1,1,1,0,0,0,1,0,0,0,0,1],"size":8},{"is_valid":false,"config":[1,1,0,1,0,1,0,1,1,0,1,0,1,1,0],"size":9},{"is_valid":false,"config":[0,0,0,0,0,1,0,1,0,0,1,0,1,0,1],"size":5},{"is_valid":false,"config":[1,1,0,1,0,1,1,1,1,0,1,1,1,1,1],"size":12},{"is_valid":false,"config":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"size":15},{"is_valid":false,"config":[1,0,0,0,1,1,0,0,1,1,0,0,1,1,0],"size":7},{"is_valid":false,"config":[0,1,0,1,1,1,0,1,1,1,1,1,0,0,1],"size":10}],"best_solutions":[[0,0,1,0,1,0,1,0,1,1,0,0,0,0,0],[1,0,0,0,0,1,0,0,0,1,1,0,1,0,0],[0,1,0,1,0,0,0,0,1,0,1,0,0,1,0],[1,0,0,0,0,0,1,1,0,0,0,1,0,1,0],[0,1,0,0,1,1,0,0,0,0,0,1,0,0,1],[0,0,1,1,0,0,0,1,0,0,0,0,1,0,1]]},{"label":"rule_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":false,"config":[1,0,1,0],"size":2},{"is_valid":true,"config":[0,0,0,1],"size":1},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":true,"config":[1,0,0,1],"size":2},{"is_valid":false,"config":[1,1,0,0],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":1},{"is_valid":false,"config":[0,1,1,0],"size":2},{"is_valid":false,"config":[1,1,1,1],"size":4}],"best_solutions":[[1,0,0,1]]},{"label":"rule_4vertex_weighted","instance":{"weights":[1,2,3,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,0,1,0],"size":4},{"is_valid":true,"config":[0,0,0,1],"size":4},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":7},{"is_valid":false,"config":[0,1,1,1],"size":9},{"is_valid":false,"config":[1,1,0,0],"size":3},{"is_valid":false,"config":[0,0,1,1],"size":7},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":true,"config":[0,0,1,0],"size":3},{"is_valid":false,"config":[1,1,1,1],"size":10}],"best_solutions":[[1,0,0,1]]}],"problem_type":"Matching"} \ No newline at end of file diff --git a/tests/data/jl/maxcut.json b/tests/data/jl/maxcut.json index 91c12428..569a83ab 100644 --- a/tests/data/jl/maxcut.json +++ b/tests/data/jl/maxcut.json @@ -1 +1 @@ -{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":true,"config":[0,1,1,1,1,1,0,0,0,0],"size":9},{"is_valid":true,"config":[1,1,0,0,1,0,1,0,1,0],"size":7},{"is_valid":true,"config":[0,1,0,1,0,1,1,1,0,1],"size":10},{"is_valid":true,"config":[1,1,1,1,0,1,0,0,1,0],"size":6},{"is_valid":true,"config":[0,0,0,0,1,0,1,0,0,0],"size":6},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":true,"config":[0,0,0,1,0,1,0,0,1,1],"size":8},{"is_valid":true,"config":[0,1,1,1,0,1,0,0,0,0],"size":8},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":0},{"is_valid":true,"config":[0,0,1,1,1,1,0,1,0,1],"size":6}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,1,1,1,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[1,0,1,0,1,0,1,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,1,0,1,1,0,0,1],[1,0,1,0,0,0,0,0,1,1],[0,1,1,0,1,1,0,0,1,1],[1,1,0,1,0,0,0,1,1,1]]},{"label":"doc_k3","instance":{"weights":[1,2,3],"num_vertices":3,"edges":[[0,1],[0,2],[1,2]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":4},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":3},{"is_valid":true,"config":[0,0,1],"size":5},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[1,1,0],"size":5},{"is_valid":true,"config":[0,1,1],"size":3}],"best_solutions":[[1,1,0],[0,0,1]]},{"label":"rule_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":4},{"is_valid":true,"config":[1,0,1,1],"size":2},{"is_valid":true,"config":[1,0,1,0],"size":6},{"is_valid":true,"config":[0,0,0,1],"size":4},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,0],"size":4},{"is_valid":true,"config":[1,0,0,1],"size":8},{"is_valid":true,"config":[0,0,1,0],"size":8},{"is_valid":true,"config":[0,0,1,1],"size":4},{"is_valid":true,"config":[1,1,1,1],"size":0}],"best_solutions":[[0,0,1,0],[0,1,1,0],[1,0,0,1],[1,1,0,1]]}],"problem_type":"MaxCut"} \ No newline at end of file +{"instances":[{"label":"petersen","instance":{"weights":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":true,"config":[0,0,1,0,0,0,0,0,0,0],"size":3},{"is_valid":true,"config":[1,1,0,1,1,1,0,1,1,1],"size":6},{"is_valid":true,"config":[1,1,0,1,1,0,0,1,1,1],"size":9},{"is_valid":true,"config":[0,1,0,0,1,1,1,1,1,1],"size":7},{"is_valid":true,"config":[0,1,0,0,1,0,1,0,0,0],"size":7},{"is_valid":true,"config":[0,1,1,0,1,0,1,1,0,0],"size":9},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":true,"config":[0,0,0,0,0,1,1,1,0,1],"size":6},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":0},{"is_valid":true,"config":[0,0,0,1,0,0,0,0,1,0],"size":4}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,1,1,1,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[1,0,1,0,1,0,1,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,1,0,1,1,0,0,1],[1,0,1,0,0,0,0,0,1,1],[0,1,1,0,1,1,0,0,1,1],[1,1,0,1,0,0,0,1,1,1]]},{"label":"doc_k3","instance":{"weights":[1,2,3],"num_vertices":3,"edges":[[0,1],[0,2],[1,2]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":4},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":3},{"is_valid":true,"config":[0,0,1],"size":5},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[1,1,0],"size":5},{"is_valid":true,"config":[0,1,1],"size":3}],"best_solutions":[[1,1,0],[0,0,1]]},{"label":"rule_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,0,1,1],"size":2},{"is_valid":true,"config":[0,1,0,1],"size":6},{"is_valid":true,"config":[1,0,1,0],"size":6},{"is_valid":true,"config":[0,0,0,1],"size":4},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,0,0,1],"size":8},{"is_valid":true,"config":[0,1,1,0],"size":8},{"is_valid":true,"config":[0,0,1,0],"size":8},{"is_valid":true,"config":[1,0,0,0],"size":4},{"is_valid":true,"config":[1,1,1,1],"size":0}],"best_solutions":[[0,0,1,0],[0,1,1,0],[1,0,0,1],[1,1,0,1]]}],"problem_type":"MaxCut"} \ No newline at end of file diff --git a/tests/data/jl/maximalis.json b/tests/data/jl/maximalis.json index 52a13471..d6ce3a97 100644 --- a/tests/data/jl/maximalis.json +++ b/tests/data/jl/maximalis.json @@ -1 +1 @@ -{"instances":[{"label":"doc_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[0,3],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":false,"config":[1,0,1,1],"size":3},{"is_valid":false,"config":[1,0,1,0],"size":2},{"is_valid":true,"config":[0,1,0,1],"size":2},{"is_valid":false,"config":[0,0,0,1],"size":1},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,0,1],"size":3},{"is_valid":false,"config":[1,1,0,0],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":false,"config":[1,1,1,1],"size":4}],"best_solutions":[[0,1,0,1]]}],"problem_type":"MaximalIS"} \ No newline at end of file +{"instances":[{"label":"doc_4vertex","instance":{"weights":[1,1,1,1],"num_vertices":4,"edges":[[0,1],[0,2],[0,3],[1,2],[2,3]]},"evaluations":[{"is_valid":false,"config":[1,1,1,0],"size":3},{"is_valid":true,"config":[0,1,0,1],"size":2},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":false,"config":[0,1,1,1],"size":3},{"is_valid":false,"config":[1,1,0,0],"size":2},{"is_valid":false,"config":[1,0,0,1],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":1},{"is_valid":true,"config":[1,0,0,0],"size":1},{"is_valid":false,"config":[1,1,1,1],"size":4},{"is_valid":false,"config":[0,1,1,0],"size":2}],"best_solutions":[[0,1,0,1]]}],"problem_type":"MaximalIS"} \ No newline at end of file diff --git a/tests/data/jl/paintshop.json b/tests/data/jl/paintshop.json index 4c7637bc..55c29e19 100644 --- a/tests/data/jl/paintshop.json +++ b/tests/data/jl/paintshop.json @@ -1 +1 @@ -{"instances":[{"label":"doc_abaccb","instance":{"num_cars":3,"sequence":["a","b","a","c","c","b"]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":4},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,1],"size":3},{"is_valid":true,"config":[0,0,0],"size":3},{"is_valid":true,"config":[1,1,1],"size":3},{"is_valid":true,"config":[0,1,1],"size":2},{"is_valid":true,"config":[1,1,0],"size":3}],"best_solutions":[[1,0,0],[0,1,1]]}],"problem_type":"PaintShop"} \ No newline at end of file +{"instances":[{"label":"doc_abaccb","instance":{"num_cars":3,"sequence":["a","b","a","c","c","b"]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":4},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,1],"size":3},{"is_valid":true,"config":[0,0,0],"size":3},{"is_valid":true,"config":[1,1,1],"size":3},{"is_valid":true,"config":[1,1,0],"size":3},{"is_valid":true,"config":[0,1,1],"size":2}],"best_solutions":[[1,0,0],[0,1,1]]}],"problem_type":"PaintShop"} \ No newline at end of file diff --git a/tests/data/jl/path_factoring_to_spinglass.json b/tests/data/jl/path_factoring_to_spinglass.json new file mode 100644 index 00000000..9927356b --- /dev/null +++ b/tests/data/jl/path_factoring_to_spinglass.json @@ -0,0 +1 @@ +{"extracted":[[1,1,1]],"best_source":[[1,1,1]],"path":["UnionAll","UnionAll","UnionAll","UnionAll"]} \ No newline at end of file diff --git a/tests/data/jl/path_maxcut_to_qubo.json b/tests/data/jl/path_maxcut_to_qubo.json new file mode 100644 index 00000000..ce8447dc --- /dev/null +++ b/tests/data/jl/path_maxcut_to_qubo.json @@ -0,0 +1 @@ +{"extracted":[[0,0,1,0,1,1,1,0,0,0],[0,1,0,0,1,0,0,1,1,0],[0,1,0,1,0,1,0,0,0,1],[0,1,0,1,1,1,1,1,0,0],[0,1,1,0,1,1,0,0,1,1],[1,0,0,1,0,0,1,1,0,0],[1,0,1,0,0,0,0,0,1,1],[1,0,1,0,1,0,1,1,1,0],[1,0,1,1,0,1,1,0,0,1],[1,1,0,1,0,0,0,1,1,1]],"best_source":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,1,1,1,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[1,0,1,0,1,0,1,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,1,0,1,1,0,0,1],[1,0,1,0,0,0,0,0,1,1],[0,1,1,0,1,1,0,0,1,1],[1,1,0,1,0,0,0,1,1,1]],"path":["UnionAll","UnionAll","UnionAll"]} \ No newline at end of file diff --git a/tests/data/jl/path_maxcut_to_spinglass.json b/tests/data/jl/path_maxcut_to_spinglass.json new file mode 100644 index 00000000..30dfd037 --- /dev/null +++ b/tests/data/jl/path_maxcut_to_spinglass.json @@ -0,0 +1 @@ +{"extracted":[[0,0,1,0,1,1,1,0,0,0],[0,1,0,0,1,0,0,1,1,0],[0,1,0,1,0,1,0,0,0,1],[0,1,0,1,1,1,1,1,0,0],[0,1,1,0,1,1,0,0,1,1],[1,0,0,1,0,0,1,1,0,0],[1,0,1,0,0,0,0,0,1,1],[1,0,1,0,1,0,1,1,1,0],[1,0,1,1,0,1,1,0,0,1],[1,1,0,1,0,0,0,1,1,1]],"best_source":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,1,1,1,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[1,0,1,0,1,0,1,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,1,0,1,1,0,0,1],[1,0,1,0,0,0,0,0,1,1],[0,1,1,0,1,1,0,0,1,1],[1,1,0,1,0,0,0,1,1,1]],"path":["UnionAll","UnionAll","UnionAll"],"best_target":[[0,0,1,0,1,1,1,0,0,0],[1,0,0,1,0,0,1,1,0,0],[0,1,0,1,1,1,1,1,0,0],[0,1,0,0,1,0,0,1,1,0],[1,0,1,0,1,0,1,1,1,0],[0,1,0,1,0,1,0,0,0,1],[1,0,1,1,0,1,1,0,0,1],[1,0,1,0,0,0,0,0,1,1],[0,1,1,0,1,1,0,0,1,1],[1,1,0,1,0,0,0,1,1,1]]} \ No newline at end of file diff --git a/tests/data/jl/qubo.json b/tests/data/jl/qubo.json index 097dd733..6bfb94d3 100644 --- a/tests/data/jl/qubo.json +++ b/tests/data/jl/qubo.json @@ -1 +1 @@ -{"instances":[{"label":"3x3_matrix","instance":{"matrix":[[0,1,-2],[1,0,-2],[-2,-2,6]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":0},{"is_valid":true,"config":[1,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":0},{"is_valid":true,"config":[0,0,1],"size":6},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[1,1,0],"size":2},{"is_valid":true,"config":[0,1,1],"size":2}],"best_solutions":[[0,0,0],[1,0,0],[0,1,0],[1,1,1]]},{"label":"doc_identity","instance":{"matrix":[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":1.0},{"is_valid":true,"config":[1,0,1],"size":2.0},{"is_valid":true,"config":[1,0,0],"size":1.0},{"is_valid":true,"config":[0,0,1],"size":1.0},{"is_valid":true,"config":[0,0,0],"size":0.0},{"is_valid":true,"config":[1,1,1],"size":3.0},{"is_valid":true,"config":[1,1,0],"size":2.0},{"is_valid":true,"config":[0,1,1],"size":2.0}],"best_solutions":[[0,0,0]]},{"label":"rule_3x3","instance":{"matrix":[[2,1,-2],[1,2,-2],[-2,-2,2]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":0},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[1,1,0],"size":6},{"is_valid":true,"config":[0,1,1],"size":0}],"best_solutions":[[0,0,0],[1,0,1],[0,1,1],[1,1,1]]}],"problem_type":"QUBO"} \ No newline at end of file +{"instances":[{"label":"3x3_matrix","instance":{"matrix":[[0,1,-2],[1,0,-2],[-2,-2,6]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":0},{"is_valid":true,"config":[1,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":0},{"is_valid":true,"config":[0,0,1],"size":6},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[0,1,1],"size":2},{"is_valid":true,"config":[1,1,0],"size":2}],"best_solutions":[[0,0,0],[1,0,0],[0,1,0],[1,1,1]]},{"label":"doc_identity","instance":{"matrix":[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":1.0},{"is_valid":true,"config":[1,0,1],"size":2.0},{"is_valid":true,"config":[0,0,1],"size":1.0},{"is_valid":true,"config":[1,0,0],"size":1.0},{"is_valid":true,"config":[0,0,0],"size":0.0},{"is_valid":true,"config":[1,1,1],"size":3.0},{"is_valid":true,"config":[0,1,1],"size":2.0},{"is_valid":true,"config":[1,1,0],"size":2.0}],"best_solutions":[[0,0,0]]},{"label":"rule_3x3","instance":{"matrix":[[2,1,-2],[1,2,-2],[-2,-2,2]]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":0},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":0},{"is_valid":true,"config":[1,1,0],"size":6},{"is_valid":true,"config":[0,1,1],"size":0}],"best_solutions":[[0,0,0],[1,0,1],[0,1,1],[1,1,1]]}],"problem_type":"QUBO"} \ No newline at end of file diff --git a/tests/data/jl/rule_sat01_to_independentset.json b/tests/data/jl/rule_sat01_to_independentset.json index ee4a6f3e..4b31cea2 100644 --- a/tests/data/jl/rule_sat01_to_independentset.json +++ b/tests/data/jl/rule_sat01_to_independentset.json @@ -1 +1 @@ -{"target_type":"IndependentSet","cases":[{"label":"rule_sat01","extracted_single":[[0,0,0],[0,0,1],[1,1,0],[1,1,1]],"extracted_multiple":[[0,0,0],[0,0,1],[1,1,0],[1,1,1]],"best_source":[[0,0,0],[1,1,0],[0,0,1],[1,1,1]],"best_target":[[0,1,0,1,0,0,0,1,0,1,0,0],[0,0,1,1,0,0,0,1,0,1,0,0],[0,1,0,0,0,1,0,1,0,1,0,0],[0,1,0,1,0,0,0,0,1,1,0,0],[0,1,0,0,0,1,0,0,1,1,0,0],[1,0,0,0,1,0,1,0,0,0,1,0],[0,0,1,0,1,0,1,0,0,0,1,0],[1,0,0,0,0,1,1,0,0,0,1,0],[1,0,0,0,1,0,0,0,1,0,1,0],[1,0,0,0,0,1,0,0,1,0,1,0],[1,0,0,0,1,0,1,0,0,0,0,1],[0,0,1,0,1,0,1,0,0,0,0,1],[0,1,0,1,0,0,0,1,0,0,0,1],[0,0,1,1,0,0,0,1,0,0,0,1]]}],"source_type":"rule_SAT01"} \ No newline at end of file +{"target_type":"IndependentSet","cases":[{"label":"rule_sat01","extracted_single":[[0,0,1],[0,0,0],[1,1,1],[1,1,0]],"extracted_multiple":[[0,0,0],[0,0,1],[1,1,0],[1,1,1]],"best_source":[[0,0,0],[1,1,0],[0,0,1],[1,1,1]],"best_target":[[0,1,0,1,0,0,0,1,0,1,0,0],[0,0,1,1,0,0,0,1,0,1,0,0],[0,1,0,0,0,1,0,1,0,1,0,0],[0,1,0,1,0,0,0,0,1,1,0,0],[0,1,0,0,0,1,0,0,1,1,0,0],[1,0,0,0,1,0,1,0,0,0,1,0],[0,0,1,0,1,0,1,0,0,0,1,0],[1,0,0,0,0,1,1,0,0,0,1,0],[1,0,0,0,1,0,0,0,1,0,1,0],[1,0,0,0,0,1,0,0,1,0,1,0],[1,0,0,0,1,0,1,0,0,0,0,1],[0,0,1,0,1,0,1,0,0,0,0,1],[0,1,0,1,0,0,0,1,0,0,0,1],[0,0,1,1,0,0,0,1,0,0,0,1]]}],"source_type":"rule_SAT01"} \ No newline at end of file diff --git a/tests/data/jl/rule_sat02_to_independentset.json b/tests/data/jl/rule_sat02_to_independentset.json index 2a41c9a8..93b22648 100644 --- a/tests/data/jl/rule_sat02_to_independentset.json +++ b/tests/data/jl/rule_sat02_to_independentset.json @@ -1 +1 @@ -{"target_type":"IndependentSet","cases":[{"label":"rule_sat02","extracted_single":[[1,1,1],[1,0,1],[1,1,0],[0,1,1],[0,0,0]],"extracted_multiple":[[1,1,0],[1,1,1],[1,0,1],[0,1,1],[0,0,0]],"best_source":[[0,0,0],[1,1,0],[1,0,1],[0,1,1],[1,1,1]],"best_target":[[0,1,0,1,0,0,1,0,0],[0,0,1,1,0,0,1,0,0],[0,0,1,0,1,0,1,0,0],[0,1,0,0,0,1,1,0,0],[0,0,1,0,0,1,1,0,0],[0,1,0,1,0,0,0,1,0],[0,0,1,1,0,0,0,1,0],[1,0,0,0,0,1,0,1,0],[0,1,0,0,0,1,0,1,0],[0,0,1,0,0,1,0,1,0],[0,1,0,1,0,0,0,0,1],[1,0,0,0,1,0,0,0,1]]}],"source_type":"rule_SAT02"} \ No newline at end of file +{"target_type":"IndependentSet","cases":[{"label":"rule_sat02","extracted_single":[[1,1,0],[1,0,1],[1,1,1],[0,1,1],[0,0,0]],"extracted_multiple":[[1,1,0],[1,1,1],[1,0,1],[0,1,1],[0,0,0]],"best_source":[[0,0,0],[1,1,0],[1,0,1],[0,1,1],[1,1,1]],"best_target":[[0,1,0,1,0,0,1,0,0],[0,0,1,1,0,0,1,0,0],[0,0,1,0,1,0,1,0,0],[0,1,0,0,0,1,1,0,0],[0,0,1,0,0,1,1,0,0],[0,1,0,1,0,0,0,1,0],[0,0,1,1,0,0,0,1,0],[1,0,0,0,0,1,0,1,0],[0,1,0,0,0,1,0,1,0],[0,0,1,0,0,1,0,1,0],[0,1,0,1,0,0,0,0,1],[1,0,0,0,1,0,0,0,1]]}],"source_type":"rule_SAT02"} \ No newline at end of file diff --git a/tests/data/jl/rule_sat03_to_independentset.json b/tests/data/jl/rule_sat03_to_independentset.json index 668a179d..2ea481cf 100644 --- a/tests/data/jl/rule_sat03_to_independentset.json +++ b/tests/data/jl/rule_sat03_to_independentset.json @@ -1 +1 @@ -{"target_type":"IndependentSet","cases":[{"label":"rule_sat03","extracted_single":[[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0]],"extracted_multiple":[[0,1,0],[0,1,1],[0,0,1],[1,0,0],[1,0,1],[1,1,0]],"best_source":[[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1]],"best_target":[[0,1,0,1,0,0],[0,0,1,1,0,0],[1,0,0,0,1,0],[0,0,1,0,1,0],[1,0,0,0,0,1],[0,1,0,0,0,1]]}],"source_type":"rule_SAT03"} \ No newline at end of file +{"target_type":"IndependentSet","cases":[{"label":"rule_sat03","extracted_single":[[0,1,1],[1,0,1],[0,0,1],[1,0,0],[0,1,0]],"extracted_multiple":[[0,1,0],[0,1,1],[0,0,1],[1,0,0],[1,0,1],[1,1,0]],"best_source":[[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1]],"best_target":[[0,1,0,1,0,0],[0,0,1,1,0,0],[1,0,0,0,1,0],[0,0,1,0,1,0],[1,0,0,0,0,1],[0,1,0,0,0,1]]}],"source_type":"rule_SAT03"} \ No newline at end of file diff --git a/tests/data/jl/satisfiability.json b/tests/data/jl/satisfiability.json index 0e47af4e..9d9b5400 100644 --- a/tests/data/jl/satisfiability.json +++ b/tests/data/jl/satisfiability.json @@ -1 +1 @@ -{"instances":[{"label":"simple_clause","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":0},{"is_valid":true,"config":[1,1],"size":1},{"is_valid":true,"config":[1,0],"size":1},{"is_valid":true,"config":[0,1],"size":1}],"best_solutions":[[1,0],[0,1],[1,1]]},{"label":"rule_3sat_multi","instance":{"num_variables":4,"clauses":[{"literals":[{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2},{"negated":false,"variable":3}]}]},"evaluations":[{"is_valid":true,"config":[1,0,1,1],"size":3},{"is_valid":true,"config":[1,0,1,0],"size":3},{"is_valid":true,"config":[0,0,0,1],"size":2},{"is_valid":true,"config":[0,0,0,0],"size":2},{"is_valid":true,"config":[0,1,1,1],"size":2},{"is_valid":true,"config":[1,1,0,1],"size":2},{"is_valid":true,"config":[0,1,1,0],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":3},{"is_valid":true,"config":[1,1,1,1],"size":3}],"best_solutions":[[1,0,0,0],[1,0,1,0],[1,1,1,0],[1,0,0,1],[1,0,1,1],[1,1,1,1]]},{"label":"rule_sat01","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":true,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":true,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":3},{"is_valid":true,"config":[1,0,1],"size":3},{"is_valid":true,"config":[0,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":3},{"is_valid":true,"config":[0,0,0],"size":4},{"is_valid":true,"config":[1,1,1],"size":4},{"is_valid":true,"config":[0,1,1],"size":3},{"is_valid":true,"config":[1,1,0],"size":4}],"best_solutions":[[0,0,0],[1,1,0],[0,0,1],[1,1,1]]},{"label":"rule_sat02","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1},{"negated":true,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":3},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,0],"size":3},{"is_valid":true,"config":[1,1,1],"size":3},{"is_valid":true,"config":[1,1,0],"size":3},{"is_valid":true,"config":[0,1,1],"size":3}],"best_solutions":[[0,0,0],[1,1,0],[1,0,1],[0,1,1],[1,1,1]]},{"label":"rule_sat03","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":1},{"negated":true,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":2},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,0],"size":1},{"is_valid":true,"config":[1,1,1],"size":1},{"is_valid":true,"config":[0,1,1],"size":2},{"is_valid":true,"config":[1,1,0],"size":2}],"best_solutions":[[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1]]},{"label":"rule_sat04_unsat","instance":{"num_variables":1,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":0},{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":0},{"negated":true,"variable":0}]}]},"evaluations":[{"is_valid":true,"config":[1],"size":1},{"is_valid":true,"config":[0],"size":1}],"best_solutions":[[0],[1]]},{"label":"rule_sat05_unsat","instance":{"num_variables":1,"clauses":[{"literals":[{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":0}]}]},"evaluations":[{"is_valid":true,"config":[1],"size":1},{"is_valid":true,"config":[0],"size":1}],"best_solutions":[[0],[1]]},{"label":"rule_sat06_unsat","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":3},{"is_valid":true,"config":[1,1],"size":3},{"is_valid":true,"config":[1,0],"size":3},{"is_valid":true,"config":[0,1],"size":3}],"best_solutions":[[0,0],[1,0],[0,1],[1,1]]},{"label":"rule_sat07","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":2},{"is_valid":true,"config":[1,1],"size":3},{"is_valid":true,"config":[1,0],"size":2},{"is_valid":true,"config":[0,1],"size":2}],"best_solutions":[[1,1]]},{"label":"rule_sat_coloring","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":1},{"is_valid":true,"config":[1,1],"size":2},{"is_valid":true,"config":[1,0],"size":2},{"is_valid":true,"config":[0,1],"size":1}],"best_solutions":[[1,0],[1,1]]}],"problem_type":"Satisfiability"} \ No newline at end of file +{"instances":[{"label":"simple_clause","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":0},{"is_valid":true,"config":[1,1],"size":1},{"is_valid":true,"config":[1,0],"size":1},{"is_valid":true,"config":[0,1],"size":1}],"best_solutions":[[1,0],[0,1],[1,1]]},{"label":"rule_3sat_multi","instance":{"num_variables":4,"clauses":[{"literals":[{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2},{"negated":false,"variable":3}]}]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":3},{"is_valid":true,"config":[0,1,0,1],"size":1},{"is_valid":true,"config":[1,0,1,0],"size":3},{"is_valid":true,"config":[0,0,0,0],"size":2},{"is_valid":true,"config":[1,1,0,1],"size":2},{"is_valid":true,"config":[1,1,0,0],"size":2},{"is_valid":true,"config":[0,0,1,1],"size":2},{"is_valid":true,"config":[0,0,1,0],"size":2},{"is_valid":true,"config":[1,0,0,0],"size":3},{"is_valid":true,"config":[1,1,1,1],"size":3}],"best_solutions":[[1,0,0,0],[1,0,1,0],[1,1,1,0],[1,0,0,1],[1,0,1,1],[1,1,1,1]]},{"label":"rule_sat01","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":true,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":true,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":3},{"is_valid":true,"config":[1,0,1],"size":3},{"is_valid":true,"config":[0,0,1],"size":4},{"is_valid":true,"config":[1,0,0],"size":3},{"is_valid":true,"config":[0,0,0],"size":4},{"is_valid":true,"config":[1,1,1],"size":4},{"is_valid":true,"config":[1,1,0],"size":4},{"is_valid":true,"config":[0,1,1],"size":3}],"best_solutions":[[0,0,0],[1,1,0],[0,0,1],[1,1,1]]},{"label":"rule_sat02","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1},{"negated":true,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":3},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,0],"size":3},{"is_valid":true,"config":[1,1,1],"size":3},{"is_valid":true,"config":[0,1,1],"size":3},{"is_valid":true,"config":[1,1,0],"size":3}],"best_solutions":[[0,0,0],[1,1,0],[1,0,1],[0,1,1],[1,1,1]]},{"label":"rule_sat03","instance":{"num_variables":3,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1},{"negated":false,"variable":2}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":1},{"negated":true,"variable":2}]}]},"evaluations":[{"is_valid":true,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":2},{"is_valid":true,"config":[0,0,1],"size":2},{"is_valid":true,"config":[1,0,0],"size":2},{"is_valid":true,"config":[0,0,0],"size":1},{"is_valid":true,"config":[1,1,1],"size":1},{"is_valid":true,"config":[0,1,1],"size":2},{"is_valid":true,"config":[1,1,0],"size":2}],"best_solutions":[[1,0,0],[0,1,0],[1,1,0],[0,0,1],[1,0,1],[0,1,1]]},{"label":"rule_sat04_unsat","instance":{"num_variables":1,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":0},{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":0},{"negated":true,"variable":0}]}]},"evaluations":[{"is_valid":true,"config":[1],"size":1},{"is_valid":true,"config":[0],"size":1}],"best_solutions":[[0],[1]]},{"label":"rule_sat05_unsat","instance":{"num_variables":1,"clauses":[{"literals":[{"negated":false,"variable":0}]},{"literals":[{"negated":true,"variable":0}]}]},"evaluations":[{"is_valid":true,"config":[1],"size":1},{"is_valid":true,"config":[0],"size":1}],"best_solutions":[[0],[1]]},{"label":"rule_sat06_unsat","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":true,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":3},{"is_valid":true,"config":[1,1],"size":3},{"is_valid":true,"config":[1,0],"size":3},{"is_valid":true,"config":[0,1],"size":3}],"best_solutions":[[0,0],[1,0],[0,1],[1,1]]},{"label":"rule_sat07","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]},{"literals":[{"negated":true,"variable":0},{"negated":false,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":2},{"is_valid":true,"config":[1,1],"size":3},{"is_valid":true,"config":[1,0],"size":2},{"is_valid":true,"config":[0,1],"size":2}],"best_solutions":[[1,1]]},{"label":"rule_sat_coloring","instance":{"num_variables":2,"clauses":[{"literals":[{"negated":false,"variable":0},{"negated":false,"variable":1}]},{"literals":[{"negated":false,"variable":0},{"negated":true,"variable":1}]}]},"evaluations":[{"is_valid":true,"config":[0,0],"size":1},{"is_valid":true,"config":[1,1],"size":2},{"is_valid":true,"config":[1,0],"size":2},{"is_valid":true,"config":[0,1],"size":1}],"best_solutions":[[1,0],[1,1]]}],"problem_type":"Satisfiability"} \ No newline at end of file diff --git a/tests/data/jl/satisfiability_to_independentset.json b/tests/data/jl/satisfiability_to_independentset.json index 57a35944..64d81eef 100644 --- a/tests/data/jl/satisfiability_to_independentset.json +++ b/tests/data/jl/satisfiability_to_independentset.json @@ -1 +1 @@ -{"target_type":"IndependentSet","cases":[{"label":"sat_is","extracted_single":[[1,1],[0,1]],"extracted_multiple":[[1,0],[1,1],[0,1]],"best_source":[[1,0],[0,1],[1,1]],"best_target":[[1,0],[0,1]]}],"source_type":"Satisfiability"} \ No newline at end of file +{"target_type":"IndependentSet","cases":[{"label":"sat_is","extracted_single":[[1,0],[1,1]],"extracted_multiple":[[1,0],[1,1],[0,1]],"best_source":[[1,0],[0,1],[1,1]],"best_target":[[1,0],[0,1]]}],"source_type":"Satisfiability"} \ No newline at end of file diff --git a/tests/data/jl/setcovering.json b/tests/data/jl/setcovering.json index ca2c3b25..b5013457 100644 --- a/tests/data/jl/setcovering.json +++ b/tests/data/jl/setcovering.json @@ -1 +1 @@ -{"instances":[{"label":"doc_3subsets","instance":{"universe_size":4,"sets":[[0,1,2],[1,3],[0,3]],"weights":[1,2,3]},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":false,"config":[0,0,1],"size":3},{"is_valid":false,"config":[1,0,0],"size":1},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":6},{"is_valid":false,"config":[0,1,1],"size":5},{"is_valid":true,"config":[1,1,0],"size":3}],"best_solutions":[[1,1,0]]}],"problem_type":"SetCovering"} \ No newline at end of file +{"instances":[{"label":"doc_3subsets","instance":{"universe_size":4,"sets":[[0,1,2],[1,3],[0,3]],"weights":[1,2,3]},"evaluations":[{"is_valid":false,"config":[0,1,0],"size":2},{"is_valid":true,"config":[1,0,1],"size":4},{"is_valid":false,"config":[0,0,1],"size":3},{"is_valid":false,"config":[1,0,0],"size":1},{"is_valid":false,"config":[0,0,0],"size":0},{"is_valid":true,"config":[1,1,1],"size":6},{"is_valid":true,"config":[1,1,0],"size":3},{"is_valid":false,"config":[0,1,1],"size":5}],"best_solutions":[[1,1,0]]}],"problem_type":"SetCovering"} \ No newline at end of file diff --git a/tests/data/jl/setpacking.json b/tests/data/jl/setpacking.json index 1d6e6579..d2c18cf4 100644 --- a/tests/data/jl/setpacking.json +++ b/tests/data/jl/setpacking.json @@ -1 +1 @@ -{"instances":[{"label":"five_sets","instance":{"sets":[[0,1,4],[0,2],[1,3],[2,5],[1,2,5]],"weights":[1,1,1,1,1]},"evaluations":[{"is_valid":true,"config":[0,0,0,0,0],"size":0},{"is_valid":false,"config":[1,1,1,0,0],"size":3},{"is_valid":true,"config":[0,1,1,0,0],"size":2},{"is_valid":false,"config":[1,1,0,0,0],"size":2},{"is_valid":false,"config":[1,1,1,1,1],"size":5},{"is_valid":true,"config":[0,0,0,1,0],"size":1},{"is_valid":false,"config":[1,1,1,1,0],"size":4},{"is_valid":false,"config":[0,1,0,1,1],"size":3},{"is_valid":false,"config":[0,0,1,0,1],"size":2},{"is_valid":true,"config":[1,0,0,0,0],"size":1}],"best_solutions":[[0,1,1,0,0],[1,0,0,1,0],[0,0,1,1,0]]}],"problem_type":"SetPacking"} \ No newline at end of file +{"instances":[{"label":"five_sets","instance":{"sets":[[0,1,4],[0,2],[1,3],[2,5],[1,2,5]],"weights":[1,1,1,1,1]},"evaluations":[{"is_valid":true,"config":[0,0,0,0,0],"size":0},{"is_valid":false,"config":[1,0,1,1,1],"size":4},{"is_valid":false,"config":[0,0,1,1,1],"size":3},{"is_valid":false,"config":[1,1,1,0,0],"size":3},{"is_valid":true,"config":[0,0,1,1,0],"size":2},{"is_valid":false,"config":[1,1,1,1,1],"size":5},{"is_valid":true,"config":[0,0,0,1,0],"size":1},{"is_valid":false,"config":[0,1,0,1,1],"size":3},{"is_valid":false,"config":[1,0,1,0,1],"size":3},{"is_valid":true,"config":[0,0,1,0,0],"size":1}],"best_solutions":[[0,1,1,0,0],[1,0,0,1,0],[0,0,1,1,0]]}],"problem_type":"SetPacking"} \ No newline at end of file diff --git a/tests/data/jl/spinglass.json b/tests/data/jl/spinglass.json index 7a59c2bf..bd08b167 100644 --- a/tests/data/jl/spinglass.json +++ b/tests/data/jl/spinglass.json @@ -1 +1 @@ -{"instances":[{"label":"petersen","instance":{"J":[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1],"num_vertices":10,"edges":[[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]],"h":[0,0,0,0,0,0,0,0,0,0]},"evaluations":[{"is_valid":true,"config":[0,1,0,1,0,1,1,0,1,1],"size":-2},{"is_valid":true,"config":[1,0,0,1,0,1,0,0,1,0],"size":4},{"is_valid":true,"config":[1,1,0,0,0,0,1,0,0,0],"size":6},{"is_valid":true,"config":[0,0,0,0,1,0,1,0,0,1],"size":8},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":22},{"is_valid":true,"config":[0,1,1,1,0,1,0,0,0,0],"size":2},{"is_valid":true,"config":[0,1,0,1,0,1,1,1,1,1],"size":0},{"is_valid":true,"config":[1,0,1,0,1,0,0,1,0,0],"size":-2},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":22},{"is_valid":true,"config":[0,1,1,1,0,1,1,1,0,0],"size":0}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,1,0,1,0,0,0,1,1,1]]},{"label":"doc_4vertex","instance":{"J":[1,-1,1,-1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]],"h":[1,-1,-1,1]},"evaluations":[{"is_valid":true,"config":[1,0,1,1],"size":-6},{"is_valid":true,"config":[1,1,1,0],"size":4},{"is_valid":true,"config":[0,1,0,1],"size":-2},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,1],"size":0},{"is_valid":true,"config":[0,1,1,1],"size":2},{"is_valid":true,"config":[0,0,1,1],"size":0},{"is_valid":true,"config":[0,1,1,0],"size":6},{"is_valid":true,"config":[0,0,1,0],"size":4},{"is_valid":true,"config":[1,1,1,1],"size":0}],"best_solutions":[[1,0,1,1]]},{"label":"rule_4vertex","instance":{"J":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]],"h":[0,0,0,0]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":1},{"is_valid":true,"config":[1,0,1,1],"size":5},{"is_valid":true,"config":[0,1,0,1],"size":-3},{"is_valid":true,"config":[1,0,1,0],"size":-3},{"is_valid":true,"config":[0,1,0,0],"size":5},{"is_valid":true,"config":[0,0,0,0],"size":9},{"is_valid":true,"config":[0,1,1,0],"size":-7},{"is_valid":true,"config":[1,1,0,0],"size":1},{"is_valid":true,"config":[0,0,1,1],"size":1},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[0,0,1,0],[0,1,1,0],[1,0,0,1],[1,1,0,1]]}],"problem_type":"SpinGlass"} \ No newline at end of file +{"instances":[{"label":"petersen","instance":{"J":[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1],"num_vertices":10,"edges":[[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]],"h":[0,0,0,0,0,0,0,0,0,0]},"evaluations":[{"is_valid":true,"config":[1,0,0,1,1,0,0,0,0,1],"size":6},{"is_valid":true,"config":[0,1,1,1,0,0,1,1,1,1],"size":6},{"is_valid":true,"config":[0,0,1,0,0,0,1,0,0,0],"size":4},{"is_valid":true,"config":[0,0,0,1,1,0,1,1,1,1],"size":4},{"is_valid":true,"config":[1,1,0,0,1,1,1,0,0,0],"size":-2},{"is_valid":true,"config":[0,0,1,1,1,0,1,0,0,1],"size":4},{"is_valid":true,"config":[0,0,0,0,0,0,0,0,0,0],"size":22},{"is_valid":true,"config":[1,0,1,0,0,1,0,0,1,1],"size":-10},{"is_valid":true,"config":[0,0,1,0,1,1,1,1,1,1],"size":0},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":22}],"best_solutions":[[0,0,1,0,1,1,1,0,0,0],[1,1,0,1,0,0,0,1,1,1]]},{"label":"doc_4vertex","instance":{"J":[1,-1,1,-1],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]],"h":[1,-1,-1,1]},"evaluations":[{"is_valid":true,"config":[1,0,1,1],"size":-6},{"is_valid":true,"config":[1,1,1,0],"size":4},{"is_valid":true,"config":[0,1,0,1],"size":-2},{"is_valid":true,"config":[0,1,0,0],"size":-2},{"is_valid":true,"config":[0,0,0,1],"size":0},{"is_valid":true,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,1],"size":0},{"is_valid":true,"config":[1,1,0,0],"size":0},{"is_valid":true,"config":[0,0,1,0],"size":4},{"is_valid":true,"config":[1,1,1,1],"size":0}],"best_solutions":[[1,0,1,1]]},{"label":"rule_4vertex","instance":{"J":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]],"h":[0,0,0,0]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":1},{"is_valid":true,"config":[0,1,0,1],"size":-3},{"is_valid":true,"config":[1,0,1,0],"size":-3},{"is_valid":true,"config":[0,1,0,0],"size":5},{"is_valid":true,"config":[0,0,0,1],"size":1},{"is_valid":true,"config":[0,0,0,0],"size":9},{"is_valid":true,"config":[0,1,1,1],"size":1},{"is_valid":true,"config":[0,0,1,1],"size":1},{"is_valid":true,"config":[1,1,0,0],"size":1},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[0,0,1,0],[0,1,1,0],[1,0,0,1],[1,1,0,1]]}],"problem_type":"SpinGlass"} \ No newline at end of file diff --git a/tests/data/jl/vertexcovering.json b/tests/data/jl/vertexcovering.json index a46341eb..1fe4214e 100644 --- a/tests/data/jl/vertexcovering.json +++ b/tests/data/jl/vertexcovering.json @@ -1 +1 @@ -{"instances":[{"label":"petersen","instance":{"weights":[1,2,1,2,1,2,1,2,1,2],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[1,0,0,0,1,0,1,1,1,0],"size":6},{"is_valid":false,"config":[0,0,1,0,1,1,0,1,0,0],"size":6},{"is_valid":true,"config":[1,1,0,1,0,1,1,1,1,1],"size":13},{"is_valid":false,"config":[1,0,1,0,0,1,0,0,0,0],"size":4},{"is_valid":false,"config":[0,0,1,0,1,0,1,0,1,0],"size":4},{"is_valid":false,"config":[0,0,1,0,1,1,0,1,1,1],"size":9},{"is_valid":false,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":false,"config":[1,0,1,0,0,1,1,0,0,0],"size":5},{"is_valid":false,"config":[0,1,1,1,0,0,0,0,0,0],"size":5},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":15}],"best_solutions":[[1,0,1,0,1,0,1,1,1,0]]},{"label":"doc_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[0,3],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,0,1,1],"size":6},{"is_valid":true,"config":[1,1,1,0],"size":5},{"is_valid":false,"config":[0,1,0,1],"size":7},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[0,1,1,1],"size":8},{"is_valid":true,"config":[1,1,0,1],"size":8},{"is_valid":false,"config":[0,0,1,1],"size":5},{"is_valid":false,"config":[1,0,0,1],"size":5},{"is_valid":false,"config":[1,0,0,0],"size":1},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[1,0,1,0]]},{"label":"rule_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":5},{"is_valid":false,"config":[0,1,0,1],"size":7},{"is_valid":false,"config":[0,0,0,1],"size":4},{"is_valid":false,"config":[0,1,0,0],"size":3},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,0,1],"size":8},{"is_valid":true,"config":[0,1,1,0],"size":4},{"is_valid":false,"config":[1,0,0,0],"size":1},{"is_valid":false,"config":[0,0,1,0],"size":1},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[1,0,1,0]]}],"problem_type":"VertexCovering"} \ No newline at end of file +{"instances":[{"label":"petersen","instance":{"weights":[1,2,1,2,1,2,1,2,1,2],"num_vertices":10,"edges":[[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]]},"evaluations":[{"is_valid":false,"config":[0,0,0,1,1,1,1,0,0,1],"size":8},{"is_valid":false,"config":[0,1,1,0,0,0,0,1,1,1],"size":8},{"is_valid":false,"config":[1,0,0,0,0,1,0,1,1,0],"size":6},{"is_valid":false,"config":[0,0,0,1,1,1,1,1,1,1],"size":11},{"is_valid":false,"config":[0,0,0,1,1,0,1,1,1,1],"size":9},{"is_valid":false,"config":[1,0,1,0,1,0,1,0,1,1],"size":7},{"is_valid":false,"config":[0,1,0,1,1,1,0,1,0,0],"size":9},{"is_valid":false,"config":[0,0,0,0,0,0,0,0,0,0],"size":0},{"is_valid":true,"config":[1,1,1,1,1,1,1,1,1,1],"size":15},{"is_valid":false,"config":[1,0,1,1,1,0,1,0,0,1],"size":8}],"best_solutions":[[1,0,1,0,1,0,1,1,1,0]]},{"label":"doc_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[0,3],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":5},{"is_valid":true,"config":[1,0,1,1],"size":6},{"is_valid":true,"config":[1,0,1,0],"size":2},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[0,1,1,1],"size":8},{"is_valid":false,"config":[1,1,0,0],"size":4},{"is_valid":false,"config":[1,0,0,1],"size":5},{"is_valid":false,"config":[1,0,0,0],"size":1},{"is_valid":false,"config":[0,0,1,0],"size":1},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[1,0,1,0]]},{"label":"rule_4vertex","instance":{"weights":[1,3,1,4],"num_vertices":4,"edges":[[0,1],[0,2],[1,2],[2,3]]},"evaluations":[{"is_valid":true,"config":[1,1,1,0],"size":5},{"is_valid":true,"config":[1,0,1,1],"size":6},{"is_valid":false,"config":[0,1,0,1],"size":7},{"is_valid":false,"config":[0,0,0,0],"size":0},{"is_valid":true,"config":[0,1,1,1],"size":8},{"is_valid":false,"config":[1,1,0,0],"size":4},{"is_valid":true,"config":[0,1,1,0],"size":4},{"is_valid":false,"config":[0,0,1,0],"size":1},{"is_valid":false,"config":[0,0,1,1],"size":5},{"is_valid":true,"config":[1,1,1,1],"size":9}],"best_solutions":[[1,0,1,0]]}],"problem_type":"VertexCovering"} \ No newline at end of file diff --git a/tests/suites/examples.rs b/tests/suites/examples.rs index 8e665488..6658d056 100644 --- a/tests/suites/examples.rs +++ b/tests/suites/examples.rs @@ -10,6 +10,7 @@ macro_rules! example_test { }; } +example_test!(chained_reduction_factoring_to_spinglass); example_test!(chained_reduction_ksat_to_mis); example_test!(reduction_circuitsat_to_spinglass); example_test!(reduction_factoring_to_circuitsat); @@ -52,6 +53,10 @@ macro_rules! example_fn { }; } +example_fn!( + test_chained_reduction_factoring_to_spinglass, + chained_reduction_factoring_to_spinglass +); example_fn!( test_chained_reduction_ksat_to_mis, chained_reduction_ksat_to_mis