00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef _eoVRPInit_h
00037 #define _eoVRPInit_h
00038
00039
00040 #include <eoInit.h>
00041
00042
00043 #include "eoVRPUtils.h"
00044
00054 #define ALFA 0.7
00055 #define BETA 0.1
00056 #define GAMMA 0.2
00057
00065 class eoVRPInit: public eoInit <eoVRP> {
00066
00067 public:
00068
00073 eoVRPInit () {
00074
00075 unsigned sz = eoVRPUtils::clients.size ();
00076
00077 if (sz <= 0) {
00078
00079 std::cerr << "Error: the dataset MUST be read before creating the initializer object." << std::endl;
00080 abort ();
00081
00082 }
00083
00084 mSeedsUsedCount = 0;
00085
00086 for (unsigned i = 0; i < sz; i++)
00087 mSeedsUsed.push_back (false);
00088
00089 }
00090
00091
00099 void operator () (eoVRP& _gen) {
00100
00101 HeuristicInitialization (_gen);
00102
00103 }
00104
00105
00106 private:
00107
00108 unsigned mSeedsUsedCount;
00109 std::vector<bool> mSeedsUsed;
00123 void HeuristicInitialization (eoVRP& _gen) {
00124
00125
00126 bool seedCheckingOverride = false;
00127
00128
00129 _gen.clear ();
00130
00131
00132 std::vector<int> unvisited;
00133
00134
00135 int unvisitedIdx = eoVRPUtils::clients.size () - 2;
00136
00137
00138 for (unsigned i = 1; i < eoVRPUtils::clients.size (); i++)
00139 unvisited.push_back (i);
00140
00141
00142 while (unvisitedIdx >= 0) {
00143
00144
00145 Route route;
00146
00147 createNewRoute (unvisited, unvisitedIdx, seedCheckingOverride, route);
00148 seedCheckingOverride = true;
00149
00150 for (unsigned i = 0; i < route.size (); i++)
00151 _gen.push_back (route [i]);
00152
00153 }
00154
00155
00156 _gen.invalidate ();
00157
00158 }
00159
00160
00176 bool createNewRoute (std::vector<int>& _unvisited, int& _unvisitedIdx,
00177 bool _seedCheckingOverride, Route& _route ) {
00178
00179
00180 unsigned seed = selectBestClientAsSeed (_unvisited, _unvisitedIdx, _seedCheckingOverride);
00181
00182
00183 _route.push_back (_unvisited [seed]);
00184
00185
00186
00187 if (!_seedCheckingOverride) {
00188
00189 mSeedsUsed [_unvisited [seed]] = true;
00190 mSeedsUsedCount++;
00191
00192 if (mSeedsUsedCount == mSeedsUsed.size () - 1) {
00193
00194 mSeedsUsedCount = 0;
00195
00196 for (unsigned i = 0; i < mSeedsUsed.size (); i++)
00197 mSeedsUsed [i] = false;
00198
00199 }
00200
00201 }
00202
00203
00204 _unvisited [seed] = _unvisited [_unvisitedIdx];
00205 _unvisitedIdx--;
00206
00207 bool feasibleInsert = true;
00208
00209 while (feasibleInsert && _unvisitedIdx >= 0) {
00210
00211
00212 Route::iterator it;
00213
00214 unsigned next;
00215
00216 if (selectBestInsertion (_unvisited, _unvisitedIdx, _route, next, it)) {
00217
00218 if (it == _route.end ())
00219 _route.insert (_route.begin (), _unvisited [next]);
00220 else
00221 _route.insert (it + 1, _unvisited [next]);
00222
00223 _unvisited [next] = _unvisited [_unvisitedIdx];
00224 _unvisitedIdx--;
00225
00226 }
00227 else
00228 feasibleInsert = false;
00229
00230 }
00231
00232 return true;
00233
00234 }
00235
00236
00249 bool selectBestInsertion (std::vector<int>& _unvisited, unsigned _unvisitedIdx, Route& _route,
00250 unsigned& _nextClient, Route::iterator& _it ) {
00251
00252 double minCost = 999999999;
00253 bool found = false;
00254
00255 bool insertionPossible = false;
00256 double cost = 0.0;
00257
00258 for (unsigned i = 0; i < _unvisitedIdx; i++) {
00259
00260 insertionPossible = evaluateInsertion (_route, _unvisited [i], -1, cost);
00261
00262 if (insertionPossible && cost < minCost) {
00263
00264 _it = _route.end ();
00265 _nextClient = i;
00266 minCost = cost;
00267 found = true;
00268
00269 }
00270
00271 }
00272
00273 for (Route::iterator it = _route.begin (); it != _route.end (); it++) {
00274
00275 for (unsigned i = 0; i < _unvisitedIdx; i++) {
00276
00277 insertionPossible = evaluateInsertion (_route, _unvisited [i], *it, cost);
00278
00279 if (insertionPossible && cost < minCost) {
00280
00281 _it = it;
00282 _nextClient = i;
00283 minCost = cost;
00284 found = true;
00285
00286 }
00287
00288 }
00289
00290 }
00291
00292 return found;
00293
00294 }
00295
00296
00308 bool evaluateInsertion (Route& _route, unsigned _newClient, int _afterClient, double& _cost) {
00309
00310
00311
00312 double demand = 0.0;
00313
00314
00315 for (unsigned i = 0; i < _route.size (); i++)
00316 demand += eoVRPUtils::clients [i].demand;
00317
00318
00319 demand += eoVRPUtils::clients [_newClient].demand;
00320
00321
00322 if (demand > VEHICLE_CAPACITY)
00323 return false;
00324
00325
00326 double readyTime, dueTime, serviceTime;
00327
00328
00329
00330 if (_afterClient == - 1) {
00331
00332
00333 _cost = eoVRPUtils::distance (0, _newClient);
00334
00335
00336 eoVRPUtils::getTimeWindow (_newClient, readyTime, dueTime, serviceTime);
00337
00338 if (_cost > dueTime)
00339 return false;
00340
00341
00342
00343 if (_cost < readyTime)
00344 _cost = readyTime;
00345
00346
00347 _cost += serviceTime;
00348
00349
00350 _cost = _cost + eoVRPUtils::distance (_newClient, _route [0]);
00351
00352 }
00353 else
00354
00355 _cost = eoVRPUtils::distance (0, _route [0]);
00356
00357
00358 for (unsigned i = 0; i < _route.size () - 1; i++) {
00359
00360
00361 eoVRPUtils::getTimeWindow (_route [i], readyTime, dueTime, serviceTime);
00362
00363 if (_cost > dueTime)
00364 return false;
00365
00366
00367
00368 if (_cost < readyTime)
00369 _cost = readyTime;
00370
00371
00372 _cost += serviceTime;
00373
00374
00375 if (_route [i] == _afterClient) {
00376
00377
00378
00379 _cost = _cost + eoVRPUtils::distance (_route [i], _newClient);
00380
00381
00382 eoVRPUtils::getTimeWindow (_newClient, readyTime, dueTime, serviceTime);
00383
00384 if (_cost > dueTime)
00385 return false;
00386
00387
00388
00389 if (_cost < readyTime)
00390 _cost = readyTime;
00391
00392
00393 _cost += serviceTime;
00394
00395
00396 _cost = _cost + eoVRPUtils::distance (_newClient, _route [i + 1]);
00397
00398 }
00399 else
00400
00401 _cost = _cost + eoVRPUtils::distance (_route [i], _route [i + 1]);
00402
00403 }
00404
00405
00406
00407 unsigned last =_route [_route.size () - 1];
00408
00409
00410
00411 eoVRPUtils::getTimeWindow (last, readyTime, dueTime, serviceTime);
00412
00413 if (_cost > dueTime)
00414 return false;
00415
00416
00417 if (_cost < readyTime)
00418 _cost = readyTime;
00419
00420
00421 _cost += serviceTime;
00422
00423
00424
00425 if (_afterClient == last) {
00426
00427
00428
00429 _cost = _cost + eoVRPUtils::distance (last, _newClient);
00430
00431
00432 eoVRPUtils::getTimeWindow (_newClient, readyTime, dueTime, serviceTime);
00433
00434 if (_cost > dueTime)
00435 return false;
00436
00437
00438 if (_cost < readyTime)
00439 _cost = readyTime;
00440
00441
00442 _cost += serviceTime;
00443
00444
00445 _cost = _cost + eoVRPUtils::distance (_newClient, 0);
00446
00447 }
00448 else
00449
00450 _cost = _cost + eoVRPUtils::distance (last, 0);
00451
00452
00453 eoVRPUtils::getTimeWindow (0, readyTime, dueTime, serviceTime);
00454
00455 if (_cost > dueTime)
00456 return false;
00457
00458
00459
00460 return true;
00461
00462 }
00463
00464
00472 unsigned selectFarthestClientAsSeed (const std::vector<int>& _unvisited, int _unvisitedIdx) {
00473
00474 unsigned maxPos = 0;
00475 double maxDist = eoVRPUtils::distance (0, _unvisited [0]);
00476
00477 for (unsigned i = 1; i <= _unvisitedIdx; i++)
00478 if (eoVRPUtils::distance (0, _unvisited [i]) > maxDist) {
00479
00480 maxPos = i;
00481 maxDist = eoVRPUtils::distance (0, _unvisited [i]);
00482
00483 }
00484
00485 return maxPos;
00486
00487 }
00488
00489
00498 unsigned selectCheapestClient (const std::vector<int>& _unvisited, int _unvisitedIdx, bool _seedCheckingOverride) {
00499
00500 int cheapestPos = -1;
00501 double cheapestCost = 999999999;
00502
00503 for (unsigned i = 0; i <= _unvisitedIdx; i++) {
00504
00505 double cost = (-ALFA * eoVRPUtils::distance (0, _unvisited [i]) ) +
00506 ( BETA * eoVRPUtils::clients [_unvisited [i]].dueTime) +
00507 (GAMMA * eoVRPUtils::polarAngle (0, _unvisited [i]) / 360 * eoVRPUtils::distance (0, _unvisited [i]));
00508
00509 if ((cost < cheapestCost || (cost == cheapestCost && rng.flip ())) &&
00510 (!mSeedsUsed [_unvisited [i]] || _seedCheckingOverride ) ) {
00511
00512 cheapestPos = i;
00513 cheapestCost = cost;
00514
00515 }
00516
00517 }
00518
00519 return cheapestPos;
00520
00521 }
00522
00523
00532 unsigned selectBestClientAsSeed (const std::vector<int>& _unvisited, int _unvisitedIdx, bool _seedCheckingOverride) {
00533
00534 int cheapestPos = -1;
00535 double cheapestCost = 999999999;
00536 double alfa, beta;
00537
00538 alfa = rng.uniform ();
00539 beta = rng.uniform ();
00540
00541 for (unsigned i = 0; i <= _unvisitedIdx; i++) {
00542
00543 double cost = (alfa * eoVRPUtils::distance (0, _unvisited [i])) +
00544 (beta * (eoVRPUtils::clients [_unvisited [i]].dueTime - eoVRPUtils::clients [_unvisited [i]].readyTime));
00545
00546
00547 if ((cost < cheapestCost || (cost == cheapestCost && rng.flip ())) &&
00548 (!mSeedsUsed [_unvisited [i]] || _seedCheckingOverride ) ) {
00549
00550 cheapestPos = i;
00551 cheapestCost = cost;
00552
00553 }
00554
00555 }
00556
00557 return cheapestPos;
00558
00559 }
00560
00561
00569 void RandomInitializationNoCheck (eoVRP& _gen) {
00570
00571
00572 _gen.clear ();
00573
00574
00575 std::vector<int> unvisited;
00576
00577
00578 int unvisitedIdx = eoVRPUtils::clients.size () - 2;
00579
00580
00581 for (unsigned i = 1; i < eoVRPUtils::clients.size (); i++)
00582 unvisited.push_back (i);
00583
00584 while (unvisitedIdx >= 0) {
00585
00586 unsigned n = rng.random (unvisitedIdx);
00587
00588 for (unsigned i = 0; i <= n; i++) {
00589
00590 unsigned pos = rng.random (unvisitedIdx);
00591
00592 _gen.push_back (unvisited [pos]);
00593
00594 unvisited [pos] = unvisited [unvisitedIdx];
00595 unvisitedIdx--;
00596
00597 }
00598
00599 }
00600
00601 }
00602
00603
00604 };
00605
00606 #endif