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 }

Generated on Thu Sep 20 11:30:28 2007 for ParadisEO-MOMovingObjects by  doxygen 1.5.2