Skip to content

Commit c59325e

Browse files
committed
port to ProblemReductions.jl, tests all pass
1 parent 523546d commit c59325e

File tree

6 files changed

+88
-24
lines changed

6 files changed

+88
-24
lines changed

src/Core.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ function Graphs.SimpleGraph(grid::GridGraph{Node{ONE}})
7676
return unit_disk_graph(getfield.(grid.nodes, :loc), grid.radius)
7777
end
7878
coordinates(grid::GridGraph) = getfield.(grid.nodes, :loc)
79+
function Graphs.neighbors(g::GridGraph, i::Int)
80+
[j for j in 1:nv(g) if i != j && distance(g.nodes[i], g.nodes[j]) <= g.radius]
81+
end
82+
distance(n1::Node, n2::Node) = sqrt(sum(abs2, n1.loc .- n2.loc))
83+
Graphs.nv(g::GridGraph) = length(g.nodes)
84+
Graphs.vertices(g::GridGraph) = 1:nv(g)
7985

8086
# printing function for Grid graphs
8187
function print_grid(io::IO, grid::GridGraph{Node{WT}}; show_weight=false) where WT

src/multiplier.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ function map_factoring(M::Int, N::Int)
9797
[pinloc(1, j, 1) for j=1:N]...,
9898
[pinloc(i, N, 4) for i=1:M]...,
9999
]
100-
return FactoringResult(gg, pp, pq, pm, p0)
100+
return FactoringResult(gg, pq, pp, pm, p0)
101101
end
102102

103103
struct FactoringResult{NT}
@@ -131,7 +131,7 @@ function solve_factoring(missolver, mres::FactoringResult, target::Int)
131131
return map_config_back(mres, cfg)
132132
end
133133

134-
function set_target(g::SimpleGraph, pins::AbstractVector, target::Int)
134+
function set_target(g, pins::AbstractVector, target::Int)
135135
vs = collect(vertices(g))
136136
for (i, p) in enumerate(pins)
137137
bitval = (target >> (i-1)) & 1

src/reduceto.jl

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,60 @@
1-
struct IndependentSetKSGResult{NT, VT} <: ProblemReductions.AbstractReductionResult
1+
struct IndependentSetToKSG{NT, VT} <: ProblemReductions.AbstractReductionResult
22
mapres::MappingResult{NT}
33
weights::VT
44
end
5+
function _to_gridgraph(g::UnitDiskMapping.GridGraph)
6+
return ProblemReductions.GridGraph(g.size, getfield.(g.nodes, :loc), g.radius)
7+
end
8+
function _extract_weights(g::UnitDiskMapping.GridGraph{<:WeightedNode})
9+
getfield.(g.nodes, :weight)
10+
end
511

6-
# unweighted reduction
12+
###### unweighted reduction
713
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, ProblemReductions.UnitWeight}}, problem::ProblemReductions.IndependentSet{GT, Int, ProblemReductions.UnitWeight} where GT<:SimpleGraph)
8-
return IndependentSetKSGResult(map_graph(UnWeighted(), problem.graph), problem.weights)
14+
return IndependentSetToKSG(map_graph(UnWeighted(), problem.graph), problem.weights)
915
end
1016

11-
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, T, Vector{T}}} where T, problem::ProblemReductions.IndependentSet{GT} where GT<:SimpleGraph)
12-
return IndependentSetKSGResult(map_graph(Weighted(), problem.graph), problem.weights)
17+
function ProblemReductions.target_problem(res::IndependentSetToKSG{<:UnWeightedNode})
18+
return ProblemReductions.IndependentSet(_to_gridgraph(res.mapres.grid_graph))
19+
end
20+
function ProblemReductions.extract_solution(res::IndependentSetToKSG, sol)
21+
return map_config_back(res.mapres, sol)
1322
end
1423

15-
function ProblemReductions.target_problem(res::IndependentSetKSGResult{<:UnWeightedNode})
16-
return ProblemReductions.IndependentSet(SimpleGraph(res.mapres.grid_graph))
24+
###### Weighted reduction
25+
# TODO: rescale the weights to avoid errors
26+
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, T, Vector{T}}} where T, problem::ProblemReductions.IndependentSet{GT} where GT<:SimpleGraph)
27+
return IndependentSetToKSG(map_graph(Weighted(), problem.graph), problem.weights)
1728
end
18-
function ProblemReductions.target_problem(res::IndependentSetKSGResult{<:WeightedNode})
19-
graph, _ = graph_and_weights(res.mapres.grid_graph)
29+
function ProblemReductions.target_problem(res::IndependentSetToKSG{<:WeightedNode})
30+
graph = _to_gridgraph(res.mapres.grid_graph)
2031
weights = UnitDiskMapping.map_weights(res.mapres, res.weights)
2132
return ProblemReductions.IndependentSet(graph, weights)
2233
end
2334

24-
function ProblemReductions.extract_solution(res::IndependentSetKSGResult, sol)
25-
return map_config_back(res.mapres, sol)
35+
###### Factoring ######
36+
struct FactoringToIndependentSet{NT} <: ProblemReductions.AbstractReductionResult
37+
mapres::FactoringResult{NT}
38+
raw_graph::ProblemReductions.GridGraph
39+
raw_weight::Vector{Int}
40+
vmap::Vector{Int}
41+
problem::ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, Vector{Int}}
42+
end
43+
function ProblemReductions.reduceto(::Type{ProblemReductions.IndependentSet{ProblemReductions.GridGraph, T, Vector{T}}} where T, problem::ProblemReductions.Factoring)
44+
mres = map_factoring(problem.m, problem.n)
45+
g = _to_gridgraph(mres.grid_graph)
46+
ws = getfield.(mres.grid_graph.nodes, :weight)
47+
mg, vmap = set_target(g, [mres.pins_zeros..., mres.pins_output...], problem.input << length(mres.pins_zeros))
48+
return FactoringToIndependentSet(mres, g, ws, vmap, ProblemReductions.IndependentSet(mg, ws[vmap]))
49+
end
50+
51+
function ProblemReductions.target_problem(res::FactoringToIndependentSet)
52+
return res.problem
53+
end
54+
55+
function ProblemReductions.extract_solution(res::FactoringToIndependentSet, sol)
56+
cfg = zeros(Int, nv(res.raw_graph))
57+
cfg[res.vmap] .= sol
58+
i1, i2 = map_config_back(res.mapres, cfg)
59+
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)])
2660
end

test/Core.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Test, UnitDiskMapping, Graphs
2+
3+
@testset "GridGraph" begin
4+
grid = GridGraph((5, 5), [Node(2, 3), Node(2, 4), Node(5, 5)], 1.2)
5+
g = SimpleGraph(grid)
6+
@test ne(g) == 1
7+
@test vertices(grid) == vertices(g)
8+
@test neighbors(grid, 2) == neighbors(g, 2)
9+
10+
grid = GridGraph((5, 5), [Node(2, 3), Node(2, 4), Node(5, 5)], 4.0)
11+
g = SimpleGraph(grid)
12+
@test ne(g) == 3
13+
@test vertices(grid) == vertices(g)
14+
@test neighbors(grid, 2) == neighbors(g, 2)
15+
end

test/reduceto.jl

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
using Test, UnitDiskMapping, ProblemReductions, Graphs
1+
using Test, UnitDiskMapping, Graphs, GenericTensorNetworks
2+
import ProblemReductions
23

34
@testset "rules" begin
45
graph = complete_graph(3) # triangle
5-
is = IndependentSet(graph)
6-
wis = IndependentSet(graph, rand(nv(graph)) .* 0.2)
6+
fact = ProblemReductions.Factoring(2, 1, 2)
7+
is = ProblemReductions.IndependentSet(graph)
8+
wis = ProblemReductions.IndependentSet(graph, rand(nv(graph)) .* 0.2)
79
for (source, target_type) in [
810
# please add more tests here
9-
is => IndependentSet{ProblemReductions.GridGraph, Int, UnitWeight},
10-
wis => IndependentSet{ProblemReductions.GridGraph, Int, Vector{Int}},
11+
is => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, ProblemReductions.UnitWeight},
12+
wis => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Float64, Vector{Float64}},
13+
fact => ProblemReductions.IndependentSet{ProblemReductions.GridGraph, Int, Vector{Int}},
1114
]
1215
@info "Testing reduction from $(typeof(source)) to $(target_type)"
1316
# directly solve
14-
best_source = findbest(source, BruteForce())
17+
best_source = ProblemReductions.findbest(source, ProblemReductions.BruteForce())
1518

1619
# reduce and solve
17-
result = reduceto(target_type, source)
18-
target = target_problem(result)
19-
best_target = findbest(target, BruteForce())
20+
result = ProblemReductions.reduceto(target_type, source)
21+
target = ProblemReductions.target_problem(result)
22+
@test target isa target_type
23+
#best_target = findbest(target, BruteForce())
24+
best_target = GenericTensorNetworks.solve(GenericTensorNetwork(GenericTensorNetworks.IndependentSet(SimpleGraph(target.graph), collect(target.weights))), ConfigsMax())[].c.data
2025

2126
# extract the solution
22-
best_source_extracted_single = unique( extract_solution.(Ref(result), best_target) )
23-
best_source_extracted_multiple = extract_multiple_solutions(result, best_target)
27+
best_source_extracted_single = unique( ProblemReductions.extract_solution.(Ref(result), best_target) )
28+
best_source_extracted_multiple = ProblemReductions.extract_multiple_solutions(result, best_target)
2429

2530
# check if the solutions are the same
2631
@test best_source_extracted_single best_source

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
using UnitDiskMapping
22
using Test
33

4+
@testset "Core" begin
5+
include("Core.jl")
6+
end
7+
48
@testset "utils" begin
59
include("utils.jl")
610
end

0 commit comments

Comments
 (0)