- Main Page
- Namespaces
- Classes
- Files

- Search for |

# edge_xover.cpp

    00001 // -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
    00002
    00003 // "edge_xover.cpp"
    00004
    00005 // (c) OPAC Team, LIFL, 2003-2006
    00006
    00007 /* LICENCE TEXT
    00008
    00009    Contact: paradiseo-help@lists.gforge.inria.fr
    00010 */
    00011
    00012 #include <assert.h>
    00013
    00014 #include <utils/eoRNG.h>
    00015
    00016 #include "edge_xover.h"
    00017 #include "route_valid.h"
    00018
    00019 #define MAXINT 1000000
    00020
    00021 void
    00022 EdgeXover :: build_map (const Route & __par1, const Route & __par2)
    00023 {
    00024
    00025   unsigned int len = __par1.size () ;
    00026
    00027   /* Initialization */
    00028   _map.clear () ;
    00029   _map.resize (len) ;
    00030
    00031   for (unsigned int i = 0 ; i < len ; i ++)
    00032     {
    00033       _map [__par1 [i]].insert (__par1 [(i + 1) % len]) ;
    00034       _map [__par2 [i]].insert (__par2 [(i + 1) % len]) ;
    00035       _map [__par1 [i]].insert (__par1 [(i - 1 + len) % len]) ;
    00036       _map [__par2 [i]].insert (__par2 [(i - 1 + len) % len]) ;
    00037     }
    00038
    00039   visited.clear () ;
    00040   visited.resize (len, false) ;
    00041 }
    00042
    00043 void
    00044 EdgeXover :: remove_entry (unsigned int __vertex, std :: vector <std :: set <unsigned int> > & __map)
    00045 {
    00046
    00047   std :: set <unsigned int> & neigh = __map [__vertex] ;
    00048
    00049   for (std :: set <unsigned int> :: iterator it = neigh.begin () ; it != neigh.end () ; it ++)
    00050     {
    00051       __map [* it].erase (__vertex) ;
    00052     }
    00053
    00054 }
    00055
    00056 void
    00057 EdgeXover :: add_vertex (unsigned int __vertex, Route & __child)
    00058 {
    00059   visited [__vertex] = true ;
    00060   __child.push_back (__vertex) ;
    00061   remove_entry (__vertex, _map) ; /* Removing entries */
    00062 }
    00063
    00064 void
    00065 EdgeXover :: cross (const Route & __par1, const Route & __par2, Route & __child) {
    00066
    00067   build_map (__par1, __par2) ;
    00068
    00069   unsigned int len = __par1.size () ;
    00070
    00071   /* Go ! */
    00072   __child.clear () ;
    00073
    00074   unsigned int cur_vertex = rng.random (len) ;
    00075
    00076   add_vertex (cur_vertex, __child) ;
    00077
    00078   for (unsigned int i = 1 ; i < len ; i ++) {
    00079
    00080     unsigned int len_min_entry = MAXINT ;
    00081
    00082     std :: set <unsigned int> & neigh = _map [cur_vertex] ;
    00083
    00084     for (std :: set <unsigned int> :: iterator it = neigh.begin () ; it != neigh.end () ; it ++)
    00085       {
    00086         unsigned int l = _map [* it].size () ;
    00087         if (len_min_entry > l)
    00088           {
    00089             len_min_entry = l ;
    00090           }
    00091       }
    00092
    00093     std :: vector <unsigned int> cand ; /* Candidates */
    00094
    00095     for (std :: set <unsigned> :: iterator it = neigh.begin () ; it != neigh.end () ;  it ++)
    00096       {
    00097         unsigned int l = _map [* it].size () ;
    00098         if (len_min_entry == l)
    00099           {
    00100             cand.push_back (* it) ;
    00101           }
    00102       }
    00103
    00104     if (! cand.size ())
    00105       {
    00106
    00107         /* Oh no ! Implicit mutation */
    00108         for (unsigned int j = 0 ; j < len ; j ++)
    00109           {
    00110             if (! visited [j])
    00111               {
    00112                 cand.push_back (j) ;
    00113               }
    00114           }
    00115       }
    00116
    00117     cur_vertex = cand [rng.random (cand.size ())] ;
    00118
    00119     add_vertex (cur_vertex, __child) ;
    00120   }
    00121 }
    00122
    00123 bool
    00124 EdgeXover :: operator () (Route & __route1, Route & __route2)
    00125 {
    00126
    00127   // Init. copy
    00128   Route par [2] ;
    00129   par [0] = __route1 ;
    00130   par [1] = __route2 ;
    00131
    00132   cross (par [0], par [1], __route1) ;
    00133   cross (par [1], par [0], __route2) ;
    00134
    00135   assert (valid (__route1)) ;
    00136   assert (valid (__route2)) ;
    00137
    00138   __route1.invalidate () ;
    00139   __route2.invalidate () ;
    00140
    00141   return true ;
    00142 }