00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <assert.h>
00038
00039 #include <utils/eoRNG.h>
00040
00041 #include "edge_xover.h"
00042 #include "route_valid.h"
00043
00044 #define MAXINT 1000000
00045
00046 void
00047 EdgeXover :: build_map (const Route & __par1, const Route & __par2)
00048 {
00049
00050 unsigned int len = __par1.size () ;
00051
00052
00053 _map.clear () ;
00054 _map.resize (len) ;
00055
00056 for (unsigned int i = 0 ; i < len ; i ++)
00057 {
00058 _map [__par1 [i]].insert (__par1 [(i + 1) % len]) ;
00059 _map [__par2 [i]].insert (__par2 [(i + 1) % len]) ;
00060 _map [__par1 [i]].insert (__par1 [(i - 1 + len) % len]) ;
00061 _map [__par2 [i]].insert (__par2 [(i - 1 + len) % len]) ;
00062 }
00063
00064 visited.clear () ;
00065 visited.resize (len, false) ;
00066 }
00067
00068 void
00069 EdgeXover :: remove_entry (unsigned int __vertex, std :: vector <std :: set <unsigned int> > & __map)
00070 {
00071
00072 std :: set <unsigned int> & neigh = __map [__vertex] ;
00073
00074 for (std :: set <unsigned int> :: iterator it = neigh.begin () ; it != neigh.end () ; it ++)
00075 {
00076 __map [* it].erase (__vertex) ;
00077 }
00078
00079 }
00080
00081 void
00082 EdgeXover :: add_vertex (unsigned int __vertex, Route & __child)
00083 {
00084 visited [__vertex] = true ;
00085 __child.push_back (__vertex) ;
00086 remove_entry (__vertex, _map) ;
00087 }
00088
00089 void
00090 EdgeXover :: cross (const Route & __par1, const Route & __par2, Route & __child) {
00091
00092 build_map (__par1, __par2) ;
00093
00094 unsigned int len = __par1.size () ;
00095
00096
00097 __child.clear () ;
00098
00099 unsigned int cur_vertex = rng.random (len) ;
00100
00101 add_vertex (cur_vertex, __child) ;
00102
00103 for (unsigned int i = 1 ; i < len ; i ++) {
00104
00105 unsigned int len_min_entry = MAXINT ;
00106
00107 std :: set <unsigned int> & neigh = _map [cur_vertex] ;
00108
00109 for (std :: set <unsigned int> :: iterator it = neigh.begin () ; it != neigh.end () ; it ++)
00110 {
00111 unsigned int l = _map [* it].size () ;
00112 if (len_min_entry > l)
00113 {
00114 len_min_entry = l ;
00115 }
00116 }
00117
00118 std :: vector <unsigned int> cand ;
00119
00120 for (std :: set <unsigned> :: iterator it = neigh.begin () ; it != neigh.end () ; it ++)
00121 {
00122 unsigned int l = _map [* it].size () ;
00123 if (len_min_entry == l)
00124 {
00125 cand.push_back (* it) ;
00126 }
00127 }
00128
00129 if (! cand.size ())
00130 {
00131
00132
00133 for (unsigned int j = 0 ; j < len ; j ++)
00134 {
00135 if (! visited [j])
00136 {
00137 cand.push_back (j) ;
00138 }
00139 }
00140 }
00141
00142 cur_vertex = cand [rng.random (cand.size ())] ;
00143
00144 add_vertex (cur_vertex, __child) ;
00145 }
00146 }
00147
00148 bool
00149 EdgeXover :: operator () (Route & __route1, Route & __route2)
00150 {
00151
00152
00153 Route par [2] ;
00154 par [0] = __route1 ;
00155 par [1] = __route2 ;
00156
00157 cross (par [0], par [1], __route1) ;
00158 cross (par [1], par [0], __route2) ;
00159
00160 assert (valid (__route1)) ;
00161 assert (valid (__route2)) ;
00162
00163 __route1.invalidate () ;
00164 __route2.invalidate () ;
00165
00166 return true ;
00167 }