Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] new shrinking #23

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/UnitDiskMapping.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export unapply_gadgets!, unmatch
export Pattern, Corner, Turn, Cross, source_graph, mapped_graph, TruncatedTurn, EndTurn
export mapped_entry_to_compact, source_entry_to_configs, map_config_back, mis_overhead
export UNode, contract_graph, compress_graph
export unitdisk_graph

include("utils.jl")
include("gadgets.jl")
Expand All @@ -18,5 +19,6 @@ include("simplifiers.jl")
include("extracting_results.jl")
include("pathdecomposition/pathdecomposition.jl")
include("tikz/tikz.jl")
include("shrinking/shrinking.jl")

end
56 changes: 50 additions & 6 deletions src/extracting_results.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function mapped_entry_to_compact(::Cross{false})
end

function source_entry_to_configs(::Cross{false})
return Dict(Pair{Int64, Vector{BitVector}}[5 => [[1, 0, 1, 0, 0, 0, 1, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 1]], 12 => [[0, 0, 1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 0, 1, 0, 1, 0, 1]], 8 => [[0, 0, 1, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 1, 0, 0], [0, 1, 0, 0, 1, 0, 1, 0, 0]], 1 => [[1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 1, 0, 0]], 0 => [[0, 1, 0, 1, 0, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 1, 0, 0]], 6 => [[0, 1, 0, 1, 0, 1, 0, 0, 1]], 11 => [[1, 0, 1, 0, 1, 1, 0, 1, 0]], 9 => [[1, 0, 1, 0, 1, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1, 0, 0]], 14 => [[0, 0, 1, 0, 1, 1, 0, 0, 1], [0, 1, 0, 0, 1, 1, 0, 0, 1]], 3 => [[1, 0, 1, 0, 0, 1, 0, 1, 0], [1, 0, 0, 1, 0, 1, 0, 1, 0]], 7 => [[1, 0, 1, 0, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 1, 0, 0, 1]], 4 => [[0, 1, 0, 1, 0, 0, 1, 0, 1]], 13 => [[1, 0, 1, 0, 1, 0, 1, 0, 1]], 15 => [[1, 0, 1, 0, 1, 1, 0, 0, 1]], 2 => [[0, 1, 0, 1, 0, 1, 0, 1, 0]], 10 => [[0, 0, 1, 0, 1, 1, 0, 1, 0], [0, 1, 0, 0, 1, 1, 0, 1, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[5 => [[1, 0, 0, 1, 0, 0, 1, 0, 1], [1, 0, 1, 0, 0, 0, 1, 0, 1]], 12 => [[0, 1, 0, 0, 1, 0, 1, 0, 1], [0, 0, 1, 0, 1, 0, 1, 0, 1]], 8 => [[0, 1, 0, 0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0, 1, 0, 0]], 1 => [[1, 0, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 1, 0, 0], [1, 0, 1, 0, 0, 0, 1, 0, 0]], 0 => [[0, 1, 0, 1, 0, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0, 1, 0, 0]], 6 => [[0, 1, 0, 1, 0, 1, 0, 0, 1]], 11 => [[1, 0, 1, 0, 1, 1, 0, 1, 0]], 9 => [[1, 0, 1, 0, 1, 0, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1, 0, 0]], 14 => [[0, 1, 0, 0, 1, 1, 0, 0, 1], [0, 0, 1, 0, 1, 1, 0, 0, 1]], 3 => [[1, 0, 0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 0, 1, 0, 1, 0]], 7 => [[1, 0, 0, 1, 0, 1, 0, 0, 1], [1, 0, 1, 0, 0, 1, 0, 0, 1]], 4 => [[0, 1, 0, 1, 0, 0, 1, 0, 1]], 13 => [[1, 0, 1, 0, 1, 0, 1, 0, 1]], 15 => [[1, 0, 1, 0, 1, 1, 0, 0, 1]], 2 => [[0, 1, 0, 1, 0, 1, 0, 1, 0]], 10 => [[0, 1, 0, 0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 1, 1, 0, 1, 0]]])
end

mis_overhead(::Cross{false}) = -1
Expand All @@ -27,7 +27,7 @@ function mapped_entry_to_compact(::Turn)
end

function source_entry_to_configs(::Turn)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 1, 0]], 2 => [[0, 0, 1, 0, 1], [0, 1, 0, 0, 1]], 3 => [[1, 0, 1, 0, 1]], 1 => [[1, 0, 1, 0, 0], [1, 0, 0, 1, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 1, 0]], 2 => [[0, 1, 0, 0, 1], [0, 0, 1, 0, 1]], 3 => [[1, 0, 1, 0, 1]], 1 => [[1, 0, 0, 1, 0], [1, 0, 1, 0, 0]]])
end

mis_overhead(::Turn) = -1
Expand All @@ -38,7 +38,7 @@ function mapped_entry_to_compact(::WTurn)
end

function source_entry_to_configs(::WTurn)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[1, 0, 1, 0, 0]], 2 => [[0, 0, 0, 1, 1], [1, 0, 0, 0, 1]], 3 => [[0, 1, 0, 1, 1]], 1 => [[0, 1, 1, 0, 0], [0, 1, 0, 1, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[1, 0, 1, 0, 0]], 2 => [[1, 0, 0, 0, 1], [0, 0, 0, 1, 1]], 3 => [[0, 1, 0, 1, 1]], 1 => [[0, 1, 0, 1, 0], [0, 1, 1, 0, 0]]])
end

mis_overhead(::WTurn) = -1
Expand All @@ -49,7 +49,7 @@ function mapped_entry_to_compact(::Branch)
end

function source_entry_to_configs(::Branch)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 1, 0, 0, 1, 0]], 4 => [[0, 0, 1, 0, 0, 1, 0, 1], [0, 1, 0, 0, 0, 1, 0, 1], [0, 1, 0, 1, 0, 0, 0, 1]], 5 => [[1, 0, 1, 0, 0, 1, 0, 1]], 6 => [[0, 0, 1, 0, 1, 1, 0, 1], [0, 1, 0, 0, 1, 1, 0, 1]], 2 => [[0, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 1, 0, 0]], 7 => [[1, 0, 1, 0, 1, 1, 0, 1]], 3 => [[1, 0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 1, 0, 0]], 1 => [[1, 0, 1, 0, 0, 0, 1, 0], [1, 0, 1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 1, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 1, 0, 0, 1, 0]], 4 => [[0, 1, 0, 0, 0, 1, 0, 1], [0, 0, 1, 0, 0, 1, 0, 1], [0, 1, 0, 1, 0, 0, 0, 1]], 5 => [[1, 0, 1, 0, 0, 1, 0, 1]], 6 => [[0, 1, 0, 0, 1, 1, 0, 1], [0, 0, 1, 0, 1, 1, 0, 1]], 2 => [[0, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 0, 1, 1, 0, 0], [0, 1, 0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0, 1, 0]], 7 => [[1, 0, 1, 0, 1, 1, 0, 1]], 3 => [[1, 0, 1, 0, 1, 1, 0, 0], [1, 0, 1, 0, 1, 0, 1, 0]], 1 => [[1, 0, 1, 0, 0, 1, 0, 0], [1, 0, 1, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 1, 0]]])
end

mis_overhead(::Branch) = -1
Expand All @@ -60,7 +60,7 @@ function mapped_entry_to_compact(::BranchFix)
end

function source_entry_to_configs(::BranchFix)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0]], 2 => [[0, 1, 0, 1, 0, 1]], 3 => [[1, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 1]], 1 => [[1, 0, 1, 0, 1, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0]], 2 => [[0, 1, 0, 1, 0, 1]], 3 => [[1, 0, 0, 1, 0, 1], [1, 0, 1, 0, 0, 1]], 1 => [[1, 0, 1, 0, 1, 0]]])
end

mis_overhead(::BranchFix) = -1
Expand Down Expand Up @@ -93,7 +93,7 @@ function mapped_entry_to_compact(::BranchFixB)
end

function source_entry_to_configs(::BranchFixB)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 0, 1, 0], [0, 1, 0, 0]], 2 => [[0, 0, 1, 1]], 3 => [[1, 0, 0, 1]], 1 => [[1, 1, 0, 0]]])
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 0], [0, 0, 1, 0]], 2 => [[0, 0, 1, 1]], 3 => [[1, 0, 0, 1]], 1 => [[1, 1, 0, 0]]])
end

mis_overhead(::BranchFixB) = -1
Expand All @@ -119,3 +119,47 @@ function source_entry_to_configs(::UnitDiskMapping.DanglingLeg)
end

mis_overhead(::UnitDiskMapping.DanglingLeg) = -1


function mapped_entry_to_compact(::UnitDiskMapping.Square)
return Dict([0 => 0, 2 => 2, 3 => 3, 1 => 1])
end

function source_entry_to_configs(::UnitDiskMapping.Square)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 0, 1, 0], [0, 0, 0, 1]], 2 => [[0, 1, 1, 0]], 3 => [], 1 => [[1, 0, 0, 1]]])
end

mis_overhead(::UnitDiskMapping.Square) = -1


function mapped_entry_to_compact(::UnitDiskMapping.EndCrossing_with_Edge)
return Dict([0 => 0, 4 => 4, 5 => 1, 6 => 6, 2 => 2, 7 => 7, 3 => 3, 1 => 1])
end

function source_entry_to_configs(::UnitDiskMapping.EndCrossing_with_Edge)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0]], 4 => [[0, 0, 0, 1, 0, 1], [0, 0, 1, 0, 0, 1]], 5 => [[1, 0, 0, 0, 0, 1]], 6 => [[0, 1, 0, 1, 0, 1]], 2 => [[0, 1, 0, 1, 0, 0]], 7 => [], 3 => [], 1 => [[1, 0, 0, 0, 1, 0]]])
end

mis_overhead(::UnitDiskMapping.EndCrossing_with_Edge) = 0


function mapped_entry_to_compact(::UnitDiskMapping.Cane)
return Dict([0 => 0, 2 => 0, 3 => 3, 1 => 0])
end

function source_entry_to_configs(::UnitDiskMapping.Cane)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 0, 1, 0]], 2 => [[0, 0, 1, 0, 1], [0, 1, 0, 0, 1]], 3 => [[1, 0, 1, 0, 1]], 1 => [[1, 0, 0, 1, 0], [1, 0, 1, 0, 0]]])
end

mis_overhead(::UnitDiskMapping.Cane) = -1


function mapped_entry_to_compact(::UnitDiskMapping.CLoop)
return Dict([0 => 0, 2 => 0, 3 => 3, 1 => 0])
end

function source_entry_to_configs(::UnitDiskMapping.CLoop)
return Dict(Pair{Int64, Vector{BitVector}}[0 => [[0, 1, 1, 0, 0]], 2 => [[0, 1, 0, 0, 1], [1, 0, 0, 0, 1]], 3 => [[1, 0, 0, 1, 1]], 1 => [[1, 0, 0, 1, 0], [0, 0, 1, 1, 0]]])
end

mis_overhead(::UnitDiskMapping.CLoop) = -1
8 changes: 6 additions & 2 deletions src/mapping.jl
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ function mis_overhead_copylines(ug::UGrid{WC,W}) where {WC,W}
end

##### Interfaces ######
export MappingResult, map_graph, map_configs_back
export MappingResult, map_graph, map_configs_back, apply_simplifiers_unweighted

struct MappingResult{CT,WT}
grid_graph::UGrid{CT,WT}
Expand Down Expand Up @@ -386,6 +386,10 @@ function map_graph(mode, g::SimpleGraph; vertex_order=Greedy(), ruleset=default_
return MappingResult(ug, vcat(tape, tape2) , mis_overhead0 + mis_overhead1 + mis_overhead2)
end

function apply_simplifiers_unweighted(ug::UGrid)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted an estimate of overhead scaling, can delete/modify function

return apply_simplifier_gadgets!(ug; ruleset=default_simplifier_ruleset(UnWeighted()))
end

map_configs_back(r::MappingResult{<:Cell}, configs::AbstractVector) = unapply_gadgets!(copy(r.grid_graph), r.mapping_history, copy.(configs))[2]
default_simplifier_ruleset(::UnWeighted) = vcat([rotated_and_reflected(rule) for rule in simplifier_ruleset]...)
default_simplifier_ruleset(::Weighted) = weighted.(default_simplifier_ruleset(UnWeighted()))
default_simplifier_ruleset(::Weighted) = weighted.(default_simplifier_ruleset(UnWeighted()))
191 changes: 191 additions & 0 deletions src/shrinking/shrinking.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
module CompressUDG
using Graphs

export UNode, contract_graph, CompressUDGMethod

struct UNode
vertex::Int # vertex index in original graph
pos::Tuple{Int, Int}
neighbors::Vector{Int}
end
function Base.:(==)(x::UNode, y::UNode)
x.vertex == y.vertex && x.neighbors == y.neighbors
end

# get surrounding neighbor points on UDG
function get_udg_neighbors(pos::Tuple{Int, Int})
p_x, p_y = pos
pos_udg_neighbors = Vector{Tuple{Int, Int}}()

for i = -1:1, j = -1:1
!(i == 0 && j == 0) && push!(pos_udg_neighbors, (p_x + i, p_y + j))
end
return pos_udg_neighbors
end


# find UDNode given a position; return nothing if no node at that position
function get_UNode_from_pos(pos::Tuple{Int, Int}, node_list::Vector{UNode})
for u in node_list
(u.pos == pos) && return u
end
return nothing
end

# find boundaries of grid graph given list of UNodes
function find_boundaries(node_list::Vector{UNode})
min_x = typemax(Int)
min_y = typemax(Int)
max_x = 0
max_y = 0

for u in node_list
p_x, p_y = u.pos
(p_x > max_x) && (max_x = p_x)
(p_x < min_x) && (min_x = p_x)
(p_y > max_y) && (max_y = p_y)
(p_y < min_y) && (min_y = p_y)
end
return min_x, min_y, max_x, max_y
end

# find points on the boundary that can be moved
function find_boundary_points(node_list::Vector{UNode}, x_min, x_max, y_min, y_max)
pts_boundary = Vector{UNode}()

for u in node_list
p_x, p_y = u.pos
(p_x == x_min || p_x == x_max || p_y == y_min || p_y == y_max) && push!(pts_boundary, u)
end

return pts_boundary
end


# check that the new position of node n satisfies UDG requirements
function check_UDG_criteria(n::UNode, new_pos::Tuple{Int, Int},
node_list::Vector{UNode})
# check if new_pos is already occupied
(get_UNode_from_pos(new_pos, node_list) != nothing) && return false

p_x, p_y = new_pos
new_neighbors = Vector{Int}()

for p in get_udg_neighbors(new_pos)
unode = get_UNode_from_pos(p, node_list)

if (unode !== nothing) && (unode.vertex != n.vertex)
push!(new_neighbors, unode.vertex)
end
end

(issetequal(new_neighbors, n.neighbors) == true) && return true
return false
end

# move node n to a new position new_pos
function move_node(n::UNode, node_list::Vector{UNode}, candidates::Vector{Tuple{Int, Int}})
for p in candidates
if check_UDG_criteria(n, p, node_list)
node_list[n.vertex] = UNode(n.vertex, p, n.neighbors)
return node_list
end
end
return node_list
end

# determine candidates to move
function determine_candidates(pos::Tuple{Int, Int}, x_min, x_max, y_min, y_max)
p_x, p_y = pos

halfx = (x_max - x_min)/2 + x_min
halfy = (y_max - y_min)/2 + y_min

# move boundary vertices such that we can shrink graph from four quadrants
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good! Now it is much easier to read. If possible, you should try to lessen the number of branches - otherwise you need to write tests for every branch to ensure the test coverage is good.

(p_x == x_min && p_y >= halfy) && return [(p_x + 1, p_y), (p_x + 1, p_y - 1), (p_x, p_y - 1)]
(p_x == x_min && p_y < halfy) && return [(p_x + 1, p_y), (p_x + 1, p_y + 1), (p_x, p_y + 1)]
(p_x == x_max && p_y >= halfy) && return [(p_x - 1, p_y), (p_x - 1, p_y - 1), (p_x, p_y - 1)]
(p_x == x_max && p_y < halfy) && return [(p_x - 1, p_y), (p_x - 1, p_y + 1), (p_x, p_y + 1)]

(p_x < halfx && p_y == y_min) && return [(p_x, p_y + 1), (p_x + 1, p_y + 1), (p_x + 1, p_y)]
(p_x >= halfx && p_y == y_min) && return [(p_x, p_y + 1), (p_x - 1, p_y + 1), (p_x - 1, p_y)]
(p_x < halfx && p_y == y_max) && return [(p_x, p_y - 1), (p_x + 1, p_y - 1), (p_x + 1, p_y)]
(p_x >= halfx && p_y == y_max) && return [(p_x, p_y - 1), (p_x - 1, p_y - 1), (p_x - 1, p_y)]

end


# one shrinking step
function greedy_step(node_list::Vector{UNode}, min_x::Int, max_x::Int,
min_y::Int, max_y::Int)

boundary_pts = find_boundary_points(node_list, min_x, max_x,
min_y, max_y)

for p in boundary_pts
node_list = move_node(p, node_list, determine_candidates(p.pos, min_x, max_x,
min_y, max_y))
end

return node_list
end

function unitdisk_graph(locs::AbstractVector, unit::Real)
minhthin1028 marked this conversation as resolved.
Show resolved Hide resolved
n = length(locs)
g = SimpleGraph(n)
for i=1:n, j=i+1:n
if sum(abs2, locs[i] .- locs[j]) < unit ^ 2
add_edge!(g, i, j)
end
end
return g
end

# interfaces
abstract type CompressUDGMethod end

"""
contract_graph(locs::Vector{Tuple{Int, Int}})
Compute a contracted version of input graph node positions and returns a
corresponding layout of new condensed graph
"""
function contract_graph(node_positions::Vector{Tuple{Int, Int}})
# initiate UNodes

n_list = Vector{UNode}(undef, size(node_positions)[1])
g = unitdisk_graph(node_positions, 1.5)

for (ind, n_pos) in enumerate(node_positions)
n_list[ind] = UNode(ind, n_pos, neighbors(g, ind))
end

xmin, ymin, xmax, ymax = find_boundaries(n_list)


while (xmax - xmin > 1) && (ymax - ymin > 1)
n_list = greedy_step(n_list, xmin, xmax, ymin, ymax)

if xmin < xmax
xmin += 1
xmax -= 1
end

if ymin < ymax
ymin += 1
ymax -= 1
end

end

locs_new = Vector{Tuple{Int, Int}}(undef, size(node_positions)[1])
for (ind, un) in enumerate(n_list)
locs_new[ind] = un.pos
end

return locs_new
end

end

using .CompressUDG
export UNode, contract_graph, CompressUDGMethod
Loading