Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 3 additions & 3 deletions src/bruteforce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ A brute force method to find the best configuration of a problem.
"""
struct BruteForce end

function findbest(problem::AbstractProblem, ::BruteForce)
function findbest(problem::AbstractProblem, ::BruteForce; atol=eps(Float64), rtol=eps(Float64))
best_size = Inf
best_configs = Vector{Int}[]
configs = Iterators.product([flavors(problem) for i in 1:num_variables(problem)]...)
for (size, config) in energy_multi(problem, configs)
if size == best_size
if isapprox(size, best_size; atol, rtol)
push!(best_configs, collect(config))
elseif size < best_size[1]
best_size = Float64(size)
Expand All @@ -19,4 +19,4 @@ function findbest(problem::AbstractProblem, ::BruteForce)
end
end
return best_configs
end
end
46 changes: 19 additions & 27 deletions src/topology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ $TYPEDEF
A unit disk graph is a graph in which the vertices are points in a plane and two vertices are connected by an edge if and only if the Euclidean distance between them is at most a given radius.

### Fields
- `n::Int`: the number of vertices
- `locations::Vector{NTuple{D, T}}`: the locations of the vertices
- `radius::T`: the radius of the unit disk
- `radius::Float64`: the radius of the unit disk
"""
struct UnitDiskGraph{D, T} <: Graphs.AbstractGraph{Int}
locations::Vector{NTuple{D, T}}
radius::T
radius::Float64
end
Base.:(==)(a::UnitDiskGraph, b::UnitDiskGraph) = a.locations == b.locations && a.radius == b.radius
Graphs.nv(g::UnitDiskGraph) = length(g.locations)
Expand All @@ -71,9 +70,7 @@ end
function all_edges(g::UnitDiskGraph)
edges = Graphs.SimpleEdge{Int}[]
for i in 1:nv(g), j in i+1:nv(g)
if sum(abs2, g.locations[i] .- g.locations[j]) ≤ g.radius^2
push!(edges, Graphs.SimpleEdge(i, j))
end
has_edge(g, i, j) && push!(edges, Graphs.SimpleEdge(i, j))
end
return edges
end
Expand All @@ -95,7 +92,7 @@ Base.eltype(::Type{Graphs.SimpleGraphs.SimpleEdgeIter{UnitDiskGraph{D,T}}}) wher
end

# return the next edge if it exists
if sum(abs2, g.locations[i] .- g.locations[j]) ≤ g.radius^2
if has_edge(g, i, j)
e = Graphs.SimpleEdge(i, j)
state = (i, j + 1)
return e, state
Expand All @@ -107,31 +104,26 @@ Base.eltype(::Type{Graphs.SimpleGraphs.SimpleEdgeIter{UnitDiskGraph{D,T}}}) wher
return nothing
end

"""
$TYPEDEF
function Graphs.induced_subgraph(g::UnitDiskGraph, vlist::AbstractVector{<:Integer})
return UnitDiskGraph(g.locations[vlist], g.radius), vlist
end

A grid graph is a graph in which the vertices are arranged in a grid and two vertices are connected by an edge if and only if they are adjacent in the grid.
function Graphs.neighbors(g::UnitDiskGraph, i::Int)
[j for j in 1:nv(g) if i != j && has_edge(g, i, j)]
end

### Fields
- `grid::BitMatrix`: a matrix of booleans, where `true` indicates the presence of an edge.
- `radius::Float64`: the radius of the unit disk
"""
struct GridGraph <: Graphs.AbstractGraph{Int}
grid::BitMatrix
radius::Float64
GridGraph is a unit disk graph with integer coordinates.
"""
const GridGraph{D} = UnitDiskGraph{D, Int}
function GridGraph(matrix::AbstractMatrix{Bool}, radius)
return UnitDiskGraph(vec(getfield.(findall(matrix), :I)), Float64(radius))
end
Base.:(==)(a::GridGraph, b::GridGraph) = a.grid == b.grid && a.radius == b.radius
Graphs.nv(g::GridGraph) = sum(g.grid)
Graphs.vertices(g::GridGraph) = 1:nv(g)
Graphs.ne(g::GridGraph) = length(Graphs.edges(g))
function Graphs.edges(g::GridGraph)
udg = UnitDiskGraph([Float64.(x.I) for x in findall(g.grid)], g.radius)
return Graphs.edges(udg)
function GridGraph(locations::AbstractVector{NTuple{D, Int}}, radius::Float64) where {D}
return UnitDiskGraph(locations, radius)
end

# not implemented
# struct PlanarGraph <: Graphs.AbstractGraph{Int}
# end
# TODO: implement the planar graph

##### Extra interfaces #####
_vec(e::Graphs.SimpleEdge) = [src(e), dst(e)]
Expand Down Expand Up @@ -161,4 +153,4 @@ function _add_edge_weight!(g::HyperGraph, c::HyperEdge{Int}, J, weight)
end
push!(g.edges, c)
push!(J, weight)
end
end
1 change: 1 addition & 0 deletions test/rules/rules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ end
# reduce and solve
result = reduceto(target_type, source)
target = target_problem(result)
@test target isa target_type
best_target = findbest(target, BruteForce())

# extract the solution
Expand Down
10 changes: 5 additions & 5 deletions test/rules/spinglass_sat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ end
d = x ∨ (c ∧ ¬z)
end
sg, vars = ProblemReductions.circuit2spinglass(circuit)
indexof(x) = findfirst(==(x), vars)
gadget = LogicGadget(sg, indexof.([:x, :y, :z]), [indexof(:d)])
indexof1(x) = findfirst(==(x), vars)
gadget = LogicGadget(sg, indexof1.([:x, :y, :z]), [indexof1(:d)])
tb = truth_table(gadget; variables=vars)
@test tb.values == vec([(x & y & (1-z)) | x for x in [0, 1], y in [0, 1], z in [0, 1]])
res = reduceto(SpinGlass{<:SimpleGraph}, CircuitSAT(circuit))
Expand All @@ -95,8 +95,8 @@ end
end
circuitsat = CircuitSAT(circuit)
result = reduceto(SpinGlass{<:SimpleGraph}, circuitsat)
indexof(x) = findfirst(==(x), circuitsat.symbols[sortperm(result.variables)])
gadget = LogicGadget(result.spinglass, indexof.([:x, :y, :z]), [indexof(:d)])
indexof2(x) = findfirst(==(x), circuitsat.symbols[sortperm(result.variables)])
gadget = LogicGadget(result.spinglass, indexof2.([:x, :y, :z]), [indexof2(:d)])
tb = truth_table(gadget; variables=circuitsat.symbols[result.variables])
@test tb.values == vec([((1 - (x & y)) & (1-z)) | x for x in [0, 1], y in [0, 1], z in [0, 1]])
end
end
17 changes: 16 additions & 1 deletion test/topology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,19 @@ end
@test SimpleEdge(2, 3) in edges(gg)
@test collect(edges(gg)) == [SimpleEdge(1, 2), SimpleEdge(2, 3)]
@test vertices(gg) == 1:3
end

grid = GridGraph([(2, 3), (2, 4), (5, 5)], 1.2)
g = SimpleGraph(grid)
@test ne(g) == 1
@test vertices(grid) == vertices(g)
@test neighbors(grid, 2) == neighbors(g, 2)

grid = GridGraph([(2, 3), (2, 4), (5, 5)], 4.0)
g = SimpleGraph(grid)
@test ne(g) == 3
@test vertices(grid) == vertices(g)
@test neighbors(grid, 2) == neighbors(g, 2)

ig, _ = induced_subgraph(grid, [1, 2])
@test ne(ig) == 1
end
Loading