📄 galistgenome.cpp
字号:
bro.tail(); // move to the end of the list } bro.insert(list); // stick the clone onto the end delete list; bro.head(); // set iterator to head of list nc += 1; } return nc;}// Partial match crossover for list genomes. We need two versions of this// routine: one for lists whose nodes are pointers to objects (each genome// points to the same objects as all of the other genomes) and one for// lists whose nodes contain independent objects (each node has its own copy// of the object).// This version of the partial match crossover uses objects that are multiply// instantiated - each list genome contains its own objects in its nodes.// The operator== method must be defined on the object for this implementation// to work! In this case, the 'object' is an int, so we're OK. If you are // putting your own objects in the nodes, be sure you have operator== defined// for your object. You must also have operator!= defined for your object. We// do not do any assignments, so operator= and/or copy is not required.// We assume that none of the nodes will return a NULL pointer. Also assume// that the cross site has been selected properly.// First we make a copy of the mother. Then we loop through the match // section and try to swap each element in the child's match section with its// partner (as defined by the current node in the father's match section).// Mirroring will work the same way - just swap mom & dad and you're all set.// The parents should be the same size as the child (and they should contain// the same nodes, but in any order). We do not check for this!!template <class T> intGAListGenome<T>::PartialMatchCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GAListGenome<T> &mom=DYN_CAST(const GAListGenome<T> &, p1); const GAListGenome<T> &dad=DYN_CAST(const GAListGenome<T> &, p2); if(mom.size() != dad.size()){ GAErr(GA_LOC, mom.className(), "cross", gaErrBadParentLength); return 0; } int a = GARandomInt(0, mom.size()); int b = GARandomInt(0, dad.size()); if(b<a) SWAP(a,b); T* index; int i,j,nc=0; if(c1){ GAListGenome<T> &sis=DYN_CAST(GAListGenome<T> &, *c1); sis.GAList<T>::copy(mom); GAListIter<T> diter(dad); index = diter.warp(a); for(i=a; i<b; i++, index=diter.next()){ if(*sis.head() == *index){ sis.swap(i,0); } else{ for(j=1; (j<sis.size()) && (*sis.next() != *index); j++); sis.swap(i,j); // no op if j>size } } sis.head(); // set iterator to head of list nc += 1; } if(c2){ GAListGenome<T> &bro=DYN_CAST(GAListGenome<T> &, *c2); bro.GAList<T>::copy(dad); GAListIter<T> miter(mom); index = miter.warp(a); for(i=a; i<b; i++, index=miter.next()){ if(*bro.head() == *index){ bro.swap(i,0); } else{ for(j=1; (j<bro.size()) && (*bro.next() != *index); j++); bro.swap(i,j); // no op if j>size } } bro.head(); // set iterator to head of list nc += 2; } return nc;}// Order crossover for lists. As described in Goldberg's book.// We assume that we'll never get a NULL pointer while iterating through the// list. Also we assume that the lists are the same size and non-NULL.template <class T> intGAListIsHole(const GAListGenome<T> &child, const GAListGenome<T> &parent, int index, int a, int b){ GAListIter<T> citer(child), piter(parent); citer.warp(index); piter.warp(a); for(int i=a; i<b; i++){ if(*citer.current() == *piter.current()) return 1; piter.next(); } return 0;}template <class T> intGAListGenome<T>::OrderCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GAListGenome<T> &mom=DYN_CAST(const GAListGenome<T> &, p1); const GAListGenome<T> &dad=DYN_CAST(const GAListGenome<T> &, p2); if(mom.size() != dad.size()){ GAErr(GA_LOC, mom.className(), "cross", gaErrBadParentLength); return 0; } int a = GARandomInt(0, mom.size()); int b = GARandomInt(0, dad.size()); if(b<a) SWAP(a,b); int i,j, index, nc=0; if(c1){ GAListGenome<T> &sis=DYN_CAST(GAListGenome<T> &, *c1); sis.GAList<T>::copy(mom); GAListIter<T> siter(sis); GAListIter<T> diter(dad);// Move all the 'holes' into the crossover section and maintain the ordering of// the non-hole elements. for(i=0, index=b; i<sis.size(); i++, index++){ if(index >= sis.size()) index=0; if(GAListIsHole(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(GAListIsHole(sis,dad,j,a,b)); sis.swap(index,j); }// Now put the 'holes' in the proper order within the crossover section. for(i=a, sis.warp(a), diter.warp(a); i<b; i++, sis.next(), diter.next()){ if(*sis.current() != *diter.current()){ siter.warp(i); for(j=i+1; j<b; j++) if(*siter.next() == *diter.current()){ sis.swap(i,j); sis.warp(siter); // move iterator back to previous location break; } } } sis.head(); // set iterator to head of list nc += 1; } if(c2){ GAListGenome<T> &bro=DYN_CAST(GAListGenome<T> &, *c2); bro.GAList<T>::copy(dad); GAListIter<T> biter(bro); GAListIter<T> miter(mom);// Move all the 'holes' into the crossover section and maintain the ordering of// the non-hole elements. for(i=0, index=b; i<bro.size(); i++, index++){ if(index >= bro.size()) index=0; if(GAListIsHole(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(GAListIsHole(bro,mom,j,a,b)); bro.swap(index,j); }// Now put the 'holes' in the proper order within the crossover section. for(i=a, bro.warp(a), miter.warp(a); i<b; i++, bro.next(), miter.next()){ if(*bro.current() != *miter.current()){ biter.warp(i); for(j=i+1; j<b; j++) if(*biter.next() == *miter.current()){ bro.swap(i,j); bro.warp(biter); // move iterator back to previous location break; } } } bro.head(); // set iterator to head of list nc += 1; } return nc;}template <class T> intGAListGenome<T>::CycleCrossover(const GAGenome& p1, const GAGenome& p2, GAGenome* c1, GAGenome* c2){ const GAListGenome<T> &mom=DYN_CAST(const GAListGenome<T> &, p1); const GAListGenome<T> &dad=DYN_CAST(const GAListGenome<T> &, p2); if(mom.size() != dad.size()){ GAErr(GA_LOC, mom.className(), "cross", gaErrBadParentLength); return 0; } GAMask mask; mask.size(mom.size()); mask.clear(); int i, nc=0; if(c1){ GAListGenome<T> &sis=DYN_CAST(GAListGenome<T> &, *c1); sis.GAList<T>::copy(mom); GAListIter<T> diter(dad);// Cycle through mom & dad to get the cyclic part of the crossover. mask[0] = 1; diter.head(); while(*diter.current() != *sis.head()){ for(i=0; i<sis.size(); i++, sis.next()){ if(*sis.current() == *diter.current()){ mask[i] = 1; diter.warp(i); break; } } }// Now fill in the rest of the sis with dad's contents that we didn't use// in the cycle. sis.head(); diter.head(); for(i=0; i<sis.size(); i++){ if(mask[i] == 0) *sis.current() = *diter.current(); sis.next(); diter.next(); } sis.head(); // set iterator to head of list nc += 1; } if(c2){ GAListGenome<T> &bro=DYN_CAST(GAListGenome<T> &, *c2); bro.GAList<T>::copy(dad); GAListIter<T> miter(mom);// Cycle through mom & dad to get the cyclic part of the crossover. mask[0] = 1; miter.head(); while(*miter.current() != *bro.head()){ for(i=0; i<bro.size(); i++, bro.next()){ if(*bro.current() == *miter.current()){ mask[i] = 1; miter.warp(i); break; } } }// Now fill in the rest of the bro with dad's contents that we didn't use// in the cycle. bro.head(); miter.head(); for(i=0; i<bro.size(); i++){ if(mask[i] == 0) *bro.current() = *miter.current(); bro.next(); miter.next(); } bro.head(); // set iterator to head of list nc += 1; } return nc;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -