eoVRP.h

00001 /*
00002  * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2007
00003  * (C) OPAC Team, LIFL, 2002-2007
00004  *
00005  * (c) Antonio LaTorre <atorre@fi.upm.es>, 2007
00006  *
00007  * This software is governed by the CeCILL license under French law and
00008  * abiding by the rules of distribution of free software.  You can  use,
00009  * modify and/ or redistribute the software under the terms of the CeCILL
00010  * license as circulated by CEA, CNRS and INRIA at the following URL
00011  * "http://www.cecill.info".
00012  *
00013  * As a counterpart to the access to the source code and  rights to copy,
00014  * modify and redistribute granted by the license, users are provided only
00015  * with a limited warranty  and the software's author,  the holder of the
00016  * economic rights,  and the successive licensors  have only  limited liability.
00017  *
00018  * In this respect, the user's attention is drawn to the risks associated
00019  * with loading,  using,  modifying and/or developing or reproducing the
00020  * software by the user in light of its specific status of free software,
00021  * that may mean  that it is complicated to manipulate,  and  that  also
00022  * therefore means  that it is reserved for developers  and  experienced
00023  * professionals having in-depth computer knowledge. Users are therefore
00024  * encouraged to load and test the software's suitability as regards their
00025  * requirements in conditions enabling the security of their systems and/or
00026  * data to be ensured and,  more generally, to use and operate it in the
00027  * same conditions as regards security.
00028  * The fact that you are presently reading this means that you have had
00029  * knowledge of the CeCILL license and that you accept its terms.
00030  *
00031  * ParadisEO WebSite : http://paradiseo.gforge.inria.fr
00032  * Contact: paradiseo-help@lists.gforge.inria.fr
00033  *
00034  */
00035 
00036 #ifndef _eoVRP_h
00037 #define _eoVRP_h
00038 
00039 // The base definition of eoVector
00040 #include <eoVector.h>
00041 
00042 // Utilities for the VRP-TW problem
00043 #include "eoVRPUtils.h"
00044 
00050 class eoVRP: public eoVector<eoMinimizingFitness, int> {
00051 
00052 public:
00053 
00058     eoVRP () : mLength (0.0) {
00059 
00060     }
00061 
00062 
00068     eoVRP (const eoVRP& _orig) {
00069 
00070         operator= (_orig);
00071 
00072     }
00073 
00074 
00079     virtual ~eoVRP () {
00080 
00081     }
00082 
00083 
00090     eoVRP& operator= (const eoVRP& _orig) {
00091 
00092         // Sanity check
00093         if (&_orig != this) {
00094 
00095             // Cleans both individual and decoding information
00096             clean ();
00097 
00098             // We call the assignment operator from the base class
00099             eoVector<eoMinimizingFitness, int>::operator= (_orig);
00100 
00101             // And then copy all our attributes
00102             mRoutes  = _orig.mRoutes;
00103             mLength  = _orig.mLength;
00104 
00105         }
00106 
00107         return *this;
00108 
00109     }
00110 
00111 
00117     virtual std::string className () const {
00118 
00119         return "eoVRP";
00120 
00121     }
00122 
00123 
00129     void printOn (std::ostream& _os) const {
00130 
00131         // First write the fitness
00132         _os << std::endl;
00133 
00134         // Then the individual itself using the base printing method
00135         eoVector<eoMinimizingFitness, int>::printOn (_os);
00136         _os << std::endl << std::endl;
00137 
00138     }
00139 
00140 
00146     void printAllOn (std::ostream& _os) const {
00147 
00148         // Print the individual itself using the base printing method
00149         eoVector<eoMinimizingFitness, int>::printOn (_os);
00150         _os << std::endl << std::endl;
00151 
00152         // Check if we have decoding information to print
00153         if (decoded ()) {
00154 
00155             // First, we print the decoded routes (stored in mRoutes)
00156             _os << " => Routes: " << std::endl << std::endl;
00157             printRoutes (_os);
00158             _os << std::endl << std::endl;
00159 
00160             if (this->invalid ())
00161                 _os << " => Fitness: INVALID." << std::endl << std::endl;
00162             else
00163                 _os << " => Fitness: " << this->fitness () << std::endl << std::endl;
00164 
00165         }
00166         else
00167             std::cerr << "Warning: 'printAllOn' called but the individual was not already decoded." << std::endl;
00168 
00169     }
00170 
00171 
00177     void readFrom (std::istream& _is) {
00178 
00179         // Read the individual using the method from the base class
00180         eoVector<eoMinimizingFitness, int>::readFrom (_is);
00181 
00182     }
00183 
00184 
00190     const Routes& routes () {
00191 
00192         if (mRoutes.size () == 0)
00193             std::cerr << "Warning: This individual has not been already decoded." << std::endl;
00194 
00195         return mRoutes;
00196 
00197     }
00198 
00199 
00205     double length () {
00206 
00207         return mLength;
00208 
00209     }
00210 
00211 
00217     void printRoutes (std::ostream& _os) const {
00218 
00219         _os << "[";
00220 
00221         for (unsigned i = 0; i < mRoutes.size (); i++) {
00222 
00223             _os << "[";
00224 
00225             printRoute (_os, i);
00226 
00227             if (i == mRoutes.size () - 1)
00228                 _os << "]";
00229             else
00230                 _os << "]," << std::endl;
00231         }
00232 
00233         _os << "]";
00234 
00235     }
00236 
00237 
00244     void printRoute (std::ostream& _os, unsigned _p) const {
00245 
00246         _os << "[";
00247 
00248         for (unsigned i = 0; i < mRoutes [_p].size (); i++) {
00249 
00250             _os << mRoutes [_p][i];
00251 
00252             if (i != mRoutes [_p].size () - 1)
00253                 _os << ", ";
00254 
00255         }
00256 
00257         _os << "]";
00258 
00259     }
00260 
00261 
00267     bool clean () {
00268 
00269         this->clear ();
00270         mRoutes.clear ();
00271         mLength = 0.0;
00272 
00273         return true;
00274 
00275     }
00276 
00277 
00283     bool cleanRoutes () {
00284 
00285         mRoutes.clear ();
00286         mLength = 0.0;
00287 
00288         return true;
00289 
00290     }
00291 
00292 
00298     bool decoded () const {
00299 
00300         if (mRoutes.size () == 0)
00301             return false;
00302 
00303         return true;
00304 
00305     }
00306 
00307 
00313     bool encode (Routes& _routes) {
00314 
00315         clean ();
00316 
00317         for (unsigned i = 0; i < _routes.size (); i++) {
00318 
00319             for (unsigned j = 0; j < _routes [i].size (); j++)
00320                 this->push_back (_routes [i][j]);
00321 
00322         }
00323 
00324         return true;
00325 
00326     }
00327 
00328 
00334     double decode () {
00335 
00336         bool routeStart = true;
00337 
00338         double demand = 0.0, route_len = 0.0, time = 0.0;
00339         double readyTime, dueTime, serviceTime;
00340         double depotReadyTime, depotDueTime, depotServiceTime;
00341 
00342         cleanRoutes ();
00343 
00344         Route route;
00345 
00346         eoVRPUtils::getTimeWindow (0, depotReadyTime, depotDueTime, depotServiceTime);
00347 
00348         for (unsigned i = 0; i < this->size (); i++) {
00349 
00350             if (routeStart) {
00351 
00352                 demand = eoVRPUtils::clients [this->operator[] (i)].demand;
00353                 route_len = eoVRPUtils::distance (0, this->operator[] (i));
00354                 time = eoVRPUtils::distance (0, this->operator[] (i));
00355 
00356                 // The capacity of the vehicle must NEVER be exceeded by the first client
00357                 // (it would be an instance impossible to solve in that case)
00358                 if (demand > VEHICLE_CAPACITY) {
00359 
00360                     std::cerr << "This should never happen: " << std::endl;
00361                     abort ();
00362 
00363                 }
00364 
00365                 // Check that its TW is not exceeded
00366                 eoVRPUtils::getTimeWindow (this->operator[] (i), readyTime, dueTime, serviceTime);
00367 
00368                 // Same thing as with capacity and first client, but now with the TW
00369                 if (time > dueTime) {
00370 
00371                     std::cerr << "This should never happen: " << std::endl;
00372                     abort ();
00373 
00374                 }
00375                 else if (time < readyTime)
00376                     time = readyTime;
00377 
00378                 time += serviceTime;
00379 
00380                 route.push_back (this->operator[] (i));
00381 
00382                 routeStart = false;
00383 
00384             }
00385             else {
00386 
00387                 time += eoVRPUtils::distance (this->operator[] (i - 1), this->operator[] (i));
00388 
00389                 // Check that its TW is not exceeded
00390                 eoVRPUtils::getTimeWindow (this->operator[] (i), readyTime, dueTime, serviceTime);
00391 
00392                 if ((time > dueTime) || (time + serviceTime + eoVRPUtils::distance (this->operator[] (i), 0) > depotDueTime) ||
00393                         (demand + eoVRPUtils::clients [this->operator[] (i)].demand > VEHICLE_CAPACITY)                             ) {
00394 
00395                     route_len += eoVRPUtils::distance (this->operator[] (i - 1), 0);
00396 
00397                     mLength += route_len;
00398 
00399                     i--;
00400                     routeStart = true;
00401 
00402                     // A route should contain, at least, one client. This should never happen, anyway...
00403                     if (route.size () == 0) {
00404 
00405                         std::cerr << "Error: empty route detected while decoding. The wrong genome follows..." << std::endl;
00406                         this->printOn (std::cerr);
00407                         abort ();
00408 
00409                     }
00410 
00411                     mRoutes.push_back (route);
00412                     route.clear ();
00413 
00414                 }
00415                 else {
00416 
00417                     if (time < readyTime)
00418                         time = readyTime;
00419 
00420                     time += serviceTime;
00421 
00422                     route_len += eoVRPUtils::distance (this->operator[] (i - 1), this->operator[] (i));
00423                     demand += eoVRPUtils::clients [this->operator[] (i)].demand;
00424 
00425                     route.push_back (this->operator[] (i));
00426 
00427                 }
00428 
00429             }
00430 
00431         }
00432 
00433         if (route.size () > 0) {
00434 
00435             route_len += eoVRPUtils::distance (route [route.size () - 1], 0);
00436 
00437             mLength += route_len;
00438             mRoutes.push_back (route);
00439             route.clear ();
00440 
00441         }
00442 
00443         return mLength;
00444 
00445     }
00446 
00447 
00448 private:
00449 
00450     Routes mRoutes;   
00451     double mLength;   
00453 };
00454 
00455 #endif

Generated on Fri Dec 7 16:57:19 2007 for CVRP-TW by  doxygen 1.4.7