diff --git a/octave/main.m b/octave/main.m index aba79b9..830353f 100755 --- a/octave/main.m +++ b/octave/main.m @@ -11,61 +11,59 @@ function print_s(s) fprintf('\n') end -function ret = subseq_load (sol, info) +function ret = update_subseq_info_matrix (sol, info, data) tern1 = [1, 0]; tern2 = [0, 1]; - for i = 1:info.dimen+1 + for i = 1:data.dimen+1 k = 1 - i - tern1((i ~= 1) + 1); sol.seq(i, i, info.T) = 0.0; sol.seq(i, i, info.C) = 0.0; sol.seq(i, i, info.W) = tern2((i ~= 1) + 1); - for j = i+1:info.dimen+1 + for j = i+1:data.dimen+1 j_prev = j-1; - sol.seq(i, j, info.T) = info.cost(sol.s(j_prev), sol.s(j)) + sol.seq(i, j_prev, info.T); + sol.seq(i, j, info.T) = data.cost(sol.s(j_prev), sol.s(j)) + sol.seq(i, j_prev, info.T); sol.seq(i, j, info.C) = sol.seq(i, j, info.T) + sol.seq(i, j_prev, info.C); sol.seq(i, j, info.W) = j+k; end end - sol.cost = sol.seq(1, info.dimen+1, info.C); + sol.cost = sol.seq(1, data.dimen+1, info.C); ret = sol; end -function arr = sort(arr, r, info) +function arr = sort(arr, r, data) sz = size(arr); sz = sz(2); - arr = quicksort(arr, 1, sz, r, info); + arr = quicksort(arr, 1, sz, r, data); end -function arr = quicksort(arr, left, right, r, info) +function arr = quicksort(arr, left, right, r, data) if left < right - [arr, pivotIndex] = partition(arr, left, right, r, info); - arr = quicksort(arr, left, pivotIndex - 1, r, info); - arr = quicksort(arr, pivotIndex + 1, right, r, info); + [arr, pivotIndex] = partition(arr, left, right, r, data); + arr = quicksort(arr, left, pivotIndex - 1, r, data); + arr = quicksort(arr, pivotIndex + 1, right, r, data); end end -function [arr, pivotIndex] = partition(arr, left, right, r, info) +function [arr, pivotIndex] = partition(arr, left, right, r, data) pivotValue = arr(right); i = left - 1; for j = left:right - 1 - if info.cost(r, arr(j)) < info.cost(r, pivotValue) + if data.cost(r, arr(j)) < data.cost(r, pivotValue) i = i + 1; - % Troca arr(i) e arr(j) [arr(i), arr(j)] = deal(arr(j), arr(i)); end end - % Troca o pivĂ´ [arr(i + 1), arr(right)] = deal(arr(right), arr(i + 1)); pivotIndex = i + 1; end -function [ret, index_new] = construction(alpha, info) +function [ret, index_new] = construction(alpha, data) s(1) = 1; - for i = 1:info.dimen-1 + for i = 1:data.dimen-1 cL(i) = i+1; end @@ -73,16 +71,14 @@ function print_s(s) size_cL = size(cL); size_cL = size_cL(2); while (size_cL > 0) - cL = sort(cL, r, info); + cL = sort(cL, r, data); rng = ceil(size_cL * alpha); RND = rand(1); - %RND = [RND, RND+0.0000000001]((RND < 0.0000000001) + 1); index = ceil(rng * RND); - index = info.rnd(info.rnd_index) + 1; - %info.rnd(info.rnd_index); - info.rnd_index = info.rnd_index+1; + index = data.rnd(data.rnd_index) + 1; + data.rnd_index = data.rnd_index+1; cN = cL(index); @@ -98,7 +94,7 @@ function print_s(s) size_s = size_s(2); s(size_s+1) = 1; ret = s; - index_new = info.rnd_index; + index_new = data.rnd_index; end function ret = swap(s, i, j) @@ -130,7 +126,7 @@ function print_s(s) ret = s; end -function [solut_new, ret] = search_swap(solut, info) +function [solut_new, ret] = search_swap(solut, info, data) cost_best = info.fmax; cost_new = 0.0; cost_concat_1 = 0.0; @@ -138,16 +134,16 @@ function print_s(s) cost_concat_3 = 0.0; cost_concat_4 = 0.0; - for i = 2:info.dimen-1 + for i = 2:data.dimen-1 i_prev = i-1; i_next = i+1; - cost_concat_1 = solut.seq(1, i_prev, info.T) + info.cost(solut.s(i_prev), solut.s(i_next)); - cost_concat_2 = cost_concat_1 + solut.seq(i, i_next, info.T) + info.cost(solut.s(i), solut.s(i_next+1)); + cost_concat_1 = solut.seq(1, i_prev, info.T) + data.cost(solut.s(i_prev), solut.s(i_next)); + cost_concat_2 = cost_concat_1 + solut.seq(i, i_next, info.T) + data.cost(solut.s(i), solut.s(i_next+1)); cost_new = solut.seq(1, i_prev, info.C) + ... - solut.seq(i, i_next, info.W) * (cost_concat_1) + info.cost(solut.s(i_next), solut.s(i)) + ... - solut.seq(i_next+1, info.dimen+1, info.W) * (cost_concat_2) + solut.seq(i_next+1, info.dimen+1, info.C); + solut.seq(i, i_next, info.W) * (cost_concat_1) + data.cost(solut.s(i_next), solut.s(i)) + ... + solut.seq(i_next+1, data.dimen+1, info.W) * (cost_concat_2) + solut.seq(i_next+1, data.dimen+1, info.C); if (cost_new < cost_best) cost_best = cost_new - eps; @@ -155,23 +151,23 @@ function print_s(s) J_best = i_next; end - for j = i_next+1:info.dimen + for j = i_next+1:data.dimen j_prev = j-1; j_next = j+1; - cost_concat_1 = solut.seq(1, i_prev, info.T) + info.cost(solut.s(i_prev), solut.s(j)); - cost_concat_2 = cost_concat_1 + info.cost(solut.s(j), solut.s(i_next)); - cost_concat_3 = cost_concat_2 + solut.seq(i_next, j_prev, info.T) + info.cost(solut.s(j_prev), solut.s(i)); - cost_concat_4 = cost_concat_3 + info.cost(solut.s(i), solut.s(j_next)); + cost_concat_1 = solut.seq(1, i_prev, info.T) + data.cost(solut.s(i_prev), solut.s(j)); + cost_concat_2 = cost_concat_1 + data.cost(solut.s(j), solut.s(i_next)); + cost_concat_3 = cost_concat_2 + solut.seq(i_next, j_prev, info.T) + data.cost(solut.s(j_prev), solut.s(i)); + cost_concat_4 = cost_concat_3 + data.cost(solut.s(i), solut.s(j_next)); cost_new = solut.seq(1, i_prev, info.C) + ... % 1st subseq cost_concat_1 + ... % concat 2nd subseq (single node) solut.seq(i_next, j_prev, info.W) * cost_concat_2 + solut.seq(i_next, j_prev, info.C) + ... % concat 3rd subseq cost_concat_3 + ... % concat 4th subseq (single node) - solut.seq(j_next, info.dimen+1, info.W) * cost_concat_4 + solut.seq(j_next, info.dimen+1, info.C); % concat 5th subseq + solut.seq(j_next, data.dimen+1, info.W) * cost_concat_4 + solut.seq(j_next, data.dimen+1, info.C); % concat 5th subseq if (cost_new < cost_best) cost_best = cost_new - eps; @@ -184,10 +180,8 @@ function print_s(s) end if (cost_best < solut.cost - eps) - %cost_best solut.s = swap(solut.s, I_best, J_best); - solut = subseq_load(solut, info); - %solut.cost + solut = update_subseq_info_matrix(solut, info, data); solut_new = solut; ret = true; else @@ -197,28 +191,28 @@ function print_s(s) end -function [solut_new, ret] = search_two_opt(solut, info) +function [solut_new, ret] = search_two_opt(solut, info, data) cost_best = info.fmax; cost_new = 0.0; cost_concat_1 = 0.0; cost_concat_2 = 0.0; - for i = 2:info.dimen-1 + for i = 2:data.dimen-1 i_prev = i-1; rev_seq_cost = solut.seq(i, i+1, info.T); - for j = i+2:info.dimen + for j = i+2:data.dimen j_next = j+1; - rev_seq_cost = rev_seq_cost + info.cost(solut.s(j-1), solut.s(j)) * (solut.seq(i, j, info.W)-1.0); + rev_seq_cost = rev_seq_cost + data.cost(solut.s(j-1), solut.s(j)) * (solut.seq(i, j, info.W)-1.0); - cost_concat_1 = solut.seq(1, i_prev, info.T) + info.cost(solut.s(j), solut.s(i_prev)); - cost_concat_2 = cost_concat_1 + solut.seq(i, j, info.T) + info.cost(solut.s(j_next), solut.s(i)); + cost_concat_1 = solut.seq(1, i_prev, info.T) + data.cost(solut.s(j), solut.s(i_prev)); + cost_concat_2 = cost_concat_1 + solut.seq(i, j, info.T) + data.cost(solut.s(j_next), solut.s(i)); cost_new = solut.seq(1, i_prev, info.C) + ... % 1st subseq solut.seq(i, j, info.W) * cost_concat_1 + rev_seq_cost + ... % concat 2nd subseq (reversed seq) - solut.seq(j_next, info.dimen+1, info.W) * cost_concat_2 + solut.seq(j_next, info.dimen+1, info.C); % concat 3rd subseq + solut.seq(j_next, data.dimen+1, info.W) * cost_concat_2 + solut.seq(j_next, data.dimen+1, info.C); % concat 3rd subseq if (cost_new < cost_best) cost_best = cost_new - eps; @@ -229,10 +223,8 @@ function print_s(s) end if (cost_best < solut.cost - eps) - %cost_best solut.s = reverse(solut.s, I_best, J_best); - solut = subseq_load(solut, info); - %solut.cost + solut = update_subseq_info_matrix(solut, info, data); solut_new = solut; ret = true; else @@ -242,14 +234,14 @@ function print_s(s) end -function [solut_new, ret] = search_reinsertion(solut, info, opt) +function [solut_new, ret] = search_reinsertion(solut, info, data, opt) cost_best = info.fmax; cost_new = 0.0; cost_concat_1 = 0.0; cost_concat_2 = 0.0; cost_concat_3 = 0.0; - for i = 2:info.dimen-opt+1 + for i = 2:data.dimen-opt+1 j = opt+i-1; i_prev = i-1; j_next = j+1; @@ -257,15 +249,15 @@ function print_s(s) for k = 1:i_prev-1 k_next = k+1; - cost_new = solut.seq(1, info.dimen+1, info.C); - cost_concat_1 = solut.seq(1, k, info.T) + info.cost(solut.s(k), solut.s(i)); - cost_concat_2 = cost_concat_1 + solut.seq(i, j, info.T) + info.cost(solut.s(j), solut.s(k_next)); - cost_concat_3 = cost_concat_2 + solut.seq(k_next, i_prev, info.T) + info.cost(solut.s(i_prev), solut.s(j_next)); + cost_new = solut.seq(1, data.dimen+1, info.C); + cost_concat_1 = solut.seq(1, k, info.T) + data.cost(solut.s(k), solut.s(i)); + cost_concat_2 = cost_concat_1 + solut.seq(i, j, info.T) + data.cost(solut.s(j), solut.s(k_next)); + cost_concat_3 = cost_concat_2 + solut.seq(k_next, i_prev, info.T) + data.cost(solut.s(i_prev), solut.s(j_next)); cost_new = solut.seq(1, k, info.C) + ... % 1st subseq solut.seq(i, j, info.W) * cost_concat_1 + solut.seq(i, j, info.C) + ... % concat 2nd subseq (reinserted seq) solut.seq(k_next, i_prev, info.W) * cost_concat_2 + solut.seq(k_next, i_prev, info.C) + ... % concat 3rd subseq - solut.seq(j_next, info.dimen+1, info.W) * cost_concat_3 + solut.seq(j_next, info.dimen+1, info.C); % concat 4th subseq + solut.seq(j_next, data.dimen+1, info.W) * cost_concat_3 + solut.seq(j_next, data.dimen+1, info.C); % concat 4th subseq if (cost_new < cost_best) cost_best = cost_new - eps; @@ -276,17 +268,17 @@ function print_s(s) end - for k = i+opt:info.dimen + for k = i+opt:data.dimen k_next = k+1; - cost_concat_1 = solut.seq(1, i_prev, info.T) + info.cost(solut.s(i_prev), solut.s(j_next)); - cost_concat_2 = cost_concat_1 + solut.seq(j_next, k, info.T) + info.cost(solut.s(k), solut.s(i)); - cost_concat_3 = cost_concat_2 + solut.seq(i, j, info.T) + info.cost(solut.s(j), solut.s(k_next)); + cost_concat_1 = solut.seq(1, i_prev, info.T) + data.cost(solut.s(i_prev), solut.s(j_next)); + cost_concat_2 = cost_concat_1 + solut.seq(j_next, k, info.T) + data.cost(solut.s(k), solut.s(i)); + cost_concat_3 = cost_concat_2 + solut.seq(i, j, info.T) + data.cost(solut.s(j), solut.s(k_next)); cost_new = solut.seq(1, i_prev, info.C) + ... % 1st subseq solut.seq(j_next, k, info.W) * cost_concat_1 + solut.seq(j_next, k, info.C) + ... % concat 2nd subseq solut.seq(i, j, info.W) * cost_concat_2 + solut.seq(i, j, info.C) + ... % concat 3rd subseq (reinserted seq) - solut.seq(k_next, info.dimen+1, info.W) * cost_concat_3 + solut.seq(k_next, info.dimen+1, info.C); % concat 4th subseq + solut.seq(k_next, data.dimen+1, info.W) * cost_concat_3 + solut.seq(k_next, data.dimen+1, info.C); % concat 4th subseq if (cost_new < cost_best) cost_best = cost_new - eps; @@ -298,10 +290,8 @@ function print_s(s) end if (cost_best < solut.cost) - %cost_best solut.s = reinsert(solut.s, I_best, J_best, POS_best+1); - solut = subseq_load(solut, info); - %solut.cost + solut = update_subseq_info_matrix(solut, info, data); solut_new = solut; ret = true; else @@ -311,31 +301,26 @@ function print_s(s) end -function [s, cost, index_new] = RVND(solut, info) +function [s, cost, index_new] = RVND(solut, info, data) neighbd_list = [info.SWAP, info.TWO_OPT, info.REINSERTION, info.OR_OPT_2, info.OR_OPT_3]; while (isempty(neighbd_list) == false) RND = rand(1); - %RND = [RND, RND+0.0000000001]((RND < 0.0000000001) + 1); - %index = ceil(RND*columns(neighbd_list)); - %info.rnd(info.rnd_index); - index = info.rnd(info.rnd_index) + 1; - info.rnd_index = info.rnd_index + 1; - + index = data.rnd(data.rnd_index) + 1; + data.rnd_index = data.rnd_index + 1; neighbd = neighbd_list(index); - improve_flag = false; switch (neighbd) case info.REINSERTION - [solut, improve_flag] = search_reinsertion(solut, info, info.REINSERTION); + [solut, improve_flag] = search_reinsertion(solut, info, data, info.REINSERTION); case info.OR_OPT_2 - [solut, improve_flag] = search_reinsertion(solut, info, info.OR_OPT_2); + [solut, improve_flag] = search_reinsertion(solut, info, data, info.OR_OPT_2); case info.OR_OPT_3 - [solut, improve_flag] = search_reinsertion(solut, info, info.OR_OPT_3); + [solut, improve_flag] = search_reinsertion(solut, info, data, info.OR_OPT_3); case info.SWAP - [solut, improve_flag] = search_swap(solut, info); + [solut, improve_flag] = search_swap(solut, info, data); case info.TWO_OPT - [solut, improve_flag] = search_two_opt(solut, info); + [solut, improve_flag] = search_two_opt(solut, info, data); end if (improve_flag) @@ -348,27 +333,25 @@ function print_s(s) s = solut.s; cost = solut.cost; - index_new = info.rnd_index; + index_new = data.rnd_index; end function ret = notnull_rnd() RND = rand(1); - %RND = [RND, RND+0.0000000001]((RND < 0.0000000001) + 1); ret = RND; end -function [ret, index_new] = perturb(solut, info) +function [ret, index_new] = perturb(solut, data) A_start = 1; A_end = 1; B_start = 1; B_end = 1; - size_max = ceil((info.dimen+1) / 10); - %size_max = [2, size_max]((size_max >= 2) + 1); + size_max = ceil((data.dimen+1) / 10); size_min = 2; while ((A_start <= B_start && B_start <= A_end) || (B_start <= A_start && A_start <= B_end)) - max_ = (info.dimen+1) -2 -size_max; + max_ = (data.dimen+1) -2 -size_max; rnd = notnull_rnd(); A_start = ceil(max_ * rnd) + 1; rnd = notnull_rnd(); @@ -380,19 +363,15 @@ function print_s(s) B_end = B_start + ceil(((size_max-size_min) * rnd) + size_min); - A_start = info.rnd(info.rnd_index) + 1; - %info.rnd(info.rnd_index) - info.rnd_index = info.rnd_index + 1; - A_end = A_start + info.rnd(info.rnd_index); - %info.rnd(info.rnd_index) - info.rnd_index = info.rnd_index + 1; + A_start = data.rnd(data.rnd_index) + 1; + data.rnd_index = data.rnd_index + 1; + A_end = A_start + data.rnd(data.rnd_index); + data.rnd_index = data.rnd_index + 1; - B_start = info.rnd(info.rnd_index) + 1; - %info.rnd(info.rnd_index) - info.rnd_index = info.rnd_index + 1; - B_end = B_start + info.rnd(info.rnd_index); - %info.rnd(info.rnd_index) - info.rnd_index = info.rnd_index + 1; + B_start = data.rnd(data.rnd_index) + 1; + data.rnd_index = data.rnd_index + 1; + B_end = B_start + data.rnd(data.rnd_index); + data.rnd_index = data.rnd_index + 1; end if (A_start < B_start) @@ -404,36 +383,34 @@ function print_s(s) end ret = solut.s; - index_new = info.rnd_index; + index_new = data.rnd_index; end -function ret = solut_init(info) - s.s = zeros(info.dimen+1); - s.seq = zeros(info.dimen+1, info.dimen+1, 3); +function ret = solut_init(data) + s.s = zeros(data.dimen+1); + s.seq = zeros(data.dimen+1, data.dimen+1, 3); s.cost = Inf(1); ret = s; end -function ret = GILS_RVND(Imax, Iils, R, info) - solut_crnt = solut_init(info); - solut_partial = solut_init(info); - solut_best = solut_init(info); +function ret = GILS_RVND(Imax, Iils, R, info, data) + solut_crnt = solut_init(data); + solut_partial = solut_init(data); + solut_best = solut_init(data); for i = 1:Imax RND = rand(1); - %RND = [RND, RND+0.0000000001]((RND < 0.0000000001) + 1); - %index = ceil(columns(R) * RND); - index = info.rnd(info.rnd_index) + 1; - info.rnd_index = info.rnd_index + 1; + + index = data.rnd(data.rnd_index) + 1; + data.rnd_index = data.rnd_index + 1; alpha = R(index); fprintf("[+] Search %d\n", i) fprintf("\t[+] Constructing..\n"); - %"ITER ", i - [solut_crnt.s, info.rnd_index] = construction(alpha, info); - solut_crnt = subseq_load(solut_crnt, info); + [solut_crnt.s, data.rnd_index] = construction(alpha, data); + solut_crnt = update_subseq_info_matrix(solut_crnt, info, data); solut_partial = solut_crnt; fprintf("\t[+] Looking for the best Neighbor..\n") @@ -441,7 +418,7 @@ function print_s(s) iterILS = 0; while (iterILS < Iils) - [solut_crnt.s, solut_crnt.cost, info.rnd_index] = RVND(solut_crnt, info); + [solut_crnt.s, solut_crnt.cost, data.rnd_index] = RVND(solut_crnt, info, data); if (solut_crnt.cost < solut_partial.cost - eps) solut_partial.s = solut_crnt.s; @@ -449,8 +426,8 @@ function print_s(s) iterILS = 0; end - [solut_crnt.s, info.rnd_index] = perturb(solut_partial, info); - solut_crnt = subseq_load(solut_crnt, info); + [solut_crnt.s, data.rnd_index] = perturb(solut_partial, data); + solut_crnt = update_subseq_info_matrix(solut_crnt, info, data); iterILS = iterILS + 1; end @@ -461,7 +438,6 @@ function print_s(s) fprintf("\tCurrent best cost: %.2f\n", solut_best.cost) fprintf('SOLUCAO: ') print_s(solut_best.s) - %typeinfo(solut_crnt.s) end fprintf('COST: %.2f\n', solut_best.cost) @@ -470,8 +446,8 @@ function print_s(s) end function mainn - [info.dimen, info.cost, info.rnd] = Data(); - info; + [data.dimen, data.cost, data.rnd] = Data(); + data.rnd_index = 1; info.fmax = Inf(1); info.T = 1; info.C = 2; @@ -481,31 +457,16 @@ function print_s(s) info.OR_OPT_3 = 3; info.SWAP = 4; info.TWO_OPT = 5; - info.rnd_index = 1; - - %for i = 1:info.dimen - % sol.s(i) = i; - %end - %sol.s(info.dimen+1) = 1; - %sol.cost = 0; - %sol.seq = zeros(info.dimen+1, info.dimen+1, 3); - %sol = subseq_load(sol, info); - - %sol.seq(1, info.dimen+1, info.C); - %s = construction(0.1, info); - %%s(2:7) - %%s(2:7) = flip(s(2:7)) - %s = reinsert(s, 6, 11, 2); - + Imax = 10; Iils = 100; - if info.dimen < 100 - Iils = info.dimen; + if data.dimen < 100 + Iils = data.dimen; end R = [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26]; t0 = clock (); - s = GILS_RVND(Imax, Iils, R, info); + s = GILS_RVND(Imax, Iils, R, info, data); elapsed_time = etime (clock (), t0); fprintf('TIME: %.4f\n', elapsed_time) s.s;