Skip to content

Commit

Permalink
port ProblemReductions
Browse files Browse the repository at this point in the history
  • Loading branch information
GiggleLiu committed Nov 27, 2024
1 parent c59325e commit 6db3c3c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 14 deletions.
6 changes: 3 additions & 3 deletions src/dragondrop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function post_process_grid(grid::Matrix{SimpleCell{T}}, h0, h1) where T
return gg, pins
end

struct QUBOResult{NT}
struct QUBOResult{NT} <: ProblemReductions.AbstractReductionResult
grid_graph::GridGraph{NT}
pins::Vector{Int}
mis_overhead::Int
Expand All @@ -353,13 +353,13 @@ function map_config_back(res::WMISResult, cfg)
return cfg[res.pins]
end

struct RestrictedQUBOResult{NT}
struct RestrictedQUBOResult{NT} <: ProblemReductions.AbstractReductionResult
grid_graph::GridGraph{NT}
end
function map_config_back(res::RestrictedQUBOResult, cfg)
end

struct SquareQUBOResult{NT}
struct SquareQUBOResult{NT} <: ProblemReductions.AbstractReductionResult
grid_graph::GridGraph{NT}
pins::Vector{Int}
mis_overhead::Float64
Expand Down
60 changes: 53 additions & 7 deletions src/reduceto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ struct IndependentSetToKSG{NT, VT} <: ProblemReductions.AbstractReductionResult
weights::VT
end
function _to_gridgraph(g::UnitDiskMapping.GridGraph)
return ProblemReductions.GridGraph(g.size, getfield.(g.nodes, :loc), g.radius)
return ProblemReductions.GridGraph(getfield.(g.nodes, :loc), g.radius)
end
function _extract_weights(g::UnitDiskMapping.GridGraph{<:WeightedNode})
getfield.(g.nodes, :weight)
end

###### unweighted reduction
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, ProblemReductions.UnitWeight}}, problem::ProblemReductions.IndependentSet{GT, Int, ProblemReductions.UnitWeight} where GT<:SimpleGraph)
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

Expand All @@ -23,7 +23,7 @@ end

###### Weighted reduction
# TODO: rescale the weights to avoid errors
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, T, Vector{T}}} where T, problem::ProblemReductions.IndependentSet{GT} where GT<:SimpleGraph)
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, T, Vector{T}}} where T, problem::ProblemReductions.IndependentSet{GT} where GT<:SimpleGraph)
return IndependentSetToKSG(map_graph(Weighted(), problem.graph), problem.weights)
end
function ProblemReductions.target_problem(res::IndependentSetToKSG{<:WeightedNode})
Expand All @@ -35,12 +35,12 @@ end
###### Factoring ######
struct FactoringToIndependentSet{NT} <: ProblemReductions.AbstractReductionResult
mapres::FactoringResult{NT}
raw_graph::ProblemReductions.GridGraph
raw_graph::ProblemReductions.GridGraph{2}
raw_weight::Vector{Int}
vmap::Vector{Int}
problem::ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, Vector{Int}}
problem::ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int, Vector{Int}}
end
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, T, Vector{T}}} where T, problem::ProblemReductions.Factoring)
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, T, Vector{T}}} where T, problem::ProblemReductions.Factoring)
mres = map_factoring(problem.m, problem.n)
g = _to_gridgraph(mres.grid_graph)
ws = getfield.(mres.grid_graph.nodes, :weight)
Expand All @@ -57,4 +57,50 @@ function ProblemReductions.extract_solution(res::FactoringToIndependentSet, sol)
cfg[res.vmap] .= sol
i1, i2 = map_config_back(res.mapres, cfg)
return vcat([i1>>(k-1) & 1 for k=1:length(res.mapres.pins_input1)], [i2>>(k-1) & 1 for k=1:length(res.mapres.pins_input2)])
end
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!
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)
end

function ProblemReductions.target_problem(res::QUBOResult)
grid = _to_gridgraph(res.grid_graph)
ws = getfield.(res.grid_graph.nodes, :weight)
return ProblemReductions.IndependentSet(grid, ws)
end

function ProblemReductions.extract_solution(res::QUBOResult, sol)
res = map_config_back(res, 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
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"
coupling = [(g.locations[e.src]..., g.locations[e.dst]..., J) for (e, J) in zip(edges(g), problem.J)]
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)
end

function ProblemReductions.target_problem(res::SquareQUBOResult)
grid = _to_gridgraph(res.grid_graph)
ws = getfield.(res.grid_graph.nodes, :weight)
return ProblemReductions.IndependentSet(grid, ws)
end

function ProblemReductions.extract_solution(res::SquareQUBOResult, sol)
res = map_config_back(res, sol)
return 1 .- 2 .* Int.(res)
end

16 changes: 12 additions & 4 deletions test/reduceto.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ import ProblemReductions
fact = ProblemReductions.Factoring(2, 1, 2)
is = ProblemReductions.IndependentSet(graph)
wis = ProblemReductions.IndependentSet(graph, rand(nv(graph)) .* 0.2)
sg = ProblemReductions.SpinGlass(graph, [0.2, 0.4, -0.6], [0.1, 0.1, 0.1])
sg2 = ProblemReductions.SpinGlass(graph, [0.1, 0.1, -0.1], [0.1, 0.1, 0.1])
grid = ProblemReductions.GridGraph(ones(Bool, 2, 2), 1.2)
sg_square = ProblemReductions.SpinGlass(grid, [0.1, 0.3, -0.1, 0.4], [0.1, 0.1, 0.1, 0.2])
sg_square2 = ProblemReductions.SpinGlass(grid, [0.1, -0.3, 0.1, 0.4], [0.1, 0.1, 0.1, 0.2])
for (source, target_type) in [
# please add more tests here
is => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, ProblemReductions.UnitWeight},
wis => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Float64, Vector{Float64}},
fact => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, Vector{Int}},
sg_square => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Float64, Vector{Float64}},
sg_square2 => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Float64, Vector{Float64}},
sg => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Float64, Vector{Float64}},
sg2 => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Float64, Vector{Float64}},
is => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int, ProblemReductions.UnitWeight},
wis => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Float64, Vector{Float64}},
fact => ProblemReductions.IndependentSet{ProblemReductions.GridGraph{2}, Int, Vector{Int}},
]
@info "Testing reduction from $(typeof(source)) to $(target_type)"
# directly solve
Expand Down

0 comments on commit 6db3c3c

Please sign in to comment.