-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTODO
572 lines (451 loc) · 23.9 KB
/
TODO
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
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# TODO et Carnet de bord
## TODO
- creuser pourquoi CPLEX trouve autant de symétries dans la résolution dualized
## 17.01
Sur certaines grosses instances: linux kills le programme avec la méthode dualisée
Pas de message d'erreur, simplement :
./run.sh: line 20: 2414 Killed ./myprogram "$file" "$method" "$verbose"
Mais si on creuse en affichant **dmesg**, on obtient:
Out of memory: Killed process 2576 (myprogram) total-vm:3771096kB, anon-rss:3110692kB, file-rss:4kB, shmem-rss:0kB, UID:1000 pgtables:6396kB oom_score_adj:0
Problème: c'est lorsqu on utilise cplex que le programme meurt. Il arrive bien à se build avant...
ulimit -a
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
max locked memory
The maximum size that may be locked into memory. Memory locking ensures the memory is always in RAM and never moved to the swap disk.
Quand on exporte le problème en .lp, on peut exécuter le model.lp depuis cplex lancé depuis Windows.
Donc lié à un problème de mémoire sur le WSL
Remarque: on obtient les warnings suivants:
Warning, line 1755417: Name 'x_0_0#235978' does not exist.
J imagine que ce warning apparait pour toutes les variables qui sont "créées" mais jamais utilisées dans les contraintes ou l'objectif
c'est à dire, les variables qui représentent des arcs qui n existent pas.
Dans mon fichier .wslconfig,
j'avais memory = 4Gb
Quand j enlève cette ligne, Cplex arrive à presolve le problème, ce qu'il ne faisait pas avant. Mais crash après trouver sa première solution
Out of memory: Killed process 1443 (myprogram) total-vm:3981856kB, anon-rss:3086536kB, file-rss:4kB, shmem-rss:0kB, UID:1000 pgtables:7136kB oom_score_adj:0
Essayons d'abord de modifier le problème pour que moins de mémoire soit prise.
Pas besoin de stocker un vecteur de vecteurs entier remplis à moitié de NaN, il faut faire ça de manière intelligente.
## 19.01
Résolution des sous-problèmes, c'est tellement overkill de résoudre le MILP
Si on trie au début les D et les poids des villes, il suffit de donner le plus gros coefficient aux premières villes/ aux premiers arcs.
data/processed/100_USA-road-d.COL.gr
La contrainte robuste est plus faible que la contrainte statique (poids des villes additionné), pas possible.
A débugger.
Faire attention aux décalages de 1. Indexation des instances commence à 1. Problème réglé.
En faisant tourner le modèle statique sur toutes les instances:
Running file: data/processed/2100_USA-road-d.COL.gr, 56 / 123
Advanced basis not built.
Advanced basis not built.
Running file: data/processed/2300_USA-road-d.COL.gr, 62 / 123
Advanced basis not built.
Concert exception caught: CPLEX Error 1217: No solution exists.
-> Simplement pas assez de temps donné, elle est énervée cette instance. Mais gestion des erreurs revues pour ne pas avoir d'incohérences comme cella là.
## 21.01
Problème de dualized.
Detecting symmetries...
Elapsed time for symmetry detection = 82.89 sec. (10000.42 ticks)
Found 2.310657e+347 symmetric permutations.
Comment est-ce qu il peut détecter autant de symmétries ?
A creuser pour améliorer la résolution
Running file: data/processed/1000_USA-road-d.COL.gr, 2/123
Advanced basis not built.
Que signifie "Advanced basis not built" ?
## 24.01
Branch and cut:
Problème: La résolution du sous problème de l'objectif robuste est + rapide avec CLEX qu'avec la résolution d'un knapsack continu (de 2 ordres de grandeur !!)
robust objective = 42766.5 time: 0.000247
robust objective bis = 42766.5, time: 0.010604
Le tri doit être lent?
Non, time sort = 1.3e-05, négligeable
C'est bon, le temps de calcul avec CPLEX ne prenait en compte que la résolution alors que la construction du problème prend aussi beaucoup de temps.
On a bien que la résolution gloutonne de notre knapsack continu est plus rapide.
robust objective = 42766.5, time: 0.011856
robust objective bis = 42766.5, time: 0.00619
On perd beaucoup de temps à retrouver les arcs à partir de la solution. C'est la contrepartie de ne pas stocker toute la matrice de distance, ce qui faisait crasher WSL à cause de la mémoire.
Mais on ne repart jamais de là quand on ajoute des coupes car on a directement les indexes des arcs utilisés.
J'ai des coupes qui se passent bien.
Puis à un moment, j'ai cette erreur
free(): invalid next size (fast)
ILOLAZYCONSTRAINTCALLBACK4(myCallBack,IloBoolVarArray, x,
IloBoolVarArray, y, IloNumVar, z, Instance, inst) {
std::cout << "Callback called" << std::endl;
IloEnv env = getEnv();
unsigned int n_edges = getValue(IloSum(x));
if (n_edges == 3) {
std::cout << "n_edges = " << n_edges << std::endl;
}
std::vector<IloNum> weights(n_edges, 0.0); // d
std::vector<IloNum> uncertainties(n_edges); // D
std::vector<IloInt> idx_edges(n_edges);
double static_score = 0.0;
unsigned int count = 0;
for (unsigned int a=0; a<inst.n_arc; a++) {
if (getValue(x[a]) > 1e-3) {
weights[count] = inst.mat[a].d;
static_score += inst.mat[a].d;
uncertainties[count] = inst.mat[a].D;
idx_edges[count] = a;
count++;
std::cout << inst.mat[a].tail << " -> " << inst.mat[a].head << std::endl;
std::cout << getValue(x[a]) << std::endl;
}
}
if (count != n_edges) {
std::cout << "Error: count = " << count << " != n_edges = " << n_edges << std::endl;
}
std::cout << "n_edges = " << n_edges << std::endl;
std::cout << "weights = [";
for (unsigned int i=0; i<n_edges; i++) {
std::cout << weights[i] << " ";
}
std::cout << "]" << std::endl;
std::cout << "uncertainties = [";
for (unsigned int i=0; i<n_edges; i++) {
std::cout << uncertainties[i] << " ";
}
std::cout << "]" << std::endl;
std::cout << "idx_edges = [";
for (unsigned int i=0; i<n_edges; i++) {
std::cout << idx_edges[i] << " ";
}
std::cout << "]" << std::endl;
std::vector<size_t> argsorted_weights = argsort(weights);
double robust_attack = 0.0;
double used_budget = 0.0;
int idx = n_edges-1;
IloExpr expr(env);
while (used_budget < inst.d1 && idx >= 0) {
unsigned int arc_idx = argsorted_weights[idx];
float delta1_i = std::min(inst.d1 - used_budget, uncertainties[arc_idx]);
used_budget += delta1_i;
robust_attack += delta1_i * weights[arc_idx];
IloInt real_arc = idx_edges[arc_idx];
if (abs(weights[arc_idx] - inst.mat[real_arc].d) > 1e-3) {
std::cout << "Error: weights[arc_idx] = " << weights[arc_idx] << " != inst.mat[real_arc].d = " << inst.mat[real_arc].d << std::endl;
throw std::domain_error("Error in callBack");
}
expr += inst.mat[real_arc].d * delta1_i * x[real_arc];
idx--;
}
std::cout << "used_budget = " << used_budget << std::endl;
std::cout << "robust_attack = " << robust_attack << std::endl;
std::cout << "static_score = " << static_score << std::endl;
std::cout << "robust_score = " << static_score + robust_attack << std::endl;
std::cout << "z = " << getValue(z) << std::endl;
std::cout << expr << " <= z " << std::endl;
std::cout << "\n\n\n" << std::endl;
expr += IloScalProd(x, inst.d_vec);
double robust_score = static_score + robust_attack;
// Add the violated constraint
if (robust_score > getValue(z) + 1e-3) {
add(expr <= z);
} else {
std::cout << "No violated constraint found in callBack" << std::endl;
}
expr.end();
}
Pour l'instance 20_USA-road-d.BAY.gr
A un moment, on trouve que getValue(IloSum(x)) = 3 ie on utilise 3 arcs.
Sauf que si l'on regarde tous les arcs utilisés ensuite, il y en a 4
CPLEX fait n'importe quoi
Et somehow, alors que weights est un vecteur de taille 3
Ca ne pose pas de problème d'écrire que weights[3] = ...
Il faudrait envoyer un message à CPLEX.
unsigned int a = getValue(IloSum(x))
# a = 3
IloInt b = getValue(IloSum(x));
# b = 3
float c = getValue(IloSum(x));
c = 4
C'est n'importe quoi. Je ne peux pas fixer la taille des vecteurs avant alors que ça fait gagner du temps parce que IloSum plante.
Donc je vais faire des pushBack même si c'est moche, au moins ça marche
Ca marche, ça plie l'instance de taille 20.
Mais ça prend 1 minute pour l'instance de taille 1000
Après profiling, toute la lenteur vient de cette boucle
std::vector<> xValues;
for (unsigned int a = 0; a < inst.n_arc; a++) {
xValues[a] = getValue(x[a]);
}
Cela prend tout le temps du callBack.
Comment retrieve ces données sans perdre 40s par coupe?
https://www.ibm.com/docs/en/icos/22.1.1?topic=information-querying-solution-data
IloNumArray xValues(env);
getValues(xValues, x);
On passe de 40s à retrieve les données à 0.004 secondes pour une instance à 1000 noeuds
Si on laisse tourner 300s, on a 130 callBacks qui prennent 0.03s
Soit environ 5s. Donc le temps que prend notre callBack est négligeable devant celui de CPLEX pour optimiser
On peut laisser comme ça sans grapiller des secondes qui seront inutiles.
Branch and cut ok, à lancer sur toutes les instances pour voir les résultats
Go plans sécants maintenant, il n y a pas une différence énorme par rapport à ce qu'on vient de faire.
- Résolution des sous-problèmes, c'est tellement overkill de résoudre le MILP (RESOLU)
Si l'on trie au début les D et les poids des villes, il suffit de donner le plus gros coefficient aux premières villes/ aux premiers arcs.
On va l'appeler en callback, donc c'est important que ce soit rapide. Appeler CPLEX, rien que l'interface, j'imagine que ça prend du temps alors que le problème est hyper simple à résoudre sans l'appeler.
Pour cela, faire un tri lors de la création de l'instance.
Par ordre décroissant de D_vec[a] * d_vect[a] pour le score robuste
Par ordre décroissant de ph pour la contrainte robuste
Ensuite, il suffit de parcourir dans l'ordre les villes/arcs de la solution et remplir autant que possible les incertitudes
Remarque: plusieurs centaines de milliers d'arcs. Tri en n log n. Une solution courante a max 20 arcs.
Donc on peut faire énormément de sous problèmes avant de rentabiliser le tri initial, qu'on ne fait donc pas.
Plans coupants
Done mais prend des plombes de tout recommencer à chaque fois qu'on ajoute une contrainte
Quel est l'avantage de faire ça. Garder toutes les fonctionnalités CPLEX dont on se prive lorsqu'on ajoute des CallBacks ?
## 25.01
Ca pourrait être utile pour faire des statistiques de savoir **quand a été trouvée la meilleure solution par CPLEX**
Souvent très rapide et ensuite CPLEX passe son temps à essayer de réduire le gap jusqu'à prouver l'optimalité.
C'est possible de faire cela, mais uniquement avec des CallBack et ça désactive des fonctionnalités de CPLEX.
Pas de solution miracle après recherche. Donc on va s'asseoir sur ces stats.
Plans coupants.
1ere itération: solution statique, admissible mais pas le bon score. On ajoute la coupe
2e iteration: solution admissible mais pas le bon score.
3e iteration: on obtient une solution qui n'est pas admissible. Fin du temps. L'algorithme renvoit la dernière solution pas admissible
Alors qu'on avait obtenu une solution admissible avant, mais on l'a rejeté car elle ne mettait pas le bon score (robuste)
-> garder manuellement la meilleure solution admissible. Done.
WARM START
https://www.ibm.com/docs/en/icos/22.1.1?topic=mip-starting-from-solution-starts
After a MIP start has been established for your model, you control its use by the advanced start switch (AdvInd in Concert Technology; CPX_PARAM_ADVIND in the Callable Library). At the default setting of 1 (one) , the MIP start values that you specify are used. If you set AdvInd to the value 0 (zero), then the MIP start will not be used. If you set this parameter to 2, CPLEX retains the current incumbent (if there is one), re-applies presolve, and starts a new search from a new root. **Setting 2 can be particularly useful for solving fixed MIP models, where a start vector exists but no corresponding basis is available**. For more about a fixed MIP, see Working with the fixed MIP problem
Il est aussi possible de donner plusieurs valeurs de WarmStart à CPLEX. Pas dans un premier temps.
```
Warning: No solution found from 1 MIP starts.
Retaining values of one MIP start for possible repair.
```
Pourquoi j'ai ce message même lorsque je ne fais pas de warm start? Le code n'est pas appelé
**MIP emphasis: balance optimality and feasibility**
Si on considère que l'heuristique est suffisamment bonne. On peut utiliser dualized en se concentrant uniquement sur l'optimality?
Dans le code réalisé, les solutions trouvées s'additionnent. Warm start avec autant de solutions initiales que d'itération.
Serait mieux de garder uniquement la dernière?
## 25.01 r
heuristique fonctionne très rapidement (environ 1s) pour la plupart des instances.
certains cas pathologique: 1300_BAY arrive pas a trouver une solution réalisable au début avec un dijkstra. a priori pas adapté aux petites instances.
Pour les cas qui fonctionnent, la "borne_inf" semble bien etre une borne inf, mais aucune certitude -> est ce que on peut le prouver?
Il faudrait regarder comment injecter la solution de l'heuristique dans un B&B et voir l'impact sur les performances.
La borne inf en est une si la contrainte robuste est contraignante: si on est laregment bon, on va etre ok pour K=0 et donc c'est pas pertinent
## 31.01
**parser.cpp**
Remise à jour des compute_score. Version knapsack et milp en utilisant les vecteurs qu'on ne stockait pas avant (D et d)
résolution des sous problèmes en 1e-5 secondes. contre 1e-3
Ce n'est pas la création de ces vecteurs qui prenaient tant de place en mémoire, c'était la rédaction du problèmes avec x[i][j] apparemment. Mais ne pose pas de problème à stocker comme ça.
**modèle statique**
Dans la rédaction des contraintes, celle de flow s'écrit comme suit:
for (node) {
IloExpr out_arc_i;
IloExpr in_arc_i;
for (arc) {
if arc_correspond {
blabla
}
}
}
Mémoire: O(1) mais complexité en O(n^3)
Si on stocke les n_nodes expressions. On peut s'éviter une boucle sur n.
for (arc) {
out_arc[arc.head] += x[arc]
...
}
Mémoire O(n) mais complexité en O(n^2)
Cependant, en pratique. La gestion de la mémoire fait que plus de temps est pris lors de la 2nde écriture.
Et temps négligeable par rapport à la résolution qui suit.
**Multi-objectif**
Plusieurs chemins sont équivalents -> Symétries. Pour les briser, on peut ajouter un 2e objectif qui est de minimiser la somme des indices des villes (arbitraire)
https://www.ibm.com/docs/en/icos/22.1.1?topic=optimization-cpxerr-not-multiobj
All generic callbacks and legacy optimization informational callbacks are compatible with multiobjective optimization. However, all other legacy optimization callbacks, in particular control callbacks, are not compatible with multiobjective optimization.
Benders decomposition is not compatible with multiobjective optimization.
Writing the dual problem is not compatible with multiobjective optimization.
Populate is not compatible with multiobjective optimization.
Polishing is not compatible with multiobjective optimization.
Rien compris. Je n'arrive pas à savoir si c'est possible. Beaucoup de sources contradictoires. Le Manuel de CPLEX est objectivement mal fait. Les exemples présents lors de l'installation ne sont pas clairs non plus.
**Ilo exception caught: MultipleObjException: IloCplex can not handle multiple objectives**
On va dire que ce n'est pas possible alors que le site de CPLEX semble dire que c'est possible, y compris pour les MILP...
## 3.02
test de arc_removal pour réduire les symétrie en preprocess: on contraint pour pas utiliser certains sous chemin si il existe un autre sous chemin identique. A priori rajoute trop de contraintes ca ralentit le calcul.
## 05.02
**1300_USA-road-d.BAY branch and cut: no solution admissible !**
Mais on arrive à en trouver une à l'aide de retrieval2 dans l'heuristique
[1099;1150;1115;1152;1243;1153;1084;1288;1273;1158;969;1267;516;424;559;581;898;671;938;994;970;792;826;1177]
robust objective = 77217.7
robust constraint = 492
S = 492
Quelques unes des meilleures solutions statiques
[1099;1082;845;890;697;435;353;328;165;330;424;438;1120;1160;902;503;490;502;771;792;826;1177]
static objective = 60392
robust constraint = 631
[1099;1150;845;890;1081;846;423;395;591;731;577;595;457;861;902;503;582;825;970;1123;826;1177]
static objective = 60392
robust constraint = 624
Problème dans la résolution des sous problèmes statiques
Les score ne matchent pas. Surement un +1 de décalage
Debug done, je n'avais pas mis la bonne formule, un weight[idx] au lieu de 2.0
Différence de calcul entre l'objective et la contrainte robuste.
Je laisse les assert au cas où
1300_USA-road-d.BAY
Lazy constraint callback, it 43
Robust score does not match
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
Robust score: 102694
Robust score inst 98706.5
Error in lazy constraint callback computing robust score: Robust score does not match
Robust constraint inst 566
Pas admissible
Lazy constraint callback, it 43
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
Robust score: 102694 // D'où sort ce truc?
Robust score inst 98706.5 // C'est le bon score
Robust score does not match
Error in lazy constraint callback computing robust score: Robust score does not match
Pas de problème de score quand on le balance en warm start?!
Robust score du warm start: 98706.5
Ca ne vient pas de la solution, ça vient du xValues
qui utilise des arcs qui ne sont pas dans le parcours?!
Lazy constraint callback, it 43
Tested solution
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
SUBPROBLEMS
Robust score: 102694
**Static score: 86572**
Robust attack: 16122.5
Used budget: 2
INSTANCE
**static_score: 82584**
robust_attack: 16122.5
robust_score: 98706.5
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
Robust score: 102694
Robust score inst 98706.5
Robust score does not match
Error in lazy constraint callback computing robust score: Robust score does not match
C'est le score statique qui ne correspond pas à l'itération 43.
C'est possible que l'instance ait été modifiée quelque part? NON
Lazy constraint callback, it 43
Tested solution
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
Arc 62 -> 263 is used: 475
Arc 63 -> 139 is used: 9810
Arc 139 -> 62 is used: 2438
Arc 263 -> 416 is used: 728
Arc 389 -> 63 is used: 4106
Arc 416 -> 1027 is used: 3645
Arc 505 -> 536 is used: 4964
Arc 536 -> 1186 is used: 2053
Arc 646 -> 389 is used: 4259
Arc 656 -> 1086 is used: 1957
Arc 804 -> 646 is used: 2691
Arc 818 -> 656 is used: 6028
Arc 820 -> 1177 is used: 5597
Arc 881 -> 1185 is used: 1841
**Arc 969 -> 1158 is used: 1994**
Arc 1027 -> 1067 is used: 2821
Arc 1067 -> 505 is used: 841
Arc 1086 -> 1229 is used: 6459
Arc 1099 -> 1110 is used: 2691
Arc 1110 -> 881 is used: 4903
**Arc 1158 -> 969 is used: 1994**
Arc 1185 -> 1250 is used: 1792
Arc 1186 -> 1227 is used: 1097
Arc 1212 -> 804 is used: 4903
Arc 1227 -> 818 is used: 2263
Arc 1229 -> 820 is used: 2265
Arc 1250 -> 1212 is used: 1957
SUBPROBLEMS
Static score: 86572
Robust attack: 16122.5
Robust score: 102694
INSTANCE
arc 1099 -> 1110 : 2691
arc 1110 -> 881 : 4903
arc 881 -> 1185 : 1841
arc 1185 -> 1250 : 1792
arc 1250 -> 1212 : 1957
arc 1212 -> 804 : 4903
arc 804 -> 646 : 2691
arc 646 -> 389 : 4259
arc 389 -> 63 : 4106
arc 63 -> 139 : 9810
arc 139 -> 62 : 2438
arc 62 -> 263 : 475
arc 263 -> 416 : 728
arc 416 -> 1027 : 3645
arc 1027 -> 1067 : 2821
arc 1067 -> 505 : 841
arc 505 -> 536 : 4964
arc 536 -> 1186 : 2053
arc 1186 -> 1227 : 1097
arc 1227 -> 818 : 2263
arc 818 -> 656 : 6028
arc 656 -> 1086 : 1957
arc 1086 -> 1229 : 6459
arc 1229 -> 820 : 2265
arc 820 -> 1177 : 5597
static_score: 82584
robust_attack: 16122.5
robust_score: 98706.5
1099 1110 881 1185 1250 1212 804 646 389 63 139 62 263 416 1027 1067 505 536 1186 1227 818 656 1086 1229 820 1177
Robust score: 102694
Robust score inst 98706.5
Robust score does not match
Il y a 2 arcs qui sont ajoutés dans la solution du branch and cut
Arc 969 -> 1158 is used: 1994
Arc 1158 -> 969 is used: 1994
Ils augmentent le score statique. Pourquoi sont-ils choisis?
Arc 68500: 1158 -> 969 : 1994 0.2;
Arc 77460: 969 -> 1158: 1994 0.2;
Noeud 969: p = 19, ph = 1
Noeud 1158: p = 9, ph = 3
On peut maintenant forcer le bug en warmStart!
Dans la résolution des sous-problèmes, on résout bien le bon problème
C'est lors du calcul de la solution qu'il y avait un problème. Puisqu'on ne voyait pas les arcs qui ne sont pas dans le chemin de s à t.
A l'optimal, ces boucles n'arrivent jamais mais lors de la recherche, il peut y en avoir.
// // WARM START TO DEBUG 1300_USA-road-d.BAY.gr
// // std::vector<IloInt> warm_sol = {1099,1150,1115,1152,1243,1153,1084,1288,1273,1158,969,1267,516,424,559,581,898,671,938,994,970,792,826,1177}; // admissible
// std::vector<IloInt> warm_sol = {1099,1110,881,1185,1250,1212,804,646,389,63,139,62,263,416,1027,1067,505,536,1186,1227,818,656,1086,1229,820,1177};
// double robust_score = inst.compute_robust_score_milp(env, warm_sol);
// double static_score = inst.compute_static_score(warm_sol);
// double robust_constraint = inst.compute_robust_constraint_milp(env, warm_sol);
// double static_constraint = inst.compute_static_constraint(warm_sol);
// std::cout << "Robust score du warm start: " << robust_score << std::endl;
// std::cout << "Static score du warm start: " << static_score << std::endl;
// std::cout << "Robust constraint du warm start: " << robust_constraint << std::endl;
// std::cout << "Static constraint: " << static_constraint << std::endl;
// IloNumVarArray allStartVar(env);
// IloNumArray allStartValues(env, inst.n_arc + inst.n + 1);
// for (unsigned int a=0; a<inst.n_arc; a++) {
// allStartVar.add(x[a]);
// allStartValues[a] = 0.0;
// }
// for (unsigned int i=0; i<inst.n; i++) {
// allStartVar.add(y[i]);
// allStartValues[i+inst.n_arc] = 0.0;
// }
// allStartVar.add(z);
// for (unsigned int i=0; i<warm_sol.size()-1; i++) {
// for (unsigned int a=0; a<inst.n_arc; a++) {
// if (inst.mat[a].tail == warm_sol[i] && inst.mat[a].head == warm_sol[i+1]) {
// allStartValues[a] = 1;
// break;
// }
// }
// }
// allStartValues[68500] = 1.0;
// allStartValues[77460] = 1.0;
// for (unsigned int i=0; i<warm_sol.size(); i++) {
// allStartValues[warm_sol[i]-1+inst.n_arc] = 1.0;
// }
// allStartValues[inst.n_arc+968] = 1.0;
// allStartValues[inst.n_arc+1157] = 1.0;
// allStartValues[inst.n_arc+inst.n] = robust_score;
// cplex.addMIPStart(allStartVar, allStartValues);
// allStartVar.end();
// allStartValues.end();
**close_model**
c'est une bonne pratique d'ajouter model.end() et cplex.end() à la fin du programme
Mais c'est extrêmement long (plusieurs dizaines de secondes) pour branch and cut par exemple
Donc nous ne le faisons pas volontairement
Plans_coupants
Problème
Domain error caught: Using arc that does not exist for instance data/processed/100_USA-road-d.NY.gr
if current_node == sol[inst.sol - 1] instead of sol[sol.size - 1]...
Les dangers du copier collé.
Autre problème. Quand on ne trouvait pas de solution admissible lors du run.
La meilleure solution restait initialisée à 0 et donc n'était pas un chemin admissible.
Pour rectifier cela, on garde en mémoire la meilleure solution admissible ou la meilleure solution non admissible
mais qui viole moins les contraintes.
A moins que CPLEX ne trouve pas un chemin de s à t, (ce qui n'arrive pas en pratique), cela ne doit plus crasher.
Et si jamais c'est le cas et que CPLEX ne trouve pas de chemin, ça ne me parait pas déconnant que cela renvoit une erreur.