- Main Page
- Namespaces
- Classes
- Files

- Search for |

# eoVRPQuadCrossover.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 eoVRPQuadCrossover_H
    00037 #define eoVRPQuadCrossover_H
    00038
    00039 // General includes
    00040 #include <assert.h>
    00041 #include <values.h>
    00042 #include <utils/eoRNG.h>
    00043 #include <set>
    00044
    00045 // The base definition of eoQuadOp
    00046 #include <eoOp.h>
    00047
    00053 class eoVRPGenericCrossover: public eoQuadOp <eoVRP> {
    00054
    00055 public:
    00056
    00061     eoVRPGenericCrossover () {
    00062
    00063     }
    00064
    00065
    00071     std::string className () const {
    00072
    00073         return "eoVRPGenericCrossover";
    00074
    00075     }
    00076
    00077
    00085     bool operator () (eoVRP& _genotype1, eoVRP& _genotype2) {
    00086
    00087         Routes c1 = _genotype1.routes ();
    00088         Routes c2 = _genotype2.routes ();
    00089
    00090         GenericCrossover (_genotype1.routes (), c2);
    00091         GenericCrossover (_genotype2.routes (), c1);
    00092
    00093         _genotype1.encode (c1);
    00094         _genotype2.encode (c2);
    00095
    00096         return true;
    00097
    00098     }
    00099
    00100
    00101 private:
    00102
    00110     bool GenericCrossover (const Routes& _donor, Routes& _receiver) const {
    00111
    00112         unsigned srcRoute = rng.random (_donor.size ());
    00113         unsigned srcPos1  = rng.random (_donor [srcRoute].size ());
    00114         unsigned srcPos2  = rng.random (_donor [srcRoute].size ());
    00115
    00116         if (srcPos1 > srcPos2)
    00117             std::swap (srcPos1, srcPos2);
    00118
    00119         Route::iterator it;
    00120
    00121         for (unsigned i = srcPos1; i <= srcPos2; i++)
    00122             for (unsigned j = 0; j < _receiver.size (); j++) {
    00123
    00124                 it = find (_receiver [j].begin (), _receiver [j].end (), _donor [srcRoute][i]);
    00125
    00126                 if (it != _receiver [j].end ()) {
    00127
    00128                     // Deletion of the repeated client
    00129                     _receiver [j].erase (it);
    00130
    00131                     // Deletion of empty route, if necessary
    00132                     if (_receiver [j].size () == 0)
    00133                         _receiver.erase (_receiver.begin () + j);
    00134
    00135                     break;
    00136
    00137                 }
    00138
    00139             }
    00140
    00141         unsigned dstRoute = rng.random (_receiver.size ());
    00142
    00143         it = _receiver [dstRoute].begin () + rng.random (_receiver [dstRoute].size ());
    00144
    00145         _receiver [dstRoute].insert (it + 1, _donor [srcRoute].begin () + srcPos1, _donor [srcRoute].begin () + srcPos2 + 1);
    00146
    00147         return true;
    00148
    00149     }
    00150
    00151 };
    00152
    00153
    00159 class eoVRPOnePointCrossover: public eoQuadOp <eoVRP> {
    00160
    00161 public:
    00162
    00167     eoVRPOnePointCrossover () {
    00168
    00169     }
    00170
    00171
    00177     std::string className () const {
    00178
    00179         return "eoVRPOnePointCrossover";
    00180
    00181     }
    00182
    00183
    00191     bool operator () (eoVRP& _genotype1, eoVRP& _genotype2) {
    00192
    00193         eoVRP& _gen = _genotype1;
    00194
    00195         unsigned orig1, orig2, dest;
    00196
    00197         // First child
    00198         orig1 = rng.random (_genotype2.size ());
    00199         orig2 = rng.random (_genotype2.size ());
    00200
    00201         if (orig1 > orig2)
    00202             std::swap (orig1, orig2);
    00203
    00204         for (unsigned i = orig1; i <= orig2; i++)
    00205             _genotype1.erase (find (_genotype1.begin (), _genotype1.end (), _genotype2 [i]));
    00206
    00207         dest = rng.random (_genotype1.size ());
    00208
    00209         _genotype1.insert (_genotype1.begin () + dest, _genotype2.begin () + orig1, _genotype2.begin () + orig2 + 1);
    00210
    00211         // Second child
    00212         orig1 = rng.random (_gen.size ());
    00213         orig2 = rng.random (_gen.size ());
    00214
    00215         if (orig1 > orig2)
    00216             std::swap (orig1, orig2);
    00217
    00218         for (unsigned i = orig1; i <= orig2; i++)
    00219             _genotype2.erase (find (_genotype2.begin (), _genotype2.end (), _gen [i]));
    00220
    00221         dest = rng.random (_genotype2.size ());
    00222
    00223         _genotype2.insert (_genotype2.begin () + dest, _gen.begin () + orig1, _gen.begin () + orig2 + 1);
    00224
    00225         _genotype1.cleanRoutes ();
    00226         _genotype2.cleanRoutes ();
    00227
    00228         return true;
    00229
    00230     }
    00231
    00232 };
    00233
    00234
    00240 class eoVRPEdgeCrossover: public eoQuadOp <eoVRP> {
    00241
    00242 public:
    00243
    00248     eoVRPEdgeCrossover () {
    00249
    00250     }
    00251
    00252
    00258     std::string className () const {
    00259
    00260         return "eoVRPEdgeCrossover";
    00261
    00262     }
    00263
    00264
    00272     bool operator () (eoVRP& _genotype1, eoVRP& _genotype2) {
    00273
    00274         eoVRP par [2];
    00275
    00276         // Backup of the parents
    00277         par [0] = _genotype1;
    00278         par [1] = _genotype2;
    00279
    00280         _genotype1.clean ();
    00281         _genotype2.clean ();
    00282
    00283         EdgeCrossover (par [0], par [1], _genotype1);
    00284         EdgeCrossover (par [0], par [1], _genotype2);
    00285
    00286         return true;
    00287
    00288     }
    00289
    00290
    00291 private:
    00292
    00301     bool EdgeCrossover (eoVRP& _genotype1, eoVRP& _genotype2, eoVRP& _child) {
    00302
    00303         std::vector <std::set <unsigned> > _map;
    00304         std::vector <bool> visited;
    00305
    00306         // Build map
    00307         unsigned len = _genotype1.size () ;
    00308
    00309         _map.resize (len+1) ;
    00310
    00311         for (unsigned i = 0 ; i < len ; i ++) {
    00312
    00313             _map [_genotype1 [i]].insert (_genotype1 [(i + 1) % len]) ;
    00314             _map [_genotype2 [i]].insert (_genotype2 [(i + 1) % len]) ;
    00315             _map [_genotype1 [i]].insert (_genotype1 [(i - 1 + len) % len]) ;
    00316             _map [_genotype2 [i]].insert (_genotype2 [(i - 1 + len) % len]) ;
    00317
    00318         }
    00319
    00320         visited.clear () ;
    00321         visited.resize (len+1, false) ;
    00322
    00323
    00324         _child.clear () ;
    00325
    00326         unsigned cur_vertex = rng.random (len)+1;
    00327
    00328         add_vertex (cur_vertex, visited, _map, _child);
    00329
    00330         for (unsigned i = 1; i < len; i ++) {
    00331
    00332             unsigned len_min_entry = MAXINT;
    00333
    00334             std::set <unsigned>& neigh = _map [cur_vertex];
    00335
    00336             for (std::set <unsigned>::iterator it = neigh.begin (); it != neigh.end (); it ++) {
    00337
    00338                     unsigned l = _map [*it].size ();
    00339
    00340                     if (len_min_entry > l)
    00341                         len_min_entry = l;
    00342
    00343                 }
    00344
    00345             std::vector <unsigned> cand; /* Candidates */
    00346
    00347             for (std::set <unsigned>::iterator it = neigh.begin (); it != neigh.end (); it ++) {
    00348
    00349                     unsigned l = _map [*it].size ();
    00350
    00351                     if (len_min_entry == l)
    00352                         cand.push_back (*it);
    00353
    00354                 }
    00355
    00356             if (!cand.size ()) {
    00357
    00358                 /* Oh no ! Implicit mutation */
    00359                 for (unsigned j = 1; j <= len; j ++)
    00360                     if (!visited [j])
    00361                         cand.push_back (j);
    00362
    00363             }
    00364
    00365             cur_vertex = cand [rng.random (cand.size ())] ;
    00366
    00367             add_vertex (cur_vertex, visited, _map, _child);
    00368
    00369         }
    00370
    00371     }
    00372
    00373
    00380     void remove_entry (unsigned _vertex, std::vector <std::set <unsigned> >& _map) {
    00381
    00382         std::set <unsigned>& neigh = _map [_vertex];
    00383
    00384         for (std::set <unsigned>::iterator it = neigh.begin (); it != neigh.end (); it++)
    00385                 _map [*it].erase (_vertex);
    00386
    00387     }
    00388
    00389
    00398     void add_vertex (unsigned _vertex, std::vector <bool>& _visited, std::vector <std::set <unsigned> >& _map, eoVRP& _child) {
    00399
    00400         _visited [_vertex] = true;
    00401         _child.push_back (_vertex);
    00402         remove_entry (_vertex, _map);
    00403
    00404     }
    00405
    00406 };
    00407
    00408 #endif