00001
00002
00003
00004
00005
00006
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
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) ;
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
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 ;
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
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
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 }