Skip to content

Commit

Permalink
More EP tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
dourouc05 committed May 14, 2021
1 parent 29b5aab commit 1896e1e
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/ElementaryPath/ep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ end
# Solution.

struct ElementaryPathSolution{T, O <: CombinatorialObjective} <:
CombinatorialInstance
CombinatorialSolution
instance::ElementaryPathInstance{T, O}
variables::Vector{Edge{T}}
solutions::Dict{T, Vector{Edge{T}}}
Expand Down
159 changes: 125 additions & 34 deletions test/ep.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
@testset "ElementaryPath" begin
@testset "Copying" begin
g = path_digraph(3)
add_edge!(g, 2, 1)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 3.0, Edge(2, 1) => 25.0)

i = ElementaryPathInstance(g, rewards, 1, 3)
i2 = copy(i)
@test i.graph == i2.graph
@test i.rewards == i2.rewards
@test i.src == i2.src
@test i.dst == i2.dst
@test i.objective == i2.objective
end

@testset "Transforming a solution" begin
g = path_digraph(3)
add_edge!(g, 1, 3)
Expand Down Expand Up @@ -57,32 +43,31 @@

@testset "Elementary paths" begin
@testset "Interface" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)

@testset "Global interface" begin
i = ElementaryPathInstance(g, rewards, 1, 2)
@test objective(i) == Maximise()
end

@testset "Source not in graph" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
@test_throws ErrorException ElementaryPathInstance(g, rewards, 50, 2)
end

@testset "Destination not in graph" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
@test_throws ErrorException ElementaryPathInstance(g, rewards, 1, 50)
end

@testset "Source is destination" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
@test_throws ErrorException ElementaryPathInstance(g, rewards, 1, 1)
end

@testset "Source is destination" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
@test_throws ErrorException ElementaryPathInstance(g, rewards, 1, 1)
end

@testset "An edge has a reward but is not in the graph" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0, Edge(1, 3) => 1.0)
@test_throws ErrorException ElementaryPathInstance(g, rewards, 1, 2)
end
Expand All @@ -102,6 +87,56 @@
"The graph contains a positive-cost cycle around edge 2 -> 1.",
) solve(i, BellmanFordAlgorithm())
end

@testset "Copy" begin
g = path_digraph(3)
add_edge!(g, 2, 1)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 3.0, Edge(2, 1) => 25.0)

i = ElementaryPathInstance(g, rewards, 1, 3)
i2 = copy(i)
@test i.graph == i2.graph
@test i.rewards == i2.rewards
@test i.src == i2.src
@test i.dst == i2.dst
@test i.objective == i2.objective
end

@testset "Approximation" begin
i = ElementaryPathInstance(g, rewards, 1, 3)

@test approximation_ratio(i, DynamicProgramming()) == 1.0
@test approximation_term(i, DynamicProgramming()) == 0.0

@test approximation_ratio(i, DefaultLinearFormulation(Cbc.Optimizer)) == 1.0
@test approximation_term(i, DefaultLinearFormulation(Cbc.Optimizer)) == 0.0
end

@testset "Make solution" begin
i = ElementaryPathInstance(g, rewards, 1, 3)
d = Dict(Edge(1, 3) => 0.4, Edge(1, 2) => 0.8, Edge(2, 3) => 0.7)
s = make_solution(i, d)

@test s.instance == i
@test length(s.variables) == 2
@test Edge(1, 3) s.variables
@test Edge(1, 2) s.variables
@test Edge(2, 3) s.variables
end

@testset "Solution helpers" begin
i = ElementaryPathInstance(g, rewards, 1, 3)

# Infeasible solution.
s = ElementaryPathSolution(i, Edge{Int}[])
@test value(s) == -Inf

# Valid solution.
d = Dict(Edge(1, 3) => 0.4, Edge(1, 2) => 0.8, Edge(2, 3) => 0.7)
s = make_solution(i, d)

@test value(s) == 4
end
end

@testset "Basic" begin
Expand Down Expand Up @@ -163,23 +198,79 @@

@testset "Budgeted elementary paths" begin
@testset "Interface" begin
graph = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
weights = Dict(Edge(1, 2) => 1, Edge(2, 3) => 1)

@testset "Global interface" begin
i = MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), weights)
@test objective(i) == Maximise()
end

@testset "More edges have rewards than weights" begin
g = path_digraph(4)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0, Edge(4, 1) => 1.0)
weights = Dict(Edge(1, 2) => 1, Edge(2, 3) => 1)
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(g, rewards, 1, 2), weights)
r = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0, Edge(4, 1) => 1.0)
w = Dict(Edge(1, 2) => 1, Edge(2, 3) => 1)
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(g, r, 1, 2), w)
end

@testset "Negative weight or budget" begin
g = path_digraph(3)
rewards = Dict(Edge(1, 2) => 1.0, Edge(2, 3) => 1.0)
weights = Dict(Edge(1, 2) => 1, Edge(2, 3) => 1)
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(g, rewards, 1, 2), weights, -1)
w = Dict(Edge(1, 2) => 1, Edge(2, 3) => 1)
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), w, -1)

w[Edge(4, 2)] = 1
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), w)
w[Edge(4, 2)] = -1
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), w)
end

@testset "Copy" begin
i = MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), weights)
i2 = copy(i)
@test i.weights == i2.weights
@test i.min_budget == i2.min_budget
@test i.compute_all_values == i2.compute_all_values
@test i.instance.graph == i2.instance.graph
@test i.instance.rewards == i2.instance.rewards
@test i.instance.src == i2.instance.src
@test i.instance.dst == i2.instance.dst
@test i.instance.objective == i2.instance.objective
end

@testset "Approximation" begin
i = MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), weights)

@test approximation_ratio(i, DynamicProgramming()) == 1.0
@test approximation_term(i, DynamicProgramming()) == 0.0

@test approximation_ratio(i, DefaultLinearFormulation(Cbc.Optimizer)) == 1.0
@test approximation_term(i, DefaultLinearFormulation(Cbc.Optimizer)) == 0.0
end

@testset "Make solution" begin
i = MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), weights)
d = Dict(Edge(1, 3) => 0.4, Edge(1, 2) => 0.8, Edge(2, 3) => 0.7)
s = make_solution(i, d)

@test s.instance == i
@test length(s.variables) == 2
@test Edge(1, 3) s.variables
@test Edge(1, 2) s.variables
@test Edge(2, 3) s.variables
end

@testset "Solution helpers" begin
i = MinimumBudget(ElementaryPathInstance(graph, rewards, 1, 2), weights)

# Infeasible solution.
s = BudgetedElementaryPathSolution(i, Edge{Int}[])
@test value(s) == -Inf

# Valid solution.
d = Dict(Edge(1, 3) => 0.4, Edge(1, 2) => 0.8, Edge(2, 3) => 0.7)
s = make_solution(i, d)

weights[Edge(4, 2)] = 1
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(g, rewards, 1, 2), weights)
weights[Edge(4, 2)] = -1
@test_throws ErrorException MinimumBudget(ElementaryPathInstance(g, rewards, 1, 2), weights)
@test value(s) == 2
end
end

Expand Down

0 comments on commit 1896e1e

Please sign in to comment.