void Popu::mutate(int pos){ int pos1=0,pos2=3;//size=offspring.elements.size(); //QTime t; int rd=3; Chromosome mutant; for (int i=0;i<2;i++){ if (i==0) mutant=parentOne; else mutant=parentTwo; for (int j=0;j<chromoSize;j++){ ///@todo make it dependant on a variable value Mut_prob the probability should be small rd=qrand()%chromoSize; if (rd >chromoSize-(chromoSize/5)) { //qDebug()<<"creating a mutant"; pos1=qrand()%chromoSize; //qsrand(QTime::msec ()); pos2=qrand()%chromoSize; //qDebug()<<pos2<<pos1; swapVals(mutant.elements,pos1,pos2); } //qDebug()<<mutant.elements<<"route"<< mutant.routeLength; } mutant.calcRouteLength(); //qDebug()<<"creating a mutant at "<<pos+i<<"routes"<< mutant.routeLength; ///@NOTE: As we kept the 2 best parents as are (ellitisme) and i>0 at while loop end we keep the elite //newGen.replace(pos+i,mutant); newGen.replace(pos,mutant); //qDebug()<<newGen.size(); } }
void Popu::mutateImproveMe(int pos){ Chromosome toImprove; //we mutate beginig from an elite parent if (qrand()%3==0) { toImprove=content[0]; nbrElite1++; } // We mutate a random chromosome else if (qrand()%3==1){ toImprove=content.at(pos); nbimporte++; } else { toImprove=content[1]; nbrElite2++; } int orignalRouteLength=toImprove.routeLength; int pos1=1; int pos2=2; int oldRouteLength=orignalRouteLength; for (int j=0;j<chromoSize;j++){ pos1=qrand()%chromoSize; pos2=qrand()%chromoSize; while (pos2==pos1){ pos2=qrand()%chromoSize; } oldRouteLength=toImprove.routeLength; swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength(); if ( toImprove.routeLength>oldRouteLength){ swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength();/// could be simplier =oldRouteLength ? } } newGen.replace(pos,toImprove); }
void Popu::mutateImprove(int pos){ Chromosome toImprove; /// Time to improve the route (randomly for now) even the elite are concerned for (int i=0;i<2;i++){ if (i==0) toImprove=parentOne; else toImprove=parentTwo; ///qDebug()<<"Trying to improve parent n°"<<pos+i; ///FOR debug remove me! int orignalRouteLength=toImprove.routeLength; for (int j=0;j<chromoSize*2;j++){ int pos1=qrand()%chromoSize; int pos2=qrand()%chromoSize; int oldRouteLength=toImprove.routeLength; //toImprove.elements.swap(pos1,pos2); swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength(); // qDebug()<<toImprove.routeLength<<oldRouteLength; ///undo changes as this become worse than before if ( toImprove.routeLength>oldRouteLength){ //toImprove.elements.swap(pos1,pos2); swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength();/// could be simplier =oldRouteLength ? //qDebug()<<"no changes"; } //else{ ///keep changes //} } newGen.replace(i+pos,toImprove); //newGen.replace(pos,toImprove); //qDebug()<<"Improved*********"<<toImprove.routeLength<<orignalRouteLength; //qDebug()<<toImprove.elements; //qDebug()<<"improved mutant routes"<< toImprove.routeLength; } }
void Popu::mutateImproveOffspring(Chromosome &toImprove, int pos){ int orignalRouteLength=toImprove.routeLength; int pos1=1; int pos2=2; int oldRouteLength=orignalRouteLength; for (int j=0;j<chromoSize;j++){ pos1=qrand()%chromoSize; pos2=qrand()%chromoSize; while (pos2==pos1){ pos2=qrand()%chromoSize; } oldRouteLength=toImprove.routeLength; swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength(); if ( toImprove.routeLength>oldRouteLength){ swapVals(toImprove.elements,pos1,pos2); toImprove.calcRouteLength();// could be simplier =oldRouteLength ? } } newGen.replace(pos,toImprove); }
/// returns an offspring from 2 parents Chromosome Popu::cross(Chromosome parent1, Chromosome parent2){ int i=0,pos=0,posOther=0,sizeFixe=parent2.elements.size()-1,size=parent2.elements.size()-1; double dist1=0,dist2=0; QPointFWithParent currentVal=parent1.elements.at(0); QPointFWithParent otherVal=parent2.elements.at(1),nextVal=parent1.elements.at(1); /// the other chromosome when working with p1 it's p2 and vice versa Chromosome activeParent=parent1; Chromosome otherParent=parent2; int activeParentRef=1; /// this reference chromosem is used when need to insert a random elment, as we delete from it every /// elmenet we append to the offsprings, we're sure we don't append duplicate points Chromosome referenceParent; referenceParent.elements=parent2.elements;/// could be parent1 also Chromosome offspring; //qDebug()<<"creating an offspring of "<<size+1<<"elements"; for (int i=0;i< sizeFixe-2;i++){ posOther=otherParent.elements.indexOf(currentVal); pos=activeParent.elements.indexOf(currentVal); /** //check for case at list end => start at a random pos if so if (posOther==size ){ //TODO:try with the other point before giving up if (referenceParent.elements.size()!=0){ int j=0; while (offspring.elements.contains(referenceParent.elements.at(j))){ posOther=otherParent.elements.indexOf(referenceParent.elements.at(j)); qDebug()<<"looping back randomly";j++; } qDebug()<<"stopped at" <<j; } } if (pos==size) { if (referenceParent.elements.size()!=0){ int k=0; while (offspring.elements.contains(referenceParent.elements.at(k))){ posOther=otherParent.elements.indexOf(referenceParent.elements.at(k)); qDebug()<<"looping back randomly";k++;///i++; } qDebug()<<"stopped at" <<k; currentVal=referenceParent->elements.takeAt(0); } } qDebug()<<"We're in pos="<<pos<<" Other parent contains"<<currentVal<<" at pos"<<posOther<<"size="<<size; //recheck if the random city is at list end : this tile we have to go to list begin **/ if (posOther==size || posOther>size) { ///TODO:try with the other point before giving up posOther=0;///qDebug()<<"have to loop back"; } if (pos==size || pos>size){ pos=0;///qDebug()<<"have to loop back"; } /// get the next 'city' coordinates to compute how far is it otherVal=otherParent.elements.at(posOther+1); //qDebug()<<"deciding wich paretn to keep with"; //qDebug()<<activeParent->elements; nextVal=activeParent.elements.at(pos+1); /// the distance from the other parent cuurent point to next point in it dist2=dist(otherVal,currentVal); /// the distance from curretn parent to next point in active parent dist1=dist(nextVal,currentVal); /// if dist1<dist2 have to copy the path from the other parent and make it the active one; /// UNLES it's already prensent in the offspring offspring.elements.append(currentVal); referenceParent.elements.remove(referenceParent.elements.indexOf(currentVal)); parent1.elements.remove(parent1.elements.indexOf(currentVal)); parent2.elements.remove(parent2.elements.indexOf(currentVal)); size=parent2.elements.size()-1; ///qDebug()<<parent2.elements<<parent1.elements; if (dist2 < dist1) { ///qDebug()<<"switching to other parent"; if (offspring.elements.contains(otherVal)){ qDebug()<<"Point already presnet: forcing the other"; if (!offspring.elements.contains(nextVal)){ activeParent=parent2;otherParent=parent1;activeParentRef=2; currentVal=nextVal; continue; } /// use a random take if (referenceParent.elements.size()!=0){ qDebug()<<"Everything failed :setting a random point"; currentVal=referenceParent.elements.at(0); referenceParent.elements.remove(0); } else{ ///fixme qDebug()<<"Nothing to take from reference!!??"; break; } ///i++;///time to continue; } /// change the active parent if (activeParentRef==2){ activeParent=parent2;otherParent=parent1;activeParentRef=2; } else{ activeParent=parent1;otherParent=parent2;activeParentRef=1; } /// update current val currentVal=otherVal; } /// continue with the current parent else{ ///qDebug()<<"Continuing with this parent"; //offspring->elements.append(currentVal); ///offspring->elements.append(nextVal); ///keeping the parent //activeParent=parent1;otherParent=parent2; /// update current val currentVal=nextVal; } //qDebug()<<offspring.elements; } ///offspring->elements.append(currentVal); /// finally add the only point that remain in the ref chromosome //if (referenceParent.elements.size()!=0){ offspring.elements.append(referenceParent.elements.at(0)); referenceParent.elements.remove(0); offspring.elements.append(referenceParent.elements.at(0)); referenceParent.elements.remove(0); //} offspring.calcRouteLength(); return offspring; }