📄 ga1darraygenome.cpp
字号:
GA1DArrayGenome<T>::EvenOddCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1); const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2); int nc=0; int i; if(c1 && c2){ GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1); GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2); if(sis.length() == bro.length() && mom.length() == dad.length() && sis.length() == mom.length()){ for(i=sis.length()-1; i>=1; i-=2){ sis.gene(i, mom.gene(i)); bro.gene(i, dad.gene(i)); sis.gene(i-1, dad.gene(i-1)); bro.gene(i-1, mom.gene(i-1)); } if(i==0){ sis.gene(0, mom.gene(0)); bro.gene(0, dad.gene(0)); } } else{ int start; int min = (mom.length() < dad.length()) ? mom.length() : dad.length(); start = (sis.length() < min) ? sis.length()-1 : min-1; for(i=start; i>=0; i--) sis.gene(i, ((i%2 == 0) ? mom.gene(i) : dad.gene(i))); start = (bro.length() < min) ? bro.length()-1 : min-1; for(i=start; i>=0; i--) bro.gene(i, ((i%2 == 0) ? dad.gene(i) : mom.gene(i))); } nc = 2; } else if(c1 || c2){ GA1DArrayGenome<T> &sis = (c1 ? DYN_CAST(GA1DArrayGenome<T> &, *c1) : DYN_CAST(GA1DArrayGenome<T> &, *c2)); if(mom.length() == dad.length() && sis.length() == mom.length()){ for(i=sis.length()-1; i>=1; i-=2){ sis.gene(i, mom.gene(i)); sis.gene(i-1, dad.gene(i-1)); } if(i==0){ sis.gene(0, mom.gene(0)); } } else{ int min = (mom.length() < dad.length()) ? mom.length() : dad.length(); min = (sis.length() < min) ? sis.length()-1 : min-1; for(i=min; i>=0; i--) sis.gene(i, ((i%2 == 0) ? mom.gene(i) : dad.gene(i))); } nc = 1; } return nc;}// Partial match crossover for the 1D array genome. This uses the partial// matching algorithm described in Goldberg's book.// Parents and children must be the same size for this crossover to work. If// they are not, we post an error message.// We make sure that b will be greater than a.template <class T> intGA1DArrayGenome<T>::PartialMatchCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1); const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2); int nc=0; int a = GARandomInt(0, mom.length()); int b = GARandomInt(0, dad.length()); if(b < a) SWAP(a,b); int i,j,index; if(mom.length() != dad.length()){ GAErr(GA_LOC, mom.className(), "parial match cross", gaErrBadParentLength); return nc; } if(c1 && c2){ GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1); GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2); sis.GAArray<T>::copy(mom); for(i=a, index=a; i<b; i++, index++){ for(j=0; j<sis.length()-1 && sis.gene(j) != dad.gene(index); j++); sis.swap(i,j); } bro.GAArray<T>::copy(dad); for(i=a, index=a; i<b; i++, index++){ for(j=0; j<bro.length()-1 && bro.gene(j) != mom.gene(index); j++); bro.swap(i,j); } nc = 2; } else if(c1 || c2){ GA1DArrayGenome<T> &sis = (c1 ? DYN_CAST(GA1DArrayGenome<T> &, *c1) : DYN_CAST(GA1DArrayGenome<T> &, *c2)); const GA1DArrayGenome<T> *parent1, *parent2; if(GARandomBit()) { parent1 = &mom; parent2 = &dad; } else { parent1 = &dad; parent2 = &mom; } sis.GAArray<T>::copy(*parent1); for(i=a, index=a; i<b; i++, index++){ for(j=0; j<sis.length()-1 && sis.gene(j) != parent2->gene(index); j++); sis.swap(i,j); } nc = 1; } return nc;}// This function determines whether or not an indexed position is a hole that// we can substitute into. It does a linear search to find the holes (yuk).template <class T> intGA1DArrayIsHole(const GA1DArrayGenome<T> &c, const GA1DArrayGenome<T> &dad, int index, int a, int b){ for(int i=a; i<b; i++) if(c.gene(index) == dad.gene(i)) return 1; return 0;}// Order crossover for the 1D array genome. This uses the order crossover// described in Goldberg's book.// Parents and children must be the same length.// We make sure that b will be greater than a.// This implementation isn't terribly smart. For example, I do a linear// search rather than caching and doing binary search or smarter hash tables.// First we copy the mother into the sister. Then move the 'holes' into the// crossover section and maintain the ordering of the non-hole elements. // Finally, put the 'holes' in the proper order within the crossover section.// After we have done the sister, we do the brother.template <class T> intGA1DArrayGenome<T>::OrderCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1); const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2); int nc=0; int a = GARandomInt(0, mom.length()); int b = GARandomInt(0, mom.length()); if(b < a) SWAP(a,b); int i,j, index; if(mom.length() != dad.length()){ GAErr(GA_LOC, mom.className(), "order cross", gaErrBadParentLength); return nc; } if(c1 && c2){ GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1); GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2);// Copy the parent sis.GAArray<T>::copy(mom);// Move all the 'holes' into the crossover section for(i=0, index=b; i<sis.size(); i++, index++){ if(index >= sis.size()) index=0; if(GA1DArrayIsHole(sis,dad,index,a,b)) break; } for(; i<sis.size()-b+a; i++, index++){ if(index >= sis.size()) index=0; j=index; do{ j++; if(j >= sis.size()) j=0; } while(GA1DArrayIsHole(sis,dad,j,a,b)); sis.swap(index,j); }// Now put the 'holes' in the proper order within the crossover section. for(i=a; i<b; i++){ if(sis.gene(i) != dad.gene(i)){ for(j=i+1; j<b; j++) if(sis.gene(j) == dad.gene(i)) sis.swap(i,j); } }// Now do the other child bro.GAArray<T>::copy(dad);// Move all the 'holes' into the crossover section for(i=0, index=b; i<bro.size(); i++, index++){ if(index >= bro.size()) index=0; if(GA1DArrayIsHole(bro,mom,index,a,b)) break; } for(; i<bro.size()-b+a; i++, index++){ if(index >= bro.size()) index=0; j=index; do{ j++; if(j >= bro.size()) j=0; } while(GA1DArrayIsHole(bro,mom,j,a,b)); bro.swap(index,j); } // Now put the 'holes' in the proper order within the crossover section. for(i=a; i<b; i++){ if(bro.gene(i) != mom.gene(i)){ for(j=i+1; j<b; j++) if(bro.gene(j) == mom.gene(i)) bro.swap(i,j); } } nc = 2; } else if(c1 || c2){ GA1DArrayGenome<T> &sis = (c1 ? DYN_CAST(GA1DArrayGenome<T> &, *c1) : DYN_CAST(GA1DArrayGenome<T> &, *c2)); const GA1DArrayGenome<T> *parent1, *parent2; if(GARandomBit()) { parent1 = &mom; parent2 = &dad; } else { parent1 = &dad; parent2 = &mom; } sis.GAArray<T>::copy(*parent1); for(i=0, index=b; i<sis.size(); i++, index++){ if(index >= sis.size()) index=0; if(GA1DArrayIsHole(sis,*parent2,index,a,b)) break; } for(; i<sis.size()-b+a; i++, index++){ if(index >= sis.size()) index=0; j=index; do{ j++; if(j >= sis.size()) j=0; } while(GA1DArrayIsHole(sis,*parent2,j,a,b)); sis.swap(index,j); } for(i=a; i<b; i++){ if(sis.gene(i) != parent2->gene(i)){ for(j=i+1; j<b; j++) if(sis.gene(j) == parent2->gene(i)) sis.swap(i,j); } } nc = 1; } return nc;}// Cycle crossover for the 1D array genome. This is implemented as described // in goldberg's book. The first is picked from mom, then cycle using dad.// Finally, fill in the gaps with the elements from dad.// We allocate space for a temporary array in this routine. It never frees// the memory that it uses, so you might want to re-think this if you're really// memory-constrained (similar to what we do with the uniform crossover when// the children are resizeable).// Allocate space for an array of flags. We use this to keep track of whether// the child's contents came from the mother or the father. We don't free the// space here, but it is not a memory leak.// The first step is to cycle through mom & dad to get the cyclic part of // the crossover. Then fill in the rest of the sis with dad's contents that // we didn't use in the cycle. Finally, do the same thing for the other child.// Notice that this implementation makes serious use of the operator= for the// objects in the array. It also requires the operator != and == comparators.template <class T> intGA1DArrayGenome<T>::CycleCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GA1DArrayGenome<T> &mom=DYN_CAST(const GA1DArrayGenome<T> &, p1); const GA1DArrayGenome<T> &dad=DYN_CAST(const GA1DArrayGenome<T> &, p2); int nc=0; int i, current=0; if(mom.length() != dad.length()){ GAErr(GA_LOC, mom.className(), "cycle cross", gaErrBadParentLength); return nc; } if(c1 && c2){ GAMask mask; GA1DArrayGenome<T> &sis=DYN_CAST(GA1DArrayGenome<T> &, *c1); GA1DArrayGenome<T> &bro=DYN_CAST(GA1DArrayGenome<T> &, *c2); mask.size(sis.length()); mask.clear(); sis.gene(0, mom.gene(0)); mask[0] = 1; while(dad.gene(current) != mom.gene(0)){ for(i=0; i<sis.size(); i++){ if(mom.gene(i) == dad.gene(current)){ sis.gene(i, mom.gene(i)); mask[i] = 1; current = i; break; } } } for(i=0; i<sis.size(); i++) if(mask[i] == 0) sis.gene(i, dad.gene(i)); mask.clear(); bro.gene(0, dad.gene(0)); mask[0] = 1; while(mom.gene(current) != dad.gene(0)){ for(i=0; i<bro.size(); i++){ if(dad.gene(i) == mom.gene(current)){ bro.gene(i, dad.gene(i)); mask[i] = 1; current = i; break; } } } for(i=0; i<bro.size(); i++) if(mask[i] == 0) bro.gene(i, mom.gene(i)); nc = 2; } else if(c1 || c2){ GA1DArrayGenome<T> &sis = (c1 ? DYN_CAST(GA1DArrayGenome<T> &, *c1) : DYN_CAST(GA1DArrayGenome<T> &, *c2)); const GA1DArrayGenome<T> *parent1, *parent2; if(GARandomBit()) { parent1 = &mom; parent2 = &dad; } else { parent1 = &dad; parent2 = &mom; } GAMask mask; mask.size(sis.length()); mask.clear(); sis.gene(0, parent1->gene(0)); mask[0] = 1; while(parent2->gene(current) != parent1->gene(0)){ for(i=0; i<sis.size(); i++){ if(parent1->gene(i) == parent2->gene(current)){ sis.gene(i, parent1->gene(i)); mask[i] = 1; current = i; break; } } } for(i=0; i<sis.size(); i++) if(mask[i] == 0) sis.gene(i, parent2->gene(i)); nc = 1; } return nc;}#undef SWAP#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -