Skip to content

Commit

Permalink
Removing unecessary comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jkhamphousone committed Jul 26, 2024
1 parent 72075e0 commit 6c26178
Show file tree
Hide file tree
Showing 13 changed files with 32 additions and 256 deletions.
8 changes: 3 additions & 5 deletions src/benders_rrsp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ function rrspcreatebenders_modellazy(filename, inst, pars; optimizer)
d = inst.d
start_time = time()

# o, r, rp, s, bar_offset = instance_transform_improved(inst, pars.inst_trans)


m = Model(optimizer)
Expand Down Expand Up @@ -396,7 +395,7 @@ function benders_st_optimize_lazy!(m, x, y, f, F, B, inst, pars, start_time; opt

x′, sp_cost = compute_sp_res(x̂, ŷ, V, n, tildeV, rp, s)[[1, 3]] # TODO create simpler functions that do only compute backup ring cost and ring cost
hubs, master_ring_cost =
compute_master_hubs_and_cost(x̂, V, n, tildeV, o, r)
compute_master_hubs_and_cost(x̂, V, n, o, r)
x_two_opt, x′_two_opt, two_opt_cost = run_two_opt_wiki(
x̂,
x′,
Expand Down Expand Up @@ -520,7 +519,7 @@ function benders_st_optimize_lazy!(m, x, y, f, F, B, inst, pars, start_time; opt

x′, sp_cost = compute_sp_res(x̂, ŷ, V, n, tildeV, rp, s)[[1, 3]] # TODO create simpler functions that do only compute backup ring cost and ring cost
hubs, master_ring_cost =
compute_master_hubs_and_cost(x̂, V, n, tildeV, o, r)
compute_master_hubs_and_cost(x̂, V, n, o, r)
x_two_opt, x′_two_opt, two_opt_cost = run_two_opt_wiki(
x̂,
x′,
Expand Down Expand Up @@ -844,8 +843,7 @@ function compute_sp_res(x̂, ŷ, V, n, tildeV, r, s)
return x′, y_sp, sp_cost
end

function compute_master_hubs_and_cost(x_opt, V, n, tildeV, o, r)
# TODO supprimer tildeV
function compute_master_hubs_and_cost(x_opt, V, n, o, r)
master_cost = 0.0
H = Int[]
for i in V
Expand Down
30 changes: 1 addition & 29 deletions src/benders_subproblem_poly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,35 +125,7 @@ function debug_RingStarProblems(
println()
end
end
# for i in V
# for j in tildeV
# for k in i+1:n+1
# if i != j && j != k
# if β[i,j,k] > 0 || β_poly[i,j,k] > 0
# println("β[$i, $j, $k] = $(β[i,j,k]), β_poly[$i, $j, $k] = $(β_poly[i,j,k])")
# end
# end
# end
# end
# end
# for i in V
# for j in setdiff(tildeV, i)
# if γ[i,j] > 0 || γ_poly[i,j] > 0
# println("γ[$i, $j] = $(γ[i,j]), γ_poly[$i,$j] = $(γ_poly[i,j])")
# end
# end
# end
# for i in V
# for j in tildeV
# for k in i+1:n+1
# if i != j && j != k
# if δ[i,j,k] > 0 || δ_poly[i,j,k] > 0 && !(i == 1 && k == n+1)
# println("δ[$i, $j, $k] = $(δ[i,j,k]), δ_poly[$i, $j, $k] = $(δ_poly[i,j,k]) cost[$(inst.d′[i,k == n+1 ? 1 : k])]")
# end
# end
# end
# end
# end

for i in V
for j in setdiff(V, i)
if ζ[i, j] > 0 || ζ_poly[i, j] > 0
Expand Down
45 changes: 8 additions & 37 deletions src/create_blossom_ineaqulities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function create_blossom_inequalities(cb_data, x, y, n, nblossom_pair_inequality)
F_odd = 0
end
if length(δU) > 0
βU, F = compute_βU(δU, c_m, c′_m, F_odd) # This function returns beta(U) as in (10) in the paper of Letchford and Theis, "Odd minimum cut sets and b-matching revisited", see page 1484. It also returns F, the associated subset of edges.
βU, F = compute_βU(δU, c_m, c′_m, F_odd) #
if βU < r
best_F = F
best_U = U
Expand All @@ -98,32 +98,23 @@ function create_blossom_inequalities(cb_data, x, y, n, nblossom_pair_inequality)
2 + 2sum(y[i, i] for i in setdiff(best_U, 1, n + 1)) -
floor((length(best_F) - 1) / 2.0)
)
# @show "type 1"
# @show con
# @show best_U
# @show best_F

elseif !(1 in best_U) && !(n + 1 in best_U)
con = @build_constraint(
sum(sum(x[i, j] for i in best_U if i < j) for j in best_U) +
sum(x[mima(f[1], f[2])] for f in best_F) <=
2sum(y[i, i] for i in setdiff(best_U, 1, n + 1)) -
floor((length(best_F) - 1) / 2.0)
)
# @show "type 2"
# @show con
# @show best_U
# @show best_F

else # either s or t is in best_U, but not both of them, this is a blossom pair inequality
nblossom_pair_inequality += 1
con = @build_constraint(
sum(sum(x[i, j] for i in best_U if i < j) for j in best_U) +
sum(x[mima(f[1], f[2])] for f in best_F) <=
2sum(y[i, i] for i in setdiff(best_U, 1, n + 1)) - div(length(best_F), 2)
)
# @show "type 3 (blossom pair)"
# @show con
# @show best_U
# @show best_F

end
return con, nblossom_pair_inequality
end
Expand All @@ -134,6 +125,7 @@ end
compute_βU(δU, c_m, c′_m, F_odd)
This is step 5 of Algorithm 2
Returns beta(U) as in (10) in the paper of Letchford and Theis, "Odd minimum cut sets and b-matching revisited", see page 1484. It also returns F, the associated subset of edges.
"""
function compute_βU(δU, c_m, c′_m, F_odd)
F = Tuple{Int,Int}[]
Expand Down Expand Up @@ -186,26 +178,17 @@ function create_cut_part_one(G, E_T, edge, n)
incidence_matrix[edge[1], edge[2]] = 0 # Removing edge
incidence_matrix[edge[2], edge[1]] = 0

# for i in 1:n+1
# for j in 1:n+1
# if incidence_matrix[i,j] == 1
# @show i,j
# end
# end
# end

g = SimpleGraph(incidence_matrix)
X = connected_components(g)
if length(X) > 2
@show X
println("Cut tree")
@show E_T
# println()
end
for i in X[1]
for j in X[2]
# if has_edge(G, i, j)
push!(δU, (i, j))
# end
end
end
return δU, X[1]
Expand All @@ -214,24 +197,15 @@ end

function compute_cut_tree(n, G, c_min_m)
p = ones(Int, n + 1)
# for i in 1:n+1
# for j in i+1:n+1
# if capacity_matrix[i,j] > 0
# println("$i => $j [$(capacity_matrix[i,j])] ; ")
# end
# end
# println()
# end



fl = zeros(Float64, n + 1)
fl[1] = -1 # Should not be used
for s = 2:n+1
t = p[s]
part1, part2, flow = GraphsFlows.mincut(G, s, t, c_min_m, EdmondsKarpAlgorithm())
# @show part1
# @show part2
# @show flow

X = s in part1 ? part1 : part2
fl[s] = flow
for i = 1:n+1
Expand All @@ -247,12 +221,9 @@ function compute_cut_tree(n, G, c_min_m)
fl[t] = flow
end
end
# println("Cut tree")
E_T = Tuple{Int,Int}[]
for i = 2:n+1
push!(E_T, (i, p[i]))
# print("$i => $(p[i]) [$(fl[i])],\n")
end
# println()
return E_T, fl
end
141 changes: 6 additions & 135 deletions src/create_subtour_constraint.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
function to add Labbe subtour elimination constraints by lazy constraints
Caution, y is a 2-dimensional matrix, as x
"""
function create_subtour_constraint_lazy_Labbe(
m,
cb_data,
Expand All @@ -7,8 +11,7 @@ function create_subtour_constraint_lazy_Labbe(
ring_edges,
nsubtour_cons,
)
# function to add Labbe subtour elimination constraints by lazy constraints
# caution, y is a 2-dimensional matrix, as x

visited = falses(n + 1) # visited[i] = true iff i is a hub reachable from the depot
N = [[] for i 1:n+1]
active_nodes = Set(Int[]) # Set of all hubs
Expand Down Expand Up @@ -138,7 +141,6 @@ end

function create_connectivity_cut_strategy_1(cb_data, x, y, V, n, pars)
# """ TODO
# Discribing strategy_number in [1,2,3,4]
# ``\begin{itemize}
# \item The first one is to solve one maximum-flow problem for each vertex $i\in V\backslash\{1\}:y_{ii}>0$ and to add only the connectivity cut that maximizes $2y_{ii} - f_i$. This strategy favors the most violated cut, in an attempt to keep deep cuts.
# \item The second strategy is to stop solving more flow problems as soon as a vertex $i\in V\backslash\{1\}:y_{ii}>0$ such that $f_i < 2 y_{ii}$ is found. In practice, because of numerical imprecision, we need a given threshold $\varepsilon > 0$ to be exceeded, \textit{i.e.}, we must have $f_i + \varepsilon \le 2 y_{ii}$ for the cut to be considered violated. This strategy favors speed generation for connectivity cuts. But it seems that separating these connectivity cuts is very fast (at least for small instances).
Expand Down Expand Up @@ -191,135 +193,7 @@ function create_connectivity_cut_strategy_1(cb_data, x, y, V, n, pars)
end
return -1, []
end
function create_connectivity_cut_strategy_2(cb_data, x, y, V, n, pars)
# """ TODO
# Discribing strategy_number in [1,2,3,4]
# ``\begin{itemize}
# \item The first one is to solve one maximum-flow problem for each vertex $i\in V\backslash\{1\}:y_{ii}>0$ and to add only the connectivity cut that maximizes $2y_{ii} - f_i$. This strategy favors the most violated cut, in an attempt to keep deep cuts.
# \item The second strategy is to stop solving more flow problems as soon as a vertex $i\in V\backslash\{1\}:y_{ii}>0$ such that $f_i < 2 y_{ii}$ is found. In practice, because of numerical imprecision, we need a given threshold $\varepsilon > 0$ to be exceeded, \textit{i.e.}, we must have $f_i + \varepsilon \le 2 y_{ii}$ for the cut to be considered violated. This strategy favors speed generation for connectivity cuts. But it seems that separating these connectivity cuts is very fast (at least for small instances).
# \item The third strategy is to solve the max-flow problem for all the vertices in $V\backslash\{1\}$, and to keep only the inequality that is associated to a subset $S \subset V$ such that $\min(|S|,|V\backslash S|)$ is minimum, among the inequalities that are violated by an amount larger than a given threshold $\varepsilon$. Doing so favors inequalities that involve a minimum number of $x$ variables, avoiding the generation of \textit{dense} cuts, which are known to be detrimental in branch-and-cut solution methods (see \cite{MendezDiaz2008} Section 5.1, and \url{https://arxiv.org/pdf/2001.00858} page 11). Indeed, the worst case occurs when $S$ and $V\backslash S$ have the same cardinality: the corresponding connectivity cut involves $|\delta^+(S)|=\left(\frac{1}{2}n\right)^2$ $x$ variables, whereas the best case occurs when $S$ or $V\backslash S$ has cardinality one, leading to a connectivity cut involving $|\delta^+(S)|=n-1$ $x$ variables only. This strategy aims at maximizing the efficiency of connectivity cuts to keep the solver fast when they are added.
#
# \item The fourth strategy is to stop generating connectivity cuts when we reach a given threshold. Again, this limits the nasty impact on speed of adding too many cuts.
# \end{itemize}
# ``
# """
ε = 10e-16
x_m = zeros(Float64, n, n)
y_m = Float64[callback_value(cb_data, y[i]) for i 1:n]
flow_graph = DiGraph(n)
capacity_matrix = zeros(Float64, n, n)
for i 1:n
for j i+1:n
x_m[i, j] = callback_value(cb_data, x[i, j])
if x_m[i, j] > ε
add_edge!(flow_graph, i, j)
add_edge!(flow_graph, j, i)
capacity_matrix[i, j] = x_m[i, j]
capacity_matrix[j, i] = x_m[i, j]
end
end
end
max_violated_node = -1
max_current_violation = 0.0

bestf, bestpart1, bestpart2 = 0.0, Int[], Int[]
for i 2:n
if y_m[i] > ε
part1, part2, flow = GraphsFlows.mincut(
flow_graph,
1,
i,
capacity_matrix,
EdmondsKarpAlgorithm(),
)
if max_current_violation < 2y_m[i] - flow
max_violated_node = i
max_current_violation = 2y_m[i] - flow
bestf = flow
bestpart1 = part1
bestpart2 = part2
break
end
end
end

if max_current_violation > pars.uctolerance
con = @build_constraint(
sum(sum(x[mima(j, k)] for j in bestpart1) for k in bestpart2) >=
2y[max_violated_node]
)

return max_current_violation, con
end
return -1, []
end
function create_connectivity_cut_strategy_3(cb_data, x, y, V, n, pars)
# """ TODO
# Discribing strategy_number in [1,2,3,4]
# ``\begin{itemize}
# \item The first one is to solve one maximum-flow problem for each vertex $i\in V\backslash\{1\}:y_{ii}>0$ and to add only the connectivity cut that maximizes $2y_{ii} - f_i$. This strategy favors the most violated cut, in an attempt to keep deep cuts.
# \item The second strategy is to stop solving more flow problems as soon as a vertex $i\in V\backslash\{1\}:y_{ii}>0$ such that $f_i < 2 y_{ii}$ is found. In practice, because of numerical imprecision, we need a given threshold $\varepsilon > 0$ to be exceeded, \textit{i.e.}, we must have $f_i + \varepsilon \le 2 y_{ii}$ for the cut to be considered violated. This strategy favors speed generation for connectivity cuts. But it seems that separating these connectivity cuts is very fast (at least for small instances).
# \item The third strategy is to solve the max-flow problem for all the vertices in $V\backslash\{1\}$, and to keep only the inequality that is associated to a subset $S \subset V$ such that $\min(|S|,|V\backslash S|)$ is minimum, among the inequalities that are violated by an amount larger than a given threshold $\varepsilon$. Doing so favors inequalities that involve a minimum number of $x$ variables, avoiding the generation of \textit{dense} cuts, which are known to be detrimental in branch-and-cut solution methods (see \cite{MendezDiaz2008} Section 5.1, and \url{https://arxiv.org/pdf/2001.00858} page 11). Indeed, the worst case occurs when $S$ and $V\backslash S$ have the same cardinality: the corresponding connectivity cut involves $|\delta^+(S)|=\left(\frac{1}{2}n\right)^2$ $x$ variables, whereas the best case occurs when $S$ or $V\backslash S$ has cardinality one, leading to a connectivity cut involving $|\delta^+(S)|=n-1$ $x$ variables only. This strategy aims at maximizing the efficiency of connectivity cuts to keep the solver fast when they are added.
#
# \item The fourth strategy is to stop generating connectivity cuts when we reach a given threshold. Again, this limits the nasty impact on speed of adding too many cuts.
# \end{itemize}
# ``
# """
ε = 10e-16
x_m = zeros(Float64, n, n)
y_m = Float64[callback_value(cb_data, y[i]) for i 1:n]
flow_graph = DiGraph(n)
capacity_matrix = zeros(Float64, n, n)
for i 1:n
for j i+1:n
x_m[i, j] = callback_value(cb_data, x[i, j])
if x_m[i, j] > ε
add_edge!(flow_graph, i, j)
add_edge!(flow_graph, j, i)
capacity_matrix[i, j] = x_m[i, j]
capacity_matrix[j, i] = x_m[i, j]
end
end
end
max_violated_node = -1
max_current_violation = 0.0

bestf, bestF, bestlabels = 0.0, zeros(Float64, n, n), ones(Int64, n)
for i 2:n
if y_m[i] > ε
flow, F, labels = maximum_flow(
flow_graph,
1,
i,
capacity_matrix,
algorithm = BoykovKolmogorovAlgorithm(),
)
if max_current_violation < 2y_m[i] - flow
if sum(labels .== 1) <= sum(bestlabels .== 1)
max_violated_node = i
max_current_violation = 2y_m[i] - flow
bestf = flow
bestF = F
bestlabels = labels
end
end
end
end
if max_current_violation > pars.uctolerance
con = @build_constraint(
sum(
sum(
x[j, k] for j in V if j < k && (
(bestlabels[j] == 1 && bestlabels[k] != 1) ||
(bestlabels[k] == 1 && bestlabels[j] != 1)
)
) for k in V
) >= 2y[max_violated_node]
)
return max_current_violation, con
end
return -1, []
end
function createconnectivitycut(cb_data, x, y, V, n, nconnectivity_cuts, pars)
# """ TODO
# Discribing strategy_number in [1,2,3,4]
Expand All @@ -333,10 +207,7 @@ function createconnectivitycut(cb_data, x, y, V, n, nconnectivity_cuts, pars)
# ``
# """
if nconnectivity_cuts < pars.ucstrat_limit
# if nconnectivity_cuts <= 1999
# if nconnectivity_cuts%100 == 0
# println("Generating a user cut")
# end

return create_connectivity_cut_strategy_1(cb_data, x, y, V, n, pars)
end
return -1, []
Expand Down
1 change: 1 addition & 0 deletions src/explore_F.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ function write_tikz_list_Fm_Sm(



# TODO: determine if the following should be removed
# str *= raw"\begin{figure}[ht!]
# \begin{center}
# \begin{tikzpicture}[scale=.2cm, xscale=2cm]
Expand Down
Loading

0 comments on commit 6c26178

Please sign in to comment.