Skip to content

Commit d153871

Browse files
committed
polish interfaces
1 parent 3838ce0 commit d153871

File tree

4 files changed

+86
-11
lines changed

4 files changed

+86
-11
lines changed

src/UnitDiskMapping.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module UnitDiskMapping
44

55
using Graphs
66

7-
export UGrid, apply_crossing_gadgets!, apply_gadget!, embed_graph
7+
export UGrid, apply_crossing_gadgets!, apply_simplifier_gadgets!, apply_gadget!, embed_graph
88
export unapply_gadgets!, unmatch
99
export Pattern, Corner, Turn, Cross, source_graph, mapped_graph, TruncatedTurn
1010
export mapped_entry_to_compact, source_entry_to_configs, map_config_back, mis_overhead

src/mapping.jl

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,11 @@ function apply_crossing_gadgets!(ug::UGrid, ruleset=crossing_ruleset)
7979
n = length(ug.lines)
8080
for j=1:n # start from 0 because there can be one empty padding column/row.
8181
for i=1:n
82-
matched = false
8382
for pattern in ruleset
8483
x, y = crossat(ug, i, j) .- cross_location(pattern) .+ (1,1)
8584
if match(pattern, ug.content, x, y)
8685
apply_gadget!(pattern, ug.content, x, y)
8786
push!(tape, (pattern, x, y))
88-
matched = true
8987
break
9088
end
9189
end
@@ -94,6 +92,21 @@ function apply_crossing_gadgets!(ug::UGrid, ruleset=crossing_ruleset)
9492
return ug, tape
9593
end
9694

95+
function apply_simplifier_gadgets!(ug::UGrid; ruleset, nrepeat::Int=10)
96+
tape = Tuple{Pattern,Int,Int}[]
97+
for _ in 1:nrepeat, pattern in ruleset
98+
for j=0:size(ug.content, 1) # start from 0 because there can be one empty padding column/row.
99+
for i=0:size(ug.content, 2)
100+
if match(pattern, ug.content, i, j)
101+
apply_gadget!(pattern, ug.content, i, j)
102+
push!(tape, (pattern, i, j))
103+
end
104+
end
105+
end
106+
end
107+
return ug, tape
108+
end
109+
97110
function unapply_gadgets!(ug::UGrid, tape, configurations)
98111
for (pattern, i, j) in Base.Iterators.reverse(tape)
99112
@assert unmatch(pattern, ug.content, i, j)
@@ -294,4 +307,34 @@ function mis_overhead_copylines(ug::UGrid)
294307
@assert length(locs) % 2 == 1
295308
length(locs) ÷ 2
296309
end
297-
end
310+
end
311+
312+
##### Interfaces ######
313+
export MappingResult, map_graph, map_configs_back
314+
315+
struct MappingResult
316+
grid_graph::UGrid
317+
mapping_history::Vector{Tuple{Pattern,Int,Int}}
318+
mis_overhead::Int
319+
end
320+
321+
"""
322+
map_graph(g::SimpleGraph; ruleset=[...])
323+
324+
Map a graph to a unit disk grid graph that being "equivalent" to the original graph.
325+
Here "equivalent" means a maximum independent set in the grid graph can be mapped back to
326+
a maximum independent set of the original graph in polynomial time.
327+
328+
Returns a `MappingResult` instance.
329+
"""
330+
function map_graph(g::SimpleGraph; ruleset=[RotatedGadget(DanglingLeg(), n) for n=0:3])
331+
ug = embed_graph(g)
332+
mis_overhead0 = mis_overhead_copylines(ug)
333+
ug, tape = apply_crossing_gadgets!(ug)
334+
ug, tape2 = apply_simplifier_gadgets!(ug; ruleset=ruleset)
335+
mis_overhead1 = sum(x->mis_overhead(x[1]), tape)
336+
mis_overhead2 = sum(x->mis_overhead(x[1]), tape2)
337+
return MappingResult(ug, vcat(tape, tape2) , mis_overhead0 + mis_overhead1 + mis_overhead2)
338+
end
339+
340+
map_configs_back(r::MappingResult, configs::AbstractVector) = unapply_gadgets!(copy(r.grid_graph), r.mapping_history, copy.(configs))[2]

src/simplifiers.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export @gg
1111
"""
1212
abstract type SimplifyPattern <: Pattern end
1313
iscon(s::SimplifyPattern) = false
14+
cross_location(s::SimplifyPattern) = size(s) 2
1415
function source_locations end
1516
function mapped_locations end
1617
function mapped_graph(p::SimplifyPattern)
@@ -65,6 +66,9 @@ macro gg(expr)
6566
end
6667
end
6768

69+
# # How to add a new simplification rule
70+
# 1. specify a gadget like the following. Use either `o` and `●` to specify a vertex,
71+
# either `.` or `⋅` to specify a placeholder.
6872
@gg DanglingLeg =
6973
"""
7074
⋅ ⋅ ⋅
@@ -76,4 +80,7 @@ end
7680
⋅ ⋅ ⋅
7781
⋅ ⋅ ⋅
7882
⋅ ● ⋅
79-
"""
83+
"""
84+
85+
# 2. run the script `project/createmap` to generate `mis_overhead` and other informations required
86+
# for mapping back. (Note: will overwrite the source file `src/extracting_results.jl`)

test/mapping.jl

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,47 @@ end
3636
ug = embed_graph(g)
3737
mis_overhead0 = mis_overhead_copylines(ug)
3838
ug2, tape = apply_crossing_gadgets!(copy(ug))
39+
ug3, tape2 = apply_simplifier_gadgets!(copy(ug2); ruleset=[RotatedGadget(UnitDiskMapping.DanglingLeg(), n) for n=0:3])
3940
mis_overhead1 = sum(x->mis_overhead(x[1]), tape)
40-
missize_map = solve(Independence(SimpleGraph(ug2)), "size max"; optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy())[].n
41+
mis_overhead2 = sum(x->mis_overhead(x[1]), tape2)
42+
@show mis_overhead2
43+
gp = Independence(SimpleGraph(ug3); optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy())
44+
missize_map = solve(gp, "size max")[].n
4145
missize = solve(Independence(g), "size max")[].n
42-
@test mis_overhead0 + mis_overhead1 + missize == missize_map
43-
misconfig = solve(Independence(SimpleGraph(ug2)), "config max"; optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy())[].c
44-
c = zeros(Int, size(ug2.content))
45-
for (i, loc) in enumerate(findall(!iszero, ug2.content))
46+
@test mis_overhead0 + mis_overhead1 + mis_overhead2 + missize == missize_map
47+
misconfig = solve(gp, "config max")[].c
48+
c = zeros(Int, size(ug3.content))
49+
for (i, loc) in enumerate(findall(!iszero, ug3.content))
4650
c[loc] = misconfig.data[i]
4751
end
4852
@test all(ci->UnitDiskMapping.safe_get(c, ci.I...)==0 || (UnitDiskMapping.safe_get(c, ci.I[1], ci.I[2]+1) == 0 && UnitDiskMapping.safe_get(c, ci.I[1]+1, ci.I[2]) == 0 &&
4953
UnitDiskMapping.safe_get(c, ci.I[1]-1, ci.I[2]) == 0 && UnitDiskMapping.safe_get(c, ci.I[1], ci.I[2]-1) == 0 &&
5054
UnitDiskMapping.safe_get(c, ci.I[1]-1, ci.I[2]-1) == 0 && UnitDiskMapping.safe_get(c, ci.I[1]-1, ci.I[2]+1) == 0 &&
5155
UnitDiskMapping.safe_get(c, ci.I[1]+1, ci.I[2]-1) == 0 && UnitDiskMapping.safe_get(c, ci.I[1]+1, ci.I[2]+1) == 0
5256
), CartesianIndices((55, 55)))
53-
res, cs = unapply_gadgets!(copy(ug2), tape, [copy(c)])
57+
res, cs = unapply_gadgets!(copy(ug3), [tape..., tape2...], [copy(c)])
5458
@test count(isone, cs[1]) == missize
5559
@test is_independent_set(g, cs[1])
5660
end
61+
end
62+
63+
@testset "interface" begin
64+
g = smallgraph(:petersen)
65+
res = map_graph(g)
66+
67+
# checking size
68+
gp = Independence(SimpleGraph(res.grid_graph); optimizer=TreeSA(ntrials=1, niters=10), simplifier=MergeGreedy())
69+
missize_map = solve(gp, "size max")[].n
70+
missize = solve(Independence(g), "size max")[].n
71+
@test res.mis_overhead + missize == missize_map
72+
73+
# checking mapping back
74+
misconfig = solve(gp, "config max")[].c
75+
c = zeros(Int, size(res.grid_graph.content))
76+
for (i, loc) in enumerate(findall(!iszero, res.grid_graph.content))
77+
c[loc] = misconfig.data[i]
78+
end
79+
original_configs = map_configs_back(res, [c])
80+
@test count(isone, original_configs[1]) == missize
81+
@test is_independent_set(g, original_configs[1])
5782
end

0 commit comments

Comments
 (0)