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 #include <values.h>
00039
00040 #include <utils/eoRNG.h>
00041
00042 #include "edge_xover.h"
00043
00044 void EdgeXover :: build_map (const Route & __par1, const Route & __par2)
00045 {
00046
00047 unsigned len = __par1.size () ;
00048
00049
00050 _map.clear () ;
00051 _map.resize (len) ;
00052
00053 for (unsigned i = 0 ; i < len ; i ++)
00054 {
00055 _map [__par1 [i]].insert (__par1 [(i + 1) % len]) ;
00056 _map [__par2 [i]].insert (__par2 [(i + 1) % len]) ;
00057 _map [__par1 [i]].insert (__par1 [(i - 1 + len) % len]) ;
00058 _map [__par2 [i]].insert (__par2 [(i - 1 + len) % len]) ;
00059 }
00060
00061 visited.clear () ;
00062 visited.resize (len, false) ;
00063 }
00064
00065 void EdgeXover :: remove_entry (unsigned __vertex, std :: vector <std :: set <unsigned> > & __map)
00066 {
00067
00068 std :: set <unsigned> & neigh = __map [__vertex] ;
00069
00070 for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00071 it != neigh.end () ;
00072 it ++)
00073 __map [* it].erase (__vertex) ;
00074
00075 }
00076
00077 void EdgeXover :: add_vertex (unsigned __vertex, Route & __child)
00078 {
00079
00080 visited [__vertex] = true ;
00081 __child.push_back (__vertex) ;
00082 remove_entry (__vertex, _map) ;
00083 }
00084
00085 void EdgeXover :: cross (const Route & __par1, const Route & __par2, Route & __child)
00086 {
00087
00088 build_map (__par1, __par2) ;
00089
00090 unsigned len = __par1.size () ;
00091
00092
00093 __child.clear () ;
00094
00095 unsigned cur_vertex = rng.random (len) ;
00096
00097 add_vertex (cur_vertex, __child) ;
00098
00099 for (unsigned i = 1 ; i < len ; i ++)
00100 {
00101
00102 unsigned len_min_entry = MAXINT ;
00103
00104 std :: set <unsigned> & neigh = _map [cur_vertex] ;
00105
00106 for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00107 it != neigh.end () ;
00108 it ++)
00109 {
00110 unsigned l = _map [* it].size () ;
00111 if (len_min_entry > l)
00112 len_min_entry = l ;
00113 }
00114
00115 std :: vector <unsigned> cand ;
00116
00117 for (std :: set <unsigned> :: iterator it = neigh.begin () ;
00118 it != neigh.end () ;
00119 it ++)
00120 {
00121 unsigned l = _map [* it].size () ;
00122 if (len_min_entry == l)
00123 cand.push_back (* it) ;
00124 }
00125
00126 if (! cand.size ())
00127 {
00128
00129
00130 for (unsigned j = 0 ; j < len ; j ++)
00131 if (! visited [j])
00132 cand.push_back (j) ;
00133 }
00134
00135 cur_vertex = cand [rng.random (cand.size ())] ;
00136
00137 add_vertex (cur_vertex, __child) ;
00138 }
00139 }
00140
00141 bool EdgeXover :: operator () (Route & __route1, Route & __route2)
00142 {
00143
00144
00145 Route par [2] ;
00146 par [0] = __route1 ;
00147 par [1] = __route2 ;
00148
00149 cross (par [0], par [1], __route1) ;
00150 cross (par [1], par [0], __route2) ;
00151
00152 __route1.invalidate () ;
00153 __route2.invalidate () ;
00154
00155 return true ;
00156 }