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
00006 
00007 /* This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2 of the License, or (at your option) any later version.
00011    
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016    
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with this library; if not, write to the Free Software
00019    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00020    
00021    Contact: cahon@lifl.fr
00022 */
00023 
00024 #include <assert.h>
00025 #include <values.h>
00026 
00027 #include <utils/eoRNG.h>
00028 
00029 #include "edge_xover.h"
00030 
00031 void EdgeXover :: build_map (const Route & __par1, const Route & __par2) {
00032   
00033   unsigned len = __par1.size () ;
00034   
00035   /* Initialization */
00036   _map.clear () ;
00037   _map.resize (len) ;
00038   
00039   for (unsigned i = 0 ; i < len ; i ++) {
00040     _map [__par1 [i]].insert (__par1 [(i + 1) % len]) ;
00041     _map [__par2 [i]].insert (__par2 [(i + 1) % len]) ;
00042     _map [__par1 [i]].insert (__par1 [(i - 1 + len) % len]) ;
00043     _map [__par2 [i]].insert (__par2 [(i - 1 + len) % len]) ;
00044   }
00045   
00046   visited.clear () ;
00047   visited.resize (len, false) ;
00048 }
00049 
00050 void EdgeXover :: remove_entry (unsigned __vertex, std :: vector <std :: set <unsigned> > & __map) {
00051   
00052   std :: set <unsigned> & neigh = __map [__vertex] ;
00053 
00054   for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00055        it != neigh.end () ;
00056        it ++)
00057     __map [* it].erase (__vertex) ; 
00058       
00059 }
00060 
00061 void EdgeXover :: add_vertex (unsigned __vertex, Route & __child) {
00062   
00063   visited [__vertex] = true ;
00064   __child.push_back (__vertex) ;    
00065   remove_entry (__vertex, _map) ; /* Removing entries */    
00066 }
00067 
00068 void EdgeXover :: cross (const Route & __par1, const Route & __par2, Route & __child) {
00069   
00070   build_map (__par1, __par2) ;
00071   
00072   unsigned len = __par1.size () ;
00073  
00074   /* Go ! */
00075   __child.clear () ;
00076   
00077   unsigned cur_vertex = rng.random (len) ;
00078   
00079   add_vertex (cur_vertex, __child) ;
00080 
00081   for (unsigned i = 1 ; i < len ; i ++) {
00082     
00083     unsigned len_min_entry = MAXINT ;
00084     
00085     std :: set <unsigned> & neigh = _map [cur_vertex] ;
00086     
00087     for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00088          it != neigh.end () ;
00089          it ++) {      
00090       unsigned l = _map [* it].size () ;
00091       if (len_min_entry > l)
00092         len_min_entry = l ;
00093     }
00094     
00095     std :: vector <unsigned> cand ; /* Candidates */
00096     
00097     for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00098          it != neigh.end () ;
00099          it ++) {      
00100       unsigned l = _map [* it].size () ;
00101       if (len_min_entry == l)
00102         cand.push_back (* it) ;
00103     }
00104        
00105     if (! cand.size ()) {
00106       
00107       /* Oh no ! Implicit mutation */      
00108       for (unsigned j = 0 ; j < len ; j ++)
00109         if (! visited [j])
00110           cand.push_back (j) ;
00111     }
00112 
00113     cur_vertex = cand [rng.random (cand.size ())] ;
00114     
00115     add_vertex (cur_vertex, __child) ;
00116   } 
00117 }
00118 
00119 bool EdgeXover :: operator () (Route & __route1, Route & __route2) {
00120   
00121   // Init. copy
00122   Route par [2] ;
00123   par [0] = __route1 ;
00124   par [1] = __route2 ;
00125   
00126   cross (par [0], par [1], __route1) ;
00127   cross (par [1], par [0], __route2) ;
00128   
00129   __route1.invalidate () ;
00130   __route2.invalidate () ;
00131 
00132   return true ;
00133 }

Generated on Fri Dec 22 16:54:58 2006 for ParadisEO by  doxygen 1.4.7