@@ -29,52 +29,52 @@ void testAckley() {
2929 opt.maxGenerations =1000 ;
3030 opt.maxFailTimes =100 ;
3131 static const uint8_t MinIdx=0 ,MaxIdx=1 ,LrIdx=2 ;
32- GA<std:: array<double ,2 >,false ,std:: array<double ,2 >,std:: array<double ,2 >,double > algo;
32+ GA<array<double ,2 >,false ,array<double ,2 >,array<double ,2 >,double > algo;
3333
34- std:: tuple<std:: array<double ,2 >,std:: array<double ,2 >,double > args;
35- std:: get<MinIdx>(args)={-5 ,-5 };
36- std:: get<MaxIdx>(args)={5 ,5 };
37- std:: get<LrIdx>(args)=0.05 ;
34+ tuple<array<double ,2 >,array<double ,2 >,double > args;
35+ get<MinIdx>(args)={-5 ,-5 };
36+ get<MaxIdx>(args)={5 ,5 };
37+ get<LrIdx>(args)=0.05 ;
3838
3939 algo.initialize (
40- // initializer for std:: array<double,2>
41- [](std:: array<double ,2 >* x,const typeof (args) * a) {
40+ // initializer for array<double,2>
41+ [](array<double ,2 >* x,const typeof (args) * a) {
4242 for (uint32_t idx=0 ;idx<x->size ();idx++) {
43- x->operator [](idx)=randD (std:: get<MinIdx>(*a)[idx],std:: get<MaxIdx>(*a)[idx]);
43+ x->operator [](idx)=randD (get<MinIdx>(*a)[idx],get<MaxIdx>(*a)[idx]);
4444 }},
4545 // Ackely function
46- [](const std:: array<double ,2 >* _x,const typeof (args) *) {
46+ [](const array<double ,2 >* _x,const typeof (args) *) {
4747 double x=_x->operator [](0 ),y=_x->operator [](1 );
4848 return -20 *exp (-0.2 *sqrt (0.5 *(x*x+y*y)))
4949 -exp (0.5 *(cos (M_2_PI*x)+cos (M_2_PI*y)))
5050 +20 +M_E;},
5151 // crossover
52- [](const std:: array<double ,2 >* x,const std:: array<double ,2 >* y,
53- std:: array<double ,2 > *X,std:: array<double ,2 >*Y,
52+ [](const array<double ,2 >* x,const array<double ,2 >* y,
53+ array<double ,2 > *X,array<double ,2 >*Y,
5454 const typeof (args) *) {
55- const std:: array<double ,2 > ©x=*x,©y=*y;
55+ const array<double ,2 > ©x=*x,©y=*y;
5656 for (uint32_t idx=0 ;idx<x->size ();idx++) {
57- if (std:: rand ()%2 )
57+ if (rand ()%2 )
5858 X->operator [](idx)=copyy[idx];
5959 else {
6060 X->operator [](idx)=copyx[idx];
6161 }
62- if (std:: rand ()%2 )
62+ if (rand ()%2 )
6363 Y->operator [](idx)=copyx[idx];
6464 else {
6565 Y->operator [](idx)=copyy[idx];
6666 }
6767 }},
6868 // mutate
69- [](std:: array<double ,2 >* x,const typeof (args) * a) {
70- uint8_t mutateIdx=std:: rand ()%x->size ();
71- x->operator [](mutateIdx)+=std:: get<LrIdx>(*a)*randD (-1 ,1 );
72- if (std:: rand ()%2 )
69+ [](array<double ,2 >* x,const typeof (args) * a) {
70+ uint8_t mutateIdx=rand ()%x->size ();
71+ x->operator [](mutateIdx)+=get<LrIdx>(*a)*randD (-1 ,1 );
72+ if (rand ()%2 )
7373 x->operator [](mutateIdx)*=-1 ;
7474 for (uint32_t idx=0 ;idx<x->size ();idx++) {
7575 auto & var=x->operator [](idx);
76- var=std:: min (var,std:: get<MaxIdx>(*a)[idx]);
77- var=std:: max (var,std:: get<MinIdx>(*a)[idx]);
76+ var=min (var,get<MaxIdx>(*a)[idx]);
77+ var=max (var,get<MinIdx>(*a)[idx]);
7878 }
7979 },
8080 // no other options
@@ -100,16 +100,16 @@ void testSingleNumber() {
100100 opt.maxGenerations =3000 ;
101101 algo.initialize (
102102 [](double * x,const tuple<>*){*x=randD ();},
103- [](const double * x,const tuple<>*){return 1.0 /(std:: abs (*x-3.0 )+1e-8 );},
103+ [](const double * x,const tuple<>*){return 1.0 /(abs (*x-3.0 )+1e-8 );},
104104 [](const double * x,const double *y,double *X,double *Y,const tuple<>*)
105105 {double mean=(*x+*y)/2 ;*X=(*x+mean)/2 ;*Y=(*y+mean)/2 ;},
106106 [](double * x,const tuple<>*)
107107 {
108- // if(std:: rand()%2)*x*=-1;
108+ // if(rand()%2)*x*=-1;
109109 *x+=randD (-1 ,1 )*0.5 ;},
110110 nullptr ,
111111 opt,
112- std:: tuple<>()
112+ tuple<>()
113113 );
114114
115115 cout << " Start" << endl;
@@ -131,41 +131,41 @@ void testWithEigenLib() {
131131
132132 GA<Eigen::Array4d,true ,Eigen::Array4d,Eigen::Array4d,Eigen::Array4d,double > algo;
133133 // val min max learning_rate
134- std:: tuple<Eigen::Array4d,Eigen::Array4d,Eigen::Array4d,double > Arg;
134+ tuple<Eigen::Array4d,Eigen::Array4d,Eigen::Array4d,double > Arg;
135135 static const uint8_t TargetOffset=0 ,MinOffset=1 ,MaxOffset=2 ,LROffset=3 ;
136- std:: get<TargetOffset>(Arg)=target;
137- std:: get<MinOffset>(Arg).setConstant (-1 );
138- std:: get<MaxOffset>(Arg).setConstant (2 );
139- std:: get<LROffset>(Arg)=0.01 ;
136+ get<TargetOffset>(Arg)=target;
137+ get<MinOffset>(Arg).setConstant (-1 );
138+ get<MaxOffset>(Arg).setConstant (2 );
139+ get<LROffset>(Arg)=0.01 ;
140140
141141 // typeof(Arg)
142142
143143
144144 algo.initialize (
145145 [](Eigen::Array4d* x,const typeof (Arg)*){x->setRandom ();},
146146 [](const Eigen::Array4d* x,const typeof (Arg)* arg){
147- return -(*x-std:: get<TargetOffset>(*arg)).square ().maxCoeff ();
147+ return -(*x-get<TargetOffset>(*arg)).square ().maxCoeff ();
148148 },
149149 [](const Eigen::Array4d*x,const Eigen::Array4d*y,
150150 Eigen::Array4d*X,Eigen::Array4d*Y,
151151 const typeof (Arg)*) {
152152 for (uint32_t i=0 ;i<4 ;i++) {
153153 X->operator ()(i)=
154- (std:: rand ()%2 )?
154+ (rand ()%2 )?
155155 x->operator ()(i):y->operator ()(i);
156156 Y->operator ()(i)=
157- (std:: rand ()%2 )?
157+ (rand ()%2 )?
158158 x->operator ()(i):y->operator ()(i);
159159 }},
160160 [](Eigen::Array4d*x,const typeof (Arg)* arg) {
161- uint32_t idx=std:: rand ()%4 ;
162- x->operator ()(idx)+=randD (-1 ,1 )*std:: get<LROffset>(*arg);
161+ uint32_t idx=rand ()%4 ;
162+ x->operator ()(idx)+=randD (-1 ,1 )*get<LROffset>(*arg);
163163
164- if (x->operator ()(idx)>std:: get<MaxOffset>(*arg)(idx)) {
165- x->operator ()(idx)=std:: get<MaxOffset>(*arg)(idx);
164+ if (x->operator ()(idx)>get<MaxOffset>(*arg)(idx)) {
165+ x->operator ()(idx)=get<MaxOffset>(*arg)(idx);
166166 }
167- if (x->operator ()(idx)<std:: get<MinOffset>(*arg)(idx)) {
168- x->operator ()(idx)=std:: get<MinOffset>(*arg)(idx);
167+ if (x->operator ()(idx)<get<MinOffset>(*arg)(idx)) {
168+ x->operator ()(idx)=get<MinOffset>(*arg)(idx);
169169 }},
170170 nullptr ,
171171 opt,
@@ -177,9 +177,120 @@ void testWithEigenLib() {
177177 cout<<" Result = " <<algo.result ().transpose ()<<endl;
178178}
179179
180+ void testTSP (const uint32_t PointNum) {
181+ static const uint8_t DIM=2 ;
182+ // static const double LengthBase=100;
183+ typedef array<double ,DIM> Point_t;
184+ vector<Point_t> points;
185+ points.clear ();
186+ points.reserve (PointNum);
187+ for (uint32_t i=0 ;i<PointNum;i++) {
188+ points.emplace_back ();
189+ for (auto & i : points.back ()) {
190+ i=randD ();
191+ }
192+ }
193+ cout<<" Generated random points :" <<endl;
194+ for (const auto & i : points) {
195+ cout<<' (' ;
196+ for (auto j : i) {
197+ cout<<j<<" , " ;
198+ }
199+ cout<<" )" <<endl;
200+ }
201+ typedef pair<double ,uint32_t > permUnit;
202+
203+ // typedef vector<permUnit> permulation;
204+ // var, less=better, data src
205+ GA<vector<double >,false ,const vector<Point_t>*> algo;
206+ static const uint8_t dataIdx=0 ;
207+ typedef tuple<const vector<Point_t>*> Args_t;
208+ Args_t args;// =make_tuple(PointNum,points.data());
209+ get<dataIdx>(args)=&points;
210+ // initialize function
211+
212+ auto initializeFun=[](vector<double > * x,const Args_t* args) {
213+ const uint32_t permL=get<dataIdx>(*args)->size ();
214+ x->resize (permL);
215+ for (uint32_t i=0 ;i<permL;i++) {
216+ x->at (i)=OptimT::randD ();
217+ }
218+ };
219+
220+ // calculate fitness
221+ auto calculateFun=[](const vector<double > *x,const Args_t* args) {
222+ const uint32_t permL=x->size ();
223+ vector<permUnit> perm (permL);
224+ for (uint32_t i=0 ;i<permL;i++) {
225+ perm[i].first =x->at (i);
226+ perm[i].second =i;
227+ }
228+ std::sort (perm.begin (),perm.end (),
229+ // compare function for std::sort
230+ [](const permUnit &a,const permUnit &b)
231+ { return a.first >b.first ;});
232+ double L=0 ;
233+ for (uint32_t i=1 ;i<permL;i++) {
234+ const Point_t &prev=get<dataIdx>(*args)->at (perm[i-1 ].second );
235+ const Point_t &cur=get<dataIdx>(*args)->at (perm[i].second );
236+ double curL=0 ;
237+ for (uint8_t d=0 ;d<DIM;d++) {
238+ curL+=(prev[d]-cur[d])*(prev[d]-cur[d]);
239+ }
240+ L+=curL;
241+ } return L;};
242+
243+ // calculate natural perm pathL
244+ {
245+ vector<double > natural (PointNum);
246+ for (uint32_t i=0 ;i<PointNum;i++) {
247+ natural[i]=double (i)/PointNum;
248+ }
249+ double naturalPathL=calculateFun (&natural,&args);
250+ cout<<" default pathL = " <<naturalPathL<<endl;
251+ }
252+
253+ auto crossoverFun=[](const vector<double >*p1,const vector<double >*p2,
254+ vector<double >*c1,vector<double >*c2,const Args_t*) {
255+ const uint32_t permL=p1->size ();
256+ c1->resize (permL);c2->resize (permL);
257+ for (uint32_t i=0 ;i<permL;i++) {
258+ c1->at (i)=(std::rand ()%2 )?p1->at (i):p2->at (i);
259+ c2->at (i)=(std::rand ()%2 )?p1->at (i):p2->at (i);
260+ }
261+ };
262+
263+ auto mutateFun=[](vector<double >*x,const Args_t*) {
264+ const uint32_t permL=x->size ();
265+ if (randD ()<0.5 ) {// modify one element's value
266+ double & v=x->at (std::rand ()%permL);
267+ v+=randD (-0.01 ,0.01 );
268+ v=min (v,1.0 );
269+ v=max (v,0.0 );
270+ }
271+ else {
272+ const uint32_t flipB=std::rand ()%(permL-1 );
273+ const uint32_t flipE=std::rand ()%(permL-flipB-1 )+flipB+1 ;
274+ // cout<<"flipB="<<flipB<<" , flipE"<<flipE<<endl;
275+ const uint32_t flipN=flipE-flipB+1 ;
276+ for (uint32_t flipped=0 ;flipped*2 <=flipN;flipped++) {
277+ swap (x->at (flipB+flipped),x->at (flipE-flipped));
278+ }
279+ }
280+ };
281+
282+
283+ GAOption opt;
284+ opt.maxGenerations =30 *PointNum;
285+ algo.initialize (initializeFun,calculateFun,crossoverFun,mutateFun,nullptr ,
286+ opt,args);
287+
288+ cout<<" run!" <<endl;
289+ algo.run ();
290+ cout<<" finished with " <<algo.generation ()<<" generations\n " ;
291+ cout<<" result fitness = " <<algo.eliteIt ()->fitness ()<<endl;
292+
293+
180294
181- void testTSP () {
182- typedef std::array<double ,2 > Point_t;
183- std::vector<Point_t> points;
184295}
185296
0 commit comments