edge_xover.cpp

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

Generated on Tue Jan 9 15:47:41 2007 for ParadisEO-PEO - Lessons by  doxygen 1.4.7