-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheuristics.cpp
More file actions
411 lines (310 loc) · 11 KB
/
Copy pathheuristics.cpp
File metadata and controls
411 lines (310 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
#include<bits/stdc++.h>
#include "global.h"
using namespace std;
/* -------------- Estas funciones retornan directamente el mejor valor ----------------*/
//Función miope de espacio que cambia al stack con más espacio (a la izquierda)
int myopic_space(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int max_space = 0;
int choosed_stack = 0;
for(int i = 0; i < n_bays*n_rows; i++){
if(i == origin_stack){
continue;
}
//Verificamos si es mejor que lo que ya hemos encontrado
int value = max_h - yard[i].size();
if(value > max_space){
max_space = value;
choosed_stack = i;
}
}
//Retornamos el mejor stack para moverse
return choosed_stack;
}
int RI(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
int choosed_stack = 0;
int min_ri = yard[0].size(); // Esta es la única diferencia con myopic_blocked, no debería importar (creo)
for(int i = 0; i < n_bays*n_rows; i++){
int ri_stack = 0;
if(i == origin_stack){
continue;
}
if(max_h == yard[i].size()) //Stack lleno
continue;
int size = yard[i].size();
for(int j = 0; j < size; j++){
if(yard[i][j] < c2relocate)
ri_stack++;
}
//Verificamos si es mejor que lo que ya hemos encontrado
if(min_ri > ri_stack){
min_ri = ri_stack;
choosed_stack = i;
}
}
//Retornamos el mejor stack para moverse
return choosed_stack;
}
int RIL(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
int choosed_stack = 0;
int choosed_container = 0;
int min_ri = yard[0].size();
for(int i = 0; i < n_bays*n_rows; i++){
int ri_stack = 0;
int highest_c = 0;
if(i == origin_stack){
continue;
}
if(max_h == yard[i].size()) //Stack lleno
continue;
//if(yard[i].size() == 0) //Forzar elegir stack vacio
// return i;
int size = yard[i].size();
for(int j = 0; j < size; j++){
if(yard[i][j] < c2relocate){
ri_stack++;
if(yard[i][j] > highest_c)
highest_c = yard[i][j];
}
}
//Verificamos si es mejor que lo que ya hemos encontrado
if(min_ri > ri_stack){
min_ri = ri_stack;
choosed_stack = i;
choosed_container = highest_c;
}
else if(min_ri == ri_stack){
if(highest_c > choosed_container){
choosed_stack = i;
choosed_container = highest_c;
}
}
}
//Retornamos el mejor stack para moverse
return choosed_stack;
}
/*---------------- Right handed heuristics ---------------- */
int RI_R(vector<vector<int>> &yard, int origin_stack){
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
int choosed_stack = 0;
int min_ri = yard[0].size();
//Recorremos de derecha a izquierda
for(int i = n_bays*n_rows-1; i >= 0; i--){
int ri_stack = 0;
if(i == origin_stack){
continue;
}
if(max_h == yard[i].size())
continue;
int size = yard[i].size();
for(int j = 0; j < size; j++){
if(yard[i][j] < c2relocate)
ri_stack++;
}
if(min_ri > ri_stack){
min_ri = ri_stack;
choosed_stack = i;
}
}
//Retornamos el mejor stack para moverse
return choosed_stack;
}
int RIL_R(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
int choosed_stack = 0;
int choosed_container = 0;
int min_ri = yard[0].size();
//Recorremos de derecha a izquierda
for(int i = n_bays*n_rows-1; i >= 0; i--){
int ri_stack = 0;
int highest_c = 0;
if(i == origin_stack){
continue;
}
if(max_h == yard[i].size())
continue;
int size = yard[i].size();
for(int j = 0; j < size; j++){
if(yard[i][j] < c2relocate){
ri_stack++;
if(yard[i][j] > highest_c)
highest_c = yard[i][j];
}
}
if(min_ri > ri_stack){
min_ri = ri_stack;
choosed_stack = i;
choosed_container = highest_c;
}
else if(min_ri == ri_stack){
if(highest_c > choosed_container){
choosed_stack = i;
choosed_container = highest_c;
}
}
}
//Retornamos el mejor stack para moverse
return choosed_stack;
}
/* ---------------- FUNCIONES MIOPE REBELDES ----------------*/
//Función miope inversa de espacio que cambia al stack con menos espacio
int myopic_min_space(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int min_space = max_h + 1;
int choosed_stack = -1;
for(int i = 0; i < n_bays*n_rows; i++){
if(i == origin_stack || yard[i].size() >= max_h){
continue;
}
//Verificamos si es peor que lo que ya hemos encontrado
int value = max_h - yard[i].size();
if(value < min_space){
min_space = value;
choosed_stack = i;
}
}
//Retornamos el peor stack para moverse
return choosed_stack;
}
//Funcion miope inversa que cambia al stack con mas bloqueos
int RI_inverse(vector<vector<int>> &yard, int origin_stack){
//Recorremos todo el yard y vamos calculando
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
int choosed_stack = 0;
int max_ri = -1;
for(int i = 0; i < n_bays*n_rows; i++){
int ri_stack = 0;
if(i == origin_stack){
continue;
}
if(max_h == yard[i].size()) //Stack lleno
continue;
int size = yard[i].size();
for(int j = 0; j < size; j++){
if(yard[i][j] < c2relocate)
ri_stack++;
}
//Verificamos si es peor que lo que ya hemos encontrado
if(ri_stack > max_ri){
max_ri = ri_stack;
choosed_stack = i;
}
}
//Retornamos el peor stack para moverse
return choosed_stack;
}
/* -------------- HEURÍSTICAS TOP_STACK ----------------*/
/*
Estas heurísticas solo se fijarán en el contenedor que está en el tope del stack
No preferiran los stacks vacíos pues myopic space ya hace eso
*/
//Eligirá el stack que tienene el container con id mas cercano mayor que el actual
int top_diff(vector<vector<int>> &yard, int origin_stack){
int destiny_stack = -1;
int c2relocate = yard[origin_stack][yard[origin_stack].size()-1];
int selected_stack = -1;
int min_diff_up = 10e6; //Calculamos la mínima diferencia que hay si es que el valor es mayor que el container actual
int selected_stack_up = -1;
int min_diff_down = 10e6; //Calculamos la mínima diferencia que hay si es que el valor es menor que el container actual
int selected_stack_down = -1;
for(int i = 0; i < n_bays*n_rows; i++){
//Nos saltamos el container actual
if(i == origin_stack) continue;
//Stack lleno
if(yard[i].size() >= max_h)
continue;
//Calculamos
int size = yard[i].size();
if(size == 0) continue; //ignora los contenedores vacíos
int id_actual = yard[i][size-1];
//Vamos si es que el id es mayor al c2relocate
if(id_actual > c2relocate){
int value = id_actual - c2relocate;
if (value < min_diff_up) {
min_diff_up = value;
selected_stack_up = i;
}
}
//Ahora el c2relocate es mayor que el id
else if(c2relocate > id_actual){
int value = c2relocate - id_actual;
if(value < min_diff_down){
min_diff_down = value;
selected_stack_down = i;
}
}
}
//Seleccionamos el más cercano que sea mayor a nosotros
selected_stack = selected_stack_up;
//Si es que no hay ninguno que sea mayor a c2relocate elegimos el mas cercano que sea menor
if(selected_stack == -1){
selected_stack = selected_stack_down;
}
//Si es que sigue sin elegir ninguno es que todos están vacíos
if(selected_stack == -1){
if(origin_stack == 0){
selected_stack = 1;
}
else{
selected_stack = 0;
}
}
return selected_stack;
}
//Función para elegir una de las funciones miopes disponibles de forma random
//La idea es que le aplique una heurística al yard y retorne la heurística que utilizó
int apply_random_heuristic(vector<vector<int>> &yard, vector<int> &stack_position, int origin_stack){
//Obtenemos un número aleatorio para elegir la heurística
//int n_heuristic = 4;
int choosed = getRandomInt(1, params.n_heu);
int destiny_stack;
//Heurística space
if (choosed == 1){
destiny_stack = myopic_space(yard, origin_stack);
}
//Heurística RI
else if(choosed == 2){
destiny_stack = RI(yard, origin_stack);
}
//Heurística RIL
else if(choosed == 3){
destiny_stack = RIL(yard, origin_stack);
}
//Heurística RI right handed
else if(choosed == 4){
destiny_stack = RI_R(yard, origin_stack);
}
//Heurística RIL right handed
else if(choosed == 5){
destiny_stack = RIL_R(yard, origin_stack);
}
//Heuristica top_diff
else if(choosed == 6){
destiny_stack = top_diff(yard, origin_stack);
}
//Heurística rebelde de espacio
else if(choosed == 7){
destiny_stack = myopic_min_space(yard, origin_stack);
}
//Heurística rebelde de RI
else if(choosed == 8){
destiny_stack = RI_inverse(yard, origin_stack);
}
//Realizamos el movimiento
int h_origin = yard[origin_stack].size();
int c2relocate = yard[origin_stack][h_origin-1];
yard[origin_stack].pop_back();
yard[destiny_stack].push_back(c2relocate);
stack_position[c2relocate] = destiny_stack;
return choosed;
}