From 7d4dcae0a6ada465e269311b53836e01e37cde14 Mon Sep 17 00:00:00 2001
From: dcradu <dcradu@uliege.be>
Date: Sun, 18 Apr 2021 22:09:07 +0200
Subject: [PATCH] update greedy algorithms (time gains)

---
 src/jl/MCP_heuristics.jl   | 60 +++++++++++++++++++-------------------
 src/jl/SitingHeuristics.jl | 39 ++-----------------------
 2 files changed, 32 insertions(+), 67 deletions(-)

diff --git a/src/jl/MCP_heuristics.jl b/src/jl/MCP_heuristics.jl
index 6e01c8f..035f66c 100644
--- a/src/jl/MCP_heuristics.jl
+++ b/src/jl/MCP_heuristics.jl
@@ -334,14 +334,14 @@ end
 function threshold_greedy_algorithm(D::Array{Float64,2}, c::Float64, n::Float64)
 
   W, L = size(D)
-  x_incumbent = zeros(Float64, L)
+  n = convert(Int64, n)
   ind_compl_incumbent = [i for i in 1:L]
-  ind_incumbent = []
+  ind_incumbent = Vector{Int64}(undef, n)
   Dx_incumbent = zeros(Float64, W)
-  y_incumbent = zeros(Float64, W)
   obj_incumbent = 0
   Dx_tmp = Vector{Float64}(undef, W)
   y_tmp = Vector{Float64}(undef, W)
+  ind_candidate_list = zeros(Int64, L)
   locations_added, threshold = 0, 0
   @inbounds while locations_added < n
     if locations_added < c
@@ -350,28 +350,29 @@ function threshold_greedy_algorithm(D::Array{Float64,2}, c::Float64, n::Float64)
     else
       obj_candidate = obj_incumbent
     end
-    ind_candidate_list = Vector{Int64}(undef, 0)
-    @inbounds for ind in setdiff(ind_compl_incumbent, ind_incumbent)
+    ind_candidate_pointer = 1
+    @inbounds for ind in ind_compl_incumbent
         Dx_tmp .= Dx_incumbent .+ view(D, :, ind)
         y_tmp .= Dx_tmp .>= threshold
         obj_tmp = sum(y_tmp)
         if obj_tmp > obj_candidate
-          ind_candidate_list = [ind]
+          ind_candidate_pointer = 1
+          ind_candidate_list[ind_candidate_pointer] = ind
           obj_candidate = obj_tmp
+          ind_candidate_pointer += 1
         elseif obj_tmp == obj_candidate
-          ind_candidate_list = union(ind, ind_candidate_list)
+          ind_candidate_list[ind_candidate_pointer] = ind
+          ind_candidate_pointer += 1
         end
     end
-    ind_candidate = sample(ind_candidate_list)
-    ind_incumbent = union(ind_incumbent, ind_candidate)
+    ind_candidate = sample(view(ind_candidate_list, 1:ind_candidate_pointer-1))
+    ind_incumbent[locations_added+1] = ind_candidate
+    filter!(a -> a != ind_candidate, ind_compl_incumbent)
     Dx_incumbent .= Dx_incumbent .+ view(D, :, ind_candidate)
-    y_incumbent .= Dx_incumbent .>= c
-    obj_incumbent = sum(y_incumbent)
+    obj_incumbent = obj_candidate
     locations_added += 1
   end
-  x_incumbent[ind_incumbent] .= 1.
-  return x_incumbent, obj_incumbent
-
+  return ind_incumbent, obj_incumbent
 end
 
 function time_threshold_greedy_algorithm(D::Array{Float64,2}, c::Float64, n::Float64)
@@ -397,16 +398,15 @@ end
 function stochastic_threshold_greedy_algorithm(D::Array{Float64,2}, c::Float64, n::Float64, p::Float64)
 
   W, L = size(D)
-  s = convert(Int64, round((L/n)*p))
-  x_incumbent = zeros(Float64, L)
+  s = convert(Int64, round(L*p))
   random_ind_set = Vector{Int64}(undef, s)
   ind_compl_incumbent = [i for i in 1:L]
-  ind_incumbent = []
+  ind_incumbent = Vector{Int64}(undef, convert(Int64, n))
   Dx_incumbent = zeros(Float64, W)
-  y_incumbent = zeros(Float64, W)
   obj_incumbent = 0
   Dx_tmp = Vector{Float64}(undef, W)
   y_tmp = Vector{Float64}(undef, W)
+  ind_candidate_list = zeros(Int64, L)
   locations_added, threshold = 0, 0
   @inbounds while locations_added < n
     if locations_added < c
@@ -415,30 +415,30 @@ function stochastic_threshold_greedy_algorithm(D::Array{Float64,2}, c::Float64,
     else
       obj_candidate = obj_incumbent
     end
-    ind_candidate_list = Vector{Int64}(undef, 0)
-    random_ind_set .= sample(ind_compl_incumbent, s, replace=false)
+    ind_candidate_pointer = 1
+    sample!(ind_compl_incumbent, random_ind_set, replace=false)
     @inbounds for ind in random_ind_set
         Dx_tmp .= Dx_incumbent .+ view(D, :, ind)
         y_tmp .= Dx_tmp .>= threshold
         obj_tmp = sum(y_tmp)
         if obj_tmp > obj_candidate
-          ind_candidate_list = [ind]
+          ind_candidate_pointer = 1
+          ind_candidate_list[ind_candidate_pointer] = ind
           obj_candidate = obj_tmp
+          ind_candidate_pointer += 1
         elseif obj_tmp == obj_candidate
-          ind_candidate_list = union(ind, ind_candidate_list)
+          ind_candidate_list[ind_candidate_pointer] = ind
+          ind_candidate_pointer += 1
         end
     end
-    ind_candidate = sample(ind_candidate_list)
-    ind_incumbent = union(ind_incumbent, ind_candidate)
-    ind_compl_incumbent = setdiff(ind_compl_incumbent, ind_candidate)
+    ind_candidate = sample(view(ind_candidate_list, 1:ind_candidate_pointer-1))
+    ind_incumbent[locations_added+1] = ind_candidate
+    filter!(a -> a != ind_candidate, ind_compl_incumbent)
     Dx_incumbent .= Dx_incumbent .+ view(D, :, ind_candidate)
-    y_incumbent .= Dx_incumbent .>= c
-    obj_incumbent = sum(y_incumbent)
+    obj_incumbent = obj_candidate
     locations_added += 1
   end
-  x_incumbent[ind_incumbent] .= 1.
-  return x_incumbent, obj_incumbent
-
+  return ind_incumbent, obj_incumbent
 end
 
 function stochastic_threshold_greedy_algorithm_trajectory(D::Array{Float64,2}, c::Float64, n::Float64, p::Float64)
diff --git a/src/jl/SitingHeuristics.jl b/src/jl/SitingHeuristics.jl
index 7790a32..6b9c88c 100644
--- a/src/jl/SitingHeuristics.jl
+++ b/src/jl/SitingHeuristics.jl
@@ -45,7 +45,7 @@ function main_MIRSA(index_dict, deployment_dict, D, c, N, I, E, T_init, R, run,
   if run == "MIR"
 
     x_sol, LB_sol, obj_sol = Array{Float64, 2}(undef, R, L), Array{Float64, 1}(undef, R), Array{Float64, 2}(undef, R, I)
-    x_init = solve_MILP_partitioning(D, c, n_partitions, index_dict, "Gurobi")
+    x_init = solve_MILP(D, c, n, "Gurobi")
 
     for r = 1:R
       x_sol[r, :], LB_sol[r], obj_sol[r, :] = simulated_annealing_local_search(D, c, n, N, I, E, x_init, T_init, legacy_index)
@@ -56,7 +56,7 @@ function main_MIRSA(index_dict, deployment_dict, D, c, N, I, E, T_init, R, run,
     x_sol, LB_sol, obj_sol = Array{Float64, 2}(undef, R, L), Array{Float64, 1}(undef, R), Array{Float64, 2}(undef, R, I)
     x_init = zeros(Int64, L)
     ind_set = [l for l in 1:L]
-    n_while = n_partitions[1]
+    n_while = n
 
     while n_while > 0
       loc = sample(ind_set)
@@ -153,38 +153,3 @@ function main_RAND(deployment_dict, D, c, I, R, run)
   return x_sol, LB_sol
 
 end
-
-# Local Search algorithm
-function main_LSEA(index_dict, deployment_dict, D, c, N, I, E, run)
-
-  index_dict = Dict([(convert(Int64, k), convert(Int64, index_dict[k])) for k in keys(index_dict)])
-  deployment_dict = Dict([(convert(Int64, k), convert(Int64, deployment_dict[k])) for k in keys(deployment_dict)])
-  D  = convert.(Float64, D)
-
-  c = convert(Float64, c)
-  N = convert(Int64, N)
-  I = convert(Int64, I)
-  E = convert(Int64, E)
-  T_init = convert(Float64, T_init)
-  R = convert(Int64, R)
-  run = string(run)
-
-  W, L = size(D)
-
-  P = maximum(values(index_dict))
-  n_partitions = [deployment_dict[i] for i in 1:P]
-
-  if run == "GLS"
-    x_sol, LB_sol, obj_sol = Array{Float64, 2}(undef, R, L), Array{Float64, 1}(undef, R), Array{Float64, 2}(undef, R, I)
-    x_init = solve_MILP_partitioning(D, c, n_partitions, index_dict, "Gurobi")
-    for r = 1:R
-      x_sol[r, :], LB_sol[r], obj_sol[r, :] = greedy_local_search_partition(D, c, n_partitions, N, I, E, x_init, index_dict)
-    end
-  else
-    println("No such run available.")
-    throw(ArgumentError)
-  end
-
-  return x_sol, LB_sol, obj_sol
-
-end
-- 
GitLab