Skip to content

[WIP] new shrinking #23

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Changes from all 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
@@ -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")
@@ -18,5 +19,6 @@ include("simplifiers.jl")
include("extracting_results.jl")
include("pathdecomposition/pathdecomposition.jl")
include("tikz/tikz.jl")
include("shrinking/shrinking.jl")

end
74 changes: 70 additions & 4 deletions src/extracting_results.jl
Original file line number Diff line number Diff line change
@@ -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, 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, 1, 0, 0], [0, 1, 0, 0, 1, 0, 1, 0, 0], [0, 0, 1, 0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0, 0, 1, 0]], 1 => [[1, 0, 1, 0, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 0, 1, 0, 0], [1, 0, 1, 0, 0, 0, 0, 1, 0], [1, 0, 0, 1, 0, 0, 0, 1, 0]], 0 => [[0, 1, 0, 1, 0, 0, 1, 0, 0], [0, 1, 0, 1, 0, 0, 0, 1, 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, 1, 0, 0], [1, 0, 1, 0, 1, 0, 0, 1, 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]]])
end

mis_overhead(::Cross{false}) = -1
@@ -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
@@ -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, 0, 1, 0], [0, 0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 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]]])
end

mis_overhead(::Branch) = -1
@@ -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, 1, 0, 0], [0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 1, 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]]])
end

mis_overhead(::BranchFix) = -1
@@ -119,3 +119,69 @@ 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, 0, 1], [0, 0, 1, 0]], 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, 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(::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 => [[1, 0, 0, 0, 1], [0, 1, 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


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

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

mis_overhead(::UnitDiskMapping.CurveEnd) = -1


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

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

mis_overhead(::UnitDiskMapping.DiagonalEnd) = -1
8 changes: 6 additions & 2 deletions src/mapping.jl
Original file line number Diff line number Diff line change
@@ -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}
@@ -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()))
298 changes: 298 additions & 0 deletions src/shrinking/shrinking.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
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)
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

module CompressUDG
using Graphs
using ..UnitDiskMapping: unitdisk_graph

export UNode, contract_graph, CompressUDGMethod

struct UNode
vertex::Int
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})
# udg radius = 1.5
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 UNode from given position and return nothing if no node in 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 the center of the graph given list of UNodes
function find_center(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 (max_x - min_x)/2 + min_x, (max_y - min_y)/2 + min_y
end

# filter function that checks that 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)
((unode !== nothing) && (unode.vertex != n.vertex)) && push!(new_neighbors, unode.vertex)
end

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

# determine cost for a position
# defined as distance from center of graph
function node_cost(pos::Tuple{Int, Int}, node_list::Vector{UNode})
center_x, center_y = find_center(node_list)
p_x, p_y = pos
return (center_x - p_x)^2 + (center_y - p_y)^2
end

# move a node n to minimize cost
function move_node(n::UNode, node_list::Vector{UNode})
min_cost = node_cost(n.pos, node_list)

candidates = get_UDG_neighbors(n.pos)

for p in candidates
if check_UDG_criteria(n, p, node_list)
if node_cost(p, node_list) < min_cost
node_list[n.vertex] = UNode(n.vertex, p, n.neighbors)
return node_list
end
end
end
return node_list, min_cost
end

function total_cost(node_list::Vector{UNode})
total_cost = 0
for n in node_list
total_cost += node_cost(n.pos, node_list)
end
return total_cost
end

# move all nodes to minimize cost one by one
function greedy_step(node_list::Vector{UNode})
for n in node_list
node_list, min_cost1 = move_node(n, node_list)
node_list, min_cost2 = move_node(n, node_list)
while min_cost2 != min_cost1
min_cost1 = min_cost2
node_list, min_cost2 = move_node(n, node_list)
end
end

return node_list, total_cost(node_list)
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

n_list, cost = greedy_step(n_list)
n_list, cost2 = greedy_step(n_list)

while cost != cost2
cost = cost2
n_list, cost2 = greedy_step(n_list)
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
102 changes: 92 additions & 10 deletions src/simplifiers.jl
Original file line number Diff line number Diff line change
@@ -81,23 +81,105 @@ end
# 1. specify a gadget like the following. Use either `o` and `●` to specify a vertex,
# either `.` or `⋅` to specify a placeholder.
@gg DanglingLeg =
"""
⋅ ⋅ ⋅
⋅ ● ⋅
⋅ ● ⋅
⋅ ● ⋅
"""
⋅ ⋅ ⋅
⋅ ● ⋅
⋅ ● ⋅
⋅ ● ⋅
"""=>"""
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ⋅ ⋅
⋅ ● ⋅
"""

@gg Square =
"""
⋅ ● ⋅ ⋅
● ⋅ ● ⋅
⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅
"""=>"""
⋅ ● ⋅ ⋅
● ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
"""

@gg EndCrossing_with_Edge =
"""
⋅ ● ⋅ ⋅
● ● ● ●
⋅ ● ⋅ ⋅
⋅ ⋅ ⋅ ⋅
"""=>"""
⋅ ● ⋅ ⋅
● ⋅ ⋅ ●
⋅ ● ● ⋅
⋅ ⋅ ⋅ ⋅
"""

@gg Cane =
"""
⋅ ⋅ ⋅ ⋅
⋅ ● ⋅ ⋅
● ⋅ ● ⋅
⋅ ⋅ ● ⋅
⋅ ⋅ ● ⋅
"""=>"""
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
● ⋅ ⋅ ⋅
⋅ ● ⋅ ⋅
⋅ ⋅ ● ⋅
"""

@gg CLoop =
"""
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ● ⋅
⋅ ● ⋅ ●
⋅ ● ⋅ ⋅
⋅ ⋅ ● ⋅
"""=>"""
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ●
⋅ ⋅ ● ⋅
⋅ ⋅ ● ⋅
"""

@gg CurveEnd =
"""
⋅ ⋅ ⋅ ⋅
⋅ ● ⋅ ⋅
⋅ ⋅ ● ⋅
⋅ ⋅ ● ⋅
"""=>"""
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ● ⋅
"""

@gg DiagonalEnd =
"""
⋅ ⋅ ⋅ ⋅
⋅ ● ⋅ ⋅
⋅ ⋅ ● ⋅
⋅ ⋅ ⋅ ●
"""=>"""
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ⋅
⋅ ⋅ ⋅ ●
"""

# 2. add your gadget to simplifier ruleset.
const simplifier_ruleset = SimplifyPattern[DanglingLeg()]
const simplifier_ruleset = SimplifyPattern[DanglingLeg(), Square(), EndCrossing_with_Edge(), Cane(), CLoop(), CurveEnd(), DiagonalEnd()]
# set centers (vertices with weight 1) for the weighted version
source_centers(::WeightedGadget{DanglingLeg}) = [(2,2)]
mapped_centers(::WeightedGadget{DanglingLeg}) = [(4,2)]

# 3. run the script `project/createmap` to generate `mis_overhead` and other informations required
# for mapping back. (Note: will overwrite the source file `src/extracting_results.jl`)
# for mapping back. (Note: will overwrite the source file `src/extracting_results.jl`)
27 changes: 27 additions & 0 deletions test/shrinking/shrinking.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using UnitDiskMapping, Test
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Still need to add unit tests for new functions

using Graphs

# test method "get_udg_neighbors"
# test "get_UNode_from_pos"
@testset "test neighbors" begin
# test on gadgets
g = smallgraph(:house)
# map to udg
pos = coordinates(map_graph(g).grid_graph)
ud_g = unitdisk_graph(pos, 1.5)

# list of UNodes
n_list = Vector{UNode}(undef, size(pos)[1])
# check that all neighbors of udg map in "get_udg_neighbors"
for (i, v) in enumerate(vertices(ud_g))
for j in neighbors(ud_g, v)
@test(pos[j] in get_udg_neighbors(pos[i]))
end
# initiate unodes
unode = UNode(v, pos[i], neighbors(ud_g, v))
n_list[i] = unode
end

# test node_cost
@test(node_cost((find_center(n_list)), n_list) == 0)
end