Showing 6 of 14 files from the diff.
Other files ignored by Codecov

@@ -16,7 +16,7 @@
 16 16 ` # Build the optimisation model behind solve_linear.` 17 17 ` solver.model = Model(solver.solver)` 18 18 ` indices = collect((i, j) for i in 1:n_arms, j in 1:n_arms)` 19 - ` solver.x = @variable(solver.model, [indices], lower_bound=0, upper_bound=1)` 19 + ` solver.x = @variable(solver.model, [indices], binary=true)` 20 20 21 21 ` for i in 1:n_arms # Left nodes.` 22 22 ` @constraint(solver.model, sum(solver.x[(i, j)] for j in 1:n_arms) <= 1)`

@@ -311,8 +311,9 @@
 311 311 ` # This is based on http://people.idsia.ch/~grandoni/Pubblicazioni/BBGS08ipco.pdf, Theorem 1.` 312 312 313 313 ` # If there are too few vertices, not much to do. The smallest side of the bipartite graph must have at least 4 vertices,` 314 - ` # so that 4 of them can be fixed. (Should rather perform an exhaustive exploration.)` 314 + ` # so that 4 of them can be fixed.` 315 315 ` if i.matching.n_left <= 4 || i.matching.n_right <= 4` 316 + ` # TODO: Should rather perform an exhaustive exploration.` 316 317 ` return matching_hungarian_budgeted_lagrangian_refinement(i; kwargs...)` 317 318 ` end` 318 319
@@ -340,13 +341,17 @@
 340 341 ` # Filter out the edges that have a higher value than any of these two edges. Give a very large reward to them both.` 341 342 ` cutoff = min(i.matching.reward[e1], i.matching.reward[e2], i.matching.reward[e3], i.matching.reward[e4])` 342 343 ` reward = copy(i.matching.reward)` 343 - ` filter!(kv -> kv[2] < cutoff, reward)` 344 - ` filter!(kv -> _edge_any_end_match(kv[1], e1), reward)` 345 - ` filter!(kv -> _edge_any_end_match(kv[1], e2), reward)` 346 - ` filter!(kv -> _edge_any_end_match(kv[1], e3), reward)` 347 - ` filter!(kv -> _edge_any_end_match(kv[1], e4), reward)` 344 + ` filter!(kv -> kv[2] <= cutoff, reward)` 345 + ` filter!(kv -> ! _edge_any_end_match(kv[1], e1), reward)` 346 + ` filter!(kv -> ! _edge_any_end_match(kv[1], e2), reward)` 347 + ` filter!(kv -> ! _edge_any_end_match(kv[1], e3), reward)` 348 + ` filter!(kv -> ! _edge_any_end_match(kv[1], e4), reward)` 348 349 ` reward[e1] = reward[e2] = reward[e3] = reward[e4] = prevfloat(Inf)` 349 350 351 + ` if length(keys(reward)) == 4 # Nothing left? Skip.` 352 + ` continue` 353 + ` end` 354 + 350 355 ` graph = SimpleGraph(nv(i.matching.graph))` 351 356 ` for e in keys(reward)` 352 357 ` add_edge!(graph, e)`

@@ -1,4 +1,4 @@
 1 - `struct BudgetedLongestPathInstance{T}` 1 + `struct BudgetedElementaryPathInstance{T}` 2 2 ` graph::AbstractGraph{T}` 3 3 ` rewards::Dict{Edge{T}, Float64}` 4 4 ` weights::Dict{Edge{T}, Int}`
@@ -6,12 +6,11 @@
 6 6 ` dst::T` 7 7 8 8 ` budget::Int # weights * solution >= budget` 9 - ` max_weight::Int` 10 9 11 - ` function BudgetedLongestPathInstance(graph::AbstractGraph{T}, rewards::Dict{Edge{T}, Float64},` 12 - ` weights::Dict{Edge{T}, Int}, src::T, dst::T;` 13 - ` budget::Union{Nothing, Int}=nothing,` 14 - ` max_weight::Union{Nothing, Int}=nothing) where T` 10 + ` function BudgetedElementaryPathInstance(graph::AbstractGraph{T}, rewards::Dict{Edge{T}, Float64},` 11 + ` weights::Dict{Edge{T}, Int}, src::T, dst::T;` 12 + ` budget::Union{Nothing, Int}=nothing,` 13 + ` max_weight::Union{Nothing, Int}=nothing) where T` 15 14 ` # Error checking.` 16 15 ` if src == dst` 17 16 ` error("Source node is the same as destination node.")`
@@ -30,7 +29,7 @@
 30 29 ` end` 31 30 32 31 ` # Complete the optional parameters.` 33 - ` if isnothing(max_weight)` 32 + ` if isnothing(max_weight) # Not useful to store, it is just used to compute the max budget if it is not given.` 34 33 ` max_weight = maximum(collect(values(weights)))` 35 34 ` end` 36 35
@@ -40,41 +39,50 @@
 40 39 ` end` 41 40 42 41 ` # Return a new instance.` 43 - ` new{T}(graph, rewards, weights, src, dst, budget, max_weight)` 42 + ` new{T}(graph, rewards, weights, src, dst, budget)` 44 43 ` end` 45 44 `end` 46 45 47 - `graph(i::BudgetedLongestPathInstance{T}) where T = i.graph` 48 - `rewards(i::BudgetedLongestPathInstance{T}) where T = i.rewards` 49 - `weights(i::BudgetedLongestPathInstance{T}) where T = i.weights` 50 - `src(i::BudgetedLongestPathInstance{T}) where T = i.src` 51 - `dst(i::BudgetedLongestPathInstance{T}) where T = i.dst` 52 - `budget(i::BudgetedLongestPathInstance{T}) where T = i.budget` 53 - `max_weight(i::BudgetedLongestPathInstance{T}) where T = i.max_weight` 46 + `graph(i::BudgetedElementaryPathInstance{T}) where T = i.graph` 47 + `rewards(i::BudgetedElementaryPathInstance{T}) where T = i.rewards` 48 + `weights(i::BudgetedElementaryPathInstance{T}) where T = i.weights` 49 + `src(i::BudgetedElementaryPathInstance{T}) where T = i.src` 50 + `dst(i::BudgetedElementaryPathInstance{T}) where T = i.dst` 51 + `budget(i::BudgetedElementaryPathInstance{T}) where T = i.budget` 54 52 55 - `dimension(i::BudgetedLongestPathInstance{T}) where T = ne(graph(i))` 56 - `reward(i::BudgetedLongestPathInstance{T}, u::T, v::T) where T = rewards(i)[Edge(u, v)]` 57 - `weight(i::BudgetedLongestPathInstance{T}, u::T, v::T) where T = weights(i)[Edge(u, v)]` 53 + `# dimension(i::BudgetedElementaryPathInstance{T}) where T = ne(graph(i))` 54 + `reward(i::BudgetedElementaryPathInstance{T}, u::T, v::T) where T = rewards(i)[Edge(u, v)]` 55 + `weight(i::BudgetedElementaryPathInstance{T}, u::T, v::T) where T = weights(i)[Edge(u, v)]` 58 56 59 - `struct BudgetedLongestPathSolution{T}` 60 - ` instance::BudgetedLongestPathInstance{T}` 57 + `struct BudgetedElementaryPathSolution{T}` 58 + ` instance::BudgetedElementaryPathInstance{T}` 61 59 ` path::Vector{Edge{T}}` 62 60 ` states::Dict{Tuple{T, Int}, Float64}` 63 61 ` solutions::Dict{Tuple{T, Int}, Vector{Edge{T}}}` 64 62 `end` 65 63 66 - `function paths_all_budgets(s::BudgetedLongestPathSolution{T}, max_budget::Int) where T` 64 + `function paths_all_budgets(s::BudgetedElementaryPathSolution{T}, max_budget::Int) where T` 65 + ` if max_budget > budget(s.instance)` 66 + ` @warn "The asked maximum budget \$max_budget is higher than the instance budget \$(budget(s.instance)). Therefore, some values have not been computed and are unavailable."` 67 + ` end` 68 + 69 + ` mb = min(max_budget, budget(s.instance))` 67 70 ` return Dict{Int, Vector{Edge{T}}}(` 68 - ` budget => s.solutions[s.instance.dst, budget] for budget in 0:max_budget)` 71 + ` budget => s.solutions[s.instance.dst, budget] for budget in 0:mb)` 69 72 `end` 70 73 71 - `function paths_all_budgets_as_tuples(s::BudgetedLongestPathSolution{T}, max_budget::Int) where T` 74 + `function paths_all_budgets_as_tuples(s::BudgetedElementaryPathSolution{T}, max_budget::Int) where T` 75 + ` if max_budget > budget(s.instance)` 76 + ` @warn "The asked maximum budget \$max_budget is higher than the instance budget \$(budget(s.instance)). Therefore, some values have not been computed and are unavailable."` 77 + ` end` 78 + 79 + ` mb = min(max_budget, budget(s.instance))` 72 80 ` return Dict{Int, Vector{Tuple{T, T}}}(` 73 81 ` budget => [(src(e), dst(e)) for e in s.solutions[s.instance.dst, budget]]` 74 - ` for budget in 0:max_budget)` 82 + ` for budget in 0:mb)` 75 83 `end` 76 84 77 - `function budgeted_lp_dp(i::BudgetedLongestPathInstance{T}) where T` 85 + `function budgeted_lp_dp(i::BudgetedElementaryPathInstance{T}) where T` 78 86 ` V = Dict{Tuple{T, Int}, Float64}()` 79 87 ` S = Dict{Tuple{T, Int}, Vector{Edge{T}}}()` 80 88
@@ -98,7 +106,7 @@
 98 106 99 107 ` # Dynamic part.` 100 108 ` for β in 1:budget(i)` 101 - ` # Loop needed when at least a weight is equal to zero. TODO: remove it when all weights are nonzero? ` 109 + ` # Loop needed when at least a weight is equal to zero. TODO: remove it when all weights are nonzero?` 102 110 ` while true` 103 111 ` changed = false` 104 112
@@ -143,5 +151,5 @@
 143 151 ` end` 144 152 ` end` 145 153 146 - ` return BudgetedLongestPathSolution(i, S[dst(i), budget(i)], V, S)` 154 + ` return BudgetedElementaryPathSolution(i, S[dst(i), budget(i)], V, S)` 147 155 `end`

@@ -30,7 +30,7 @@
 30 30 ` reward::Dict{Tuple{Int, Int}, Float64},` 31 31 ` weights::Dict{Tuple{Int, Int}, Int},` 32 32 ` budget::Int)` 33 - ` i = BudgetedLongestPathInstance(solver.graph,` 33 + ` i = BudgetedElementaryPathInstance(solver.graph,` 34 34 ` _tuple_dict_to_edge_dict(reward), _tuple_dict_to_edge_dict(weights),` 35 35 ` solver.source, solver.destination, budget=budget)` 36 36 ` s = budgeted_lp_dp(i).path`
@@ -41,7 +41,7 @@
 41 41 ` reward::Dict{Tuple{Int, Int}, Float64},` 42 42 ` weights::Dict{Tuple{Int, Int}, Int},` 43 43 ` max_budget::Int)` 44 - ` i = BudgetedLongestPathInstance(solver.graph,` 44 + ` i = BudgetedElementaryPathInstance(solver.graph,` 45 45 ` _tuple_dict_to_edge_dict(reward), _tuple_dict_to_edge_dict(weights),` 46 46 ` solver.source, solver.destination, budget=max_budget)` 47 47 ` return paths_all_budgets_as_tuples(budgeted_lp_dp(i), max_budget)`

@@ -26,7 +26,7 @@
 26 26 ` MSetInstance, MSetSolution, dimension, m, value, values, msets_greedy, msets_dp, msets_lp,` 27 27 ` BudgetedMSetInstance, BudgetedMSetSolution, weight, weights, budget, max_weight, items, items_all_budgets, budgeted_msets_dp, budgeted_msets_lp, budgeted_msets_lp_select, budgeted_msets_lp_all,` 28 28 ` ElementaryPathInstance, ElementaryPathSolution, graph, costs, src, dst, cost, lp_dp,` 29 - ` BudgetedLongestPathInstance, BudgetedLongestPathSolution, rewards, reward, budgeted_lp_dp,` 29 + ` BudgetedElementaryPathInstance, BudgetedElementaryPathSolution, rewards, reward, budgeted_lp_dp,` 30 30 ` SpanningTreeInstance, SpanningTreeSolution, st_prim,` 31 31 ` BudgetedSpanningTreeInstance, BudgetedSpanningTreeSolution, BudgetedSpanningTreeLagrangianSolution, SimpleBudgetedSpanningTreeSolution, _budgeted_spanning_tree_compute_value, _budgeted_spanning_tree_compute_weight, st_prim_budgeted_lagrangian, st_prim_budgeted_lagrangian_search, _solution_symmetric_difference, _solution_symmetric_difference_size, st_prim_budgeted_lagrangian_refinement, st_prim_budgeted_lagrangian_approx_half,` 32 32 ` BipartiteMatchingInstance, BipartiteMatchingSolution, matching_hungarian, BudgetedBipartiteMatchingInstance, BudgetedBipartiteMatchingSolution, BudgetedBipartiteMatchingLagrangianSolution, SimpleBudgetedBipartiteMatchingSolution, matching_hungarian_budgeted_lagrangian, matching_hungarian_budgeted_lagrangian_search, matching_hungarian_budgeted_lagrangian_refinement, matching_hungarian_budgeted_lagrangian_approx_half`
@@ -215,8 +215,8 @@
 215 215 216 216 ` ## Combinatorial algorithms. TODO: put this in another package.` 217 217 ` include("algos/helpers.jl")` 218 - ` include("algos/lp.jl")` 219 - ` include("algos/lp_budgeted.jl")` 218 + ` include("algos/ep.jl")` 219 + ` include("algos/ep_budgeted.jl")` 220 220 ` include("algos/matching.jl")` 221 221 ` include("algos/matching_budgeted.jl")` 222 222 ` include("algos/msets.jl")` 223 223 `imilarity index 100%` 224 224 `ename from src/algos/lp.jl` 225 225 `ename to src/algos/ep.jl` 226 226 `imilarity index 60%` 227 227 `ename from src/algos/lp_budgeted.jl` 228 228 `ename to src/algos/ep_budgeted.jl`
Files Coverage
src 67.42%
Project Totals (35 files) 67.42%