Andrew, I can't speak to the specifics of the problem you're using, but
it seems to be reasonable. Though you might want to look into single
elimination tournament, which may perform better. BTW, there was an
interesting paper called "Fitnessless Coevolution" which took a related
but different tack at GECCO this year.
Sean
Andrew Wagner wrote:
> Hi all,
> I'm playing around with using ECJ to evolve game-playing agents. In
> the particular, at the moment, I'm prototyping my ideas by evolving
> Tic-Tac-Toe players. I want fitness to be evaluated by each program
> playing 5 matches with randomly selected opponents. Their fitness will
> be a sum of the number of wins they wind up with, plus half a point
> for each draw. Each match consists of playing the same engine twice,
> once with X and once with O. I'm not sure if I'm implementing this
> correctly or not, so I thought I'd see what you all think.
>
> Here are my evaluation settings:
> eval = ec.coevolve.CompetitiveEvaluator
> eval.style = rand-2-ways
> eval.group-size = 5
>
> Here is the evaluate function:
>
> public void evaluate(EvolutionState state, Individual[] ind,
> boolean[] updateFitness, boolean countVictoriesOnly, int [] someInts,
> int threadnum)
> {
> float [] fitnesses = new float [] {0,0}; // resulting
> fitnesses of the individuals
>
> reset(); // set up a new game
> int index = 0; // index of individual whose turn it is
> //state.output.message("Game 1:");
> while (moves.size() > 0){ // i.e., while legal moves exist
> // calling eval on an individual causes it to choose a move
> ((GPIndividual)ind[index]).trees[0].child.eval(state,
> threadnum, (GPData)input, stack, (GPIndividual)ind[0], this);
> makemove(); // make the chosen move, calculate next set of
> legal moves
> index = (index + 1) % 2; // next player's turn
> }
> if (game_over()){ // bad name, but this checks to see whether
> there are 3 marks in a row
> // someone won
> int winner = (index + 1) % 2;
> fitnesses[winner] += 1; // 1 point for a win
> } else {
> fitnesses[0] += 0.5; // half point for a tie
> fitnesses[1] += 0.5;
> }
>
> // set up a second game
> reset();
> index = 1; // the other individual goes first this time
> //state.output.message("Game 2:");
> while (moves.size() > 0){
> ((GPIndividual)ind[index]).trees[0].child.eval(state,
> threadnum, (GPData)input, stack, (GPIndividual)ind[0], this);
> makemove();
> index = (index + 1) % 2;
> }
> if (game_over()){
> // someone won
> int winner = (index + 1) % 2;
> fitnesses[winner] += 1;
> } else {
> fitnesses[0] += 0.5;
> fitnesses[1] += 0.5;
> }
>
> // games are over: time to actually update the fitnesses
> for (int i = 0; i < 2; i++)
> if (updateFitness[i]){
> KozaFitness fitness = ((KozaFitness)ind[0].fitness);
> fitness.setStandardizedFitness(state,
> fitness.standardizedFitness() + fitnesses[i]);
> }
> }
|