Menu

(no subject)

emixam
2017-02-16
2017-02-16
  • emixam

    emixam - 2017-02-16

    First of all, congratulations for this library which seems really good!

    I'd like to use this library to solve a (very simple) 2-players games. To start with something simple i'd like to do something like that:

    • Choose randomly 2 individuals
    • "Fight" them together
    • Kill the loser

    However, I haven't seen any possibility to take 2 individuals for the fitness method. Maybe my matter could be solved by using the TournamentSelector, but I didn't find out how...

    Do you know how I could solve it? Am I doing something wrong?

    Thank's for your help

     
  • Franz Wilhelmstötter

    The library assumes that the fitness function calculates a global fitness. In general it is not possible to write a fitness function which takes two individuals. But you can try some hack:

    public class Game {
    
        static final class Player implements Comparable<Player> {
            final double value;
    
            private Player(final double value) {
                this.value = value;
            }
    
            @Override
            public int compareTo(final Player other) {
                return Double.compare(value, other.value);
            }
    
            static Player of(final double value) {
                return new Player(value);
            }
        }
    
        public static void main(final String[] args) {
    
            final Codec<Player, DoubleGene> codec = Codec.of(
                Genotype.of(DoubleChromosome.of(0, 1)),
                gt -> Player.of(gt.getGene().doubleValue())
            );
    
            final AtomicReference<Population<DoubleGene, Double>>
                population = new AtomicReference<>();
    
            // Fitness function chooses the second individual randomly from the
            // current population. The population is set by the stream as side-
            // effect.
            final Function<Player, Double> fitness = player -> {
                final Population<DoubleGene, Double> pop = population.get();
    
                final Player other;
                if (pop != null) {
                    final int index = RandomRegistry.getRandom().nextInt(pop.size());
                    other = codec.decode(pop.get(index).getGenotype());
                } else {
                    other = Player.of(0.5); // Neutral player.
                }
    
                return (double)player.compareTo(other);
            };
    
            final Engine<DoubleGene, Double> engine = Engine
                .builder(fitness, codec)
                .build();
    
            final Player best = codec.decode(
                engine.stream()
                    .limit(limit.bySteadyFitness(50))
                    .peek(er -> population.set(er.getPopulation()))
                    .collect(EvolutionResult.toBestGenotype())
            );
    
            System.out.println(best.value);
        }
    
    }
    

    The losing individual is not killed, it only gets a bad fitness value. I don't know if this works at all, but it would be nice if you can tell me about your results.

     

Log in to post a comment.