/* ----------------------------------------------------------------------------
BinaryTournamentSelector
For each generation: Put population in random order, pair up 1/2, 3/4, etc,
keep best of the two for select(), repeat until n/2 iterations, repeat
procedure. Each member of the population participates in two tournaments
for each generation. bcw 7/2/99
---------------------------------------------------------------------------- */
#if USE_BINARY_TOURNAMENT_SELECTOR == 1
GAGenome &
GABinaryTournamentSelector::select() const {
static int curIndex = -1;
int winIndex = -1;
float winScore = -1.0;
if((curIndex < 0) || (curIndex == 2*tournamentN)) {
curIndex = 0;
}
float score1 = pop->individual(tournaments[curIndex]).score();
float score2 = pop->individual(tournaments[curIndex+1]).score();
if(score1 > score2) {
winIndex = curIndex;
winScore = score1;
}
else {
winIndex = curIndex + 1;
winScore = score2;
}
// debugging info
// cout << curIndex / 2;
// cout << " winIndex: " << winIndex;
// cout << " tournaments[winIndex]: " << tournaments[winIndex];
// cout << " string: " << pop->individual(tournaments[winIndex]);
// cout << " score: " << winScore << endl << endl;
curIndex += 2;
return pop->individual(tournaments[winIndex]);
}
void
GABinaryTournamentSelector::update()
{
// allocate tournaments array on first run
if(firstRunFlag == 1) {
// cout << "Intializing tournaments storage..." << endl;
if(tournaments) {
delete [] tournaments;
}
// get population size and make sure it's even for crossover
n = pop->size();
if((n % 2) == 1) {
tournamentN = n + 1;
}
else {
tournamentN = n;
}
tournaments = new int[2*tournamentN];
firstRunFlag = 0;
}
// build tournaments array
// cout << "Generating tournaments..." << endl;
// first round of tournaments
int_gen(tournaments, 0, n-1);
reorder_ints(tournaments, 0, n-1);
// second round of tournaments
int_gen(tournaments+tournamentN, 0, n-1);
reorder_ints(tournaments+tournamentN, 0, n-1);
// if odd population size, add another two random ints for extra tournament/
// selection needed by the crossover operation
if(tournamentN == n+1) {
tournaments[tournamentN-1] = GARandomInt(0, n-1);
tournaments[2*tournamentN-1] = GARandomInt(0, n-1);
}
// for(int i=0; i < 2*tournamentN; i++) {
// cout << i << " = " << tournaments[i] << endl;
// }
}
#endif