From c1a8c68e0b5c53ec43eeefc6d6d7031f410c79e6 Mon Sep 17 00:00:00 2001 From: GiggleLiu Date: Wed, 27 Nov 2024 10:32:54 +0100 Subject: [PATCH] make problemreductions an extension --- Project.toml | 8 +++- .../ProblemReductionsExt.jl | 48 ++++++++++++------- src/UnitDiskMapping.jl | 3 -- src/dragondrop.jl | 6 +-- 4 files changed, 40 insertions(+), 25 deletions(-) rename src/reduceto.jl => ext/ProblemReductionsExt.jl (76%) diff --git a/Project.toml b/Project.toml index fd35266..c7690b6 100644 --- a/Project.toml +++ b/Project.toml @@ -6,11 +6,17 @@ version = "0.4.0" [deps] Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" LuxorGraphPlot = "1f49bdf2-22a7-4bc4-978b-948dc219fbbc" + +[weakdeps] ProblemReductions = "899c297d-f7d2-4ebf-8815-a35996def416" +[extensions] +ProblemReductionsExt = "ProblemReductions" + [compat] Graphs = "1.6" LuxorGraphPlot = "0.5" +ProblemReductions = "0.1.1" julia = "1" [extras] @@ -20,4 +26,4 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test", "Random", "GenericTensorNetworks", "LinearAlgebra"] +test = ["Test", "Random", "GenericTensorNetworks", "LinearAlgebra", "ProblemReductions"] diff --git a/src/reduceto.jl b/ext/ProblemReductionsExt.jl similarity index 76% rename from src/reduceto.jl rename to ext/ProblemReductionsExt.jl index 5cd1079..a730bf1 100644 --- a/src/reduceto.jl +++ b/ext/ProblemReductionsExt.jl @@ -1,7 +1,9 @@ -struct IndependentSetToKSG{NT, VT} <: ProblemReductions.AbstractReductionResult - mapres::MappingResult{NT} - weights::VT -end +module ProblemReductionsExt + +using UnitDiskMapping, UnitDiskMapping.Graphs +import ProblemReductions: reduceto, target_problem, extract_multiple_solutions +import ProblemReductions + function _to_gridgraph(g::UnitDiskMapping.GridGraph) return ProblemReductions.GridGraph(getfield.(g.nodes, :loc), g.radius) end @@ -10,6 +12,10 @@ function _extract_weights(g::UnitDiskMapping.GridGraph{<:WeightedNode}) end ###### unweighted reduction +struct IndependentSetToKSG{NT, VT} <: ProblemReductions.AbstractReductionResult + mapres::MappingResult{NT} + weights::VT +end function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int, ProblemReductions.UnitWeight}}, problem::ProblemReductions.IndependentSet{GT, Int, ProblemReductions.UnitWeight} where GT<:SimpleGraph) return IndependentSetToKSG(map_graph(UnWeighted(), problem.graph), problem.weights) end @@ -44,7 +50,7 @@ function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{Prob mres = map_factoring(problem.m, problem.n) g = _to_gridgraph(mres.grid_graph) ws = getfield.(mres.grid_graph.nodes, :weight) - mg, vmap = set_target(g, [mres.pins_zeros..., mres.pins_output...], problem.input << length(mres.pins_zeros)) + mg, vmap = UnitDiskMapping.set_target(g, [mres.pins_zeros..., mres.pins_output...], problem.input << length(mres.pins_zeros)) return FactoringToIndependentSet(mres, g, ws, vmap, ProblemReductions.IndependentSet(mg, ws[vmap])) end @@ -61,28 +67,34 @@ end ###### Spinglass problem to MIS on KSG ###### # NOTE: I am not sure about the correctness of this reduction. If you encounter a bug, please question this function! +struct SpinGlassToIndependentSet{NT} <: ProblemReductions.AbstractReductionResult + mapres::QUBOResult{NT} +end function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, T, Vector{T}}} where T, problem::ProblemReductions.SpinGlass{<:SimpleGraph}) n = length(problem.h) M = similar(problem.h, n, n) for (e, j) in zip(edges(problem.graph), problem.J) M[e.src, e.dst] = M[e.dst, e.src] = j end - return map_qubo(M, -problem.h) + return SpinGlassToIndependentSet(map_qubo(M, -problem.h)) end -function ProblemReductions.target_problem(res::QUBOResult) - grid = _to_gridgraph(res.grid_graph) - ws = getfield.(res.grid_graph.nodes, :weight) +function ProblemReductions.target_problem(res::SpinGlassToIndependentSet) + grid = _to_gridgraph(res.mapres.grid_graph) + ws = getfield.(res.mapres.grid_graph.nodes, :weight) return ProblemReductions.IndependentSet(grid, ws) end -function ProblemReductions.extract_solution(res::QUBOResult, sol) - res = map_config_back(res, sol) +function ProblemReductions.extract_solution(res::SpinGlassToIndependentSet, sol) + res = map_config_back(res.mapres, sol) return 1 .- 2 .* Int.(res) end ###### Spinglass problem on grid to MIS on KSG ###### # NOTE: the restricted layout is not implemented, since it is not often used +struct SquareSpinGlassToIndependentSet{NT} <: ProblemReductions.AbstractReductionResult + mapres::SquareQUBOResult{NT} +end function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, T, Vector{T}}} where T, problem::ProblemReductions.SpinGlass{ProblemReductions.GridGraph{2}}) g = problem.graph @assert 1 <= g.radius < sqrt(2) "Only support nearest neighbor interaction" @@ -90,17 +102,17 @@ function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{Prob onsite = [(i, j, -h) for ((i, j), h) in zip(g.locations, problem.h)] # a vector coupling of `(i, j, i', j', J)`, s.t. (i', j') == (i, j+1) or (i', j') = (i+1, j). # a vector of onsite term `(i, j, h)`. - return map_qubo_square(coupling, onsite) + return SquareSpinGlassToIndependentSet(map_qubo_square(coupling, onsite)) end -function ProblemReductions.target_problem(res::SquareQUBOResult) - grid = _to_gridgraph(res.grid_graph) - ws = getfield.(res.grid_graph.nodes, :weight) +function ProblemReductions.target_problem(res::SquareSpinGlassToIndependentSet) + grid = _to_gridgraph(res.mapres.grid_graph) + ws = getfield.(res.mapres.grid_graph.nodes, :weight) return ProblemReductions.IndependentSet(grid, ws) end -function ProblemReductions.extract_solution(res::SquareQUBOResult, sol) - res = map_config_back(res, sol) +function ProblemReductions.extract_solution(res::SquareSpinGlassToIndependentSet, sol) + res = map_config_back(res.mapres, sol) return 1 .- 2 .* Int.(res) end - \ No newline at end of file +end \ No newline at end of file diff --git a/src/UnitDiskMapping.jl b/src/UnitDiskMapping.jl index ba1d0fe..628f921 100644 --- a/src/UnitDiskMapping.jl +++ b/src/UnitDiskMapping.jl @@ -5,8 +5,6 @@ module UnitDiskMapping using Graphs using LuxorGraphPlot using LuxorGraphPlot.Luxor.Colors -import ProblemReductions: reduceto, target_problem, extract_multiple_solutions -import ProblemReductions # Basic types export UnWeighted, Weighted @@ -55,7 +53,6 @@ include("mapping.jl") include("weighted.jl") include("simplifiers.jl") include("extracting_results.jl") -include("reduceto.jl") include("visualize.jl") end diff --git a/src/dragondrop.jl b/src/dragondrop.jl index 66fd3bc..8d9e2ec 100644 --- a/src/dragondrop.jl +++ b/src/dragondrop.jl @@ -335,7 +335,7 @@ function post_process_grid(grid::Matrix{SimpleCell{T}}, h0, h1) where T return gg, pins end -struct QUBOResult{NT} <: ProblemReductions.AbstractReductionResult +struct QUBOResult{NT} grid_graph::GridGraph{NT} pins::Vector{Int} mis_overhead::Int @@ -353,13 +353,13 @@ function map_config_back(res::WMISResult, cfg) return cfg[res.pins] end -struct RestrictedQUBOResult{NT} <: ProblemReductions.AbstractReductionResult +struct RestrictedQUBOResult{NT} grid_graph::GridGraph{NT} end function map_config_back(res::RestrictedQUBOResult, cfg) end -struct SquareQUBOResult{NT} <: ProblemReductions.AbstractReductionResult +struct SquareQUBOResult{NT} grid_graph::GridGraph{NT} pins::Vector{Int} mis_overhead::Float64