00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <assert.h>
00025
00026 #include <utils/eoRNG.h>
00027
00028 #include "order_xover.h"
00029
00030 void OrderXover :: cross (const Route & __par1, const Route & __par2, Route & __child) {
00031
00032 unsigned cut2 = 1 + rng.random (numNodes) ;
00033 unsigned cut1 = rng.random (cut2);
00034 unsigned l = 0;
00035
00036
00037 std :: vector <bool> v (numNodes, false);
00038
00039
00040 for (unsigned i = cut1 ; i < cut2 ; i ++) {
00041 __child [l ++] = __par1 [i] ;
00042 v [__par1 [i]] = true ;
00043 }
00044
00045
00046 unsigned from = 0 ;
00047 for (unsigned i = 0; i < numNodes; i ++)
00048 if (__par2 [i] == __child [cut2 - 1]) {
00049 from = i ;
00050 break ;
00051 }
00052
00053
00054 char direct = rng.flip () ? 1 : -1 ;
00055
00056 for (unsigned i = 0; i < numNodes + 1; i ++) {
00057 unsigned bidule = (direct * i + from + numNodes) % numNodes;
00058 if (! v [__par2 [bidule]]) {
00059 __child [l ++] = __par2 [bidule] ;
00060 v [__par2 [bidule]] = true ;
00061 }
00062 }
00063 }
00064
00065 bool OrderXover :: operator () (Route & __route1, Route & __route2) {
00066
00067
00068 Route par [2] ;
00069 par [0] = __route1 ;
00070 par [1] = __route2 ;
00071
00072 cross (par [0], par [1], __route1) ;
00073 cross (par [1], par [0], __route2) ;
00074
00075 __route1.invalidate () ;
00076 __route2.invalidate () ;
00077
00078 return true ;
00079 }