watchmaker icon indicating copy to clipboard operation
watchmaker copied to clipboard

IllegalArgumentException: Too many seed candidates for specified population size.

Open DcortezMeleth opened this issue 9 years ago • 5 comments

Hey,

I'm working on simple example using multiple islands. I have code as follows:

List<EvolutionEngine<FloatGenotype>> islands = new ArrayList<>();

Random rng = new MersenneTwisterRNG();

for(int i = 0; i < this.islands; i++) {
    CandidateFactory<FloatGenotype> factory = new FloatGenotypeFactory();

    List<EvolutionaryOperator<FloatGenotype>> operators = new LinkedList<>();
    operators.add(new AverageFloatCrossover());
    operators.add(new UniformFloatMutation());

    EvolutionPipeline<FloatGenotype> pipeline = new EvolutionPipeline<>(operators);

    FitnessEvaluator<FloatGenotype> evaluator = new FloatRastriginEvaluation();

    SelectionStrategy<Object> strategy = new TournamentSelection(selectionPressureControl
    .getNumberGenerator());

    EvolutionEngine<FloatGenotype> engine = new GenerationalEvolutionEngine<>(factory, pipeline,
    evaluator, strategy, rng);

    islands.add(engine);
    }


    IslandEvolution<FloatGenotype> islandEvolution = new IslandEvolution<>(islands, new RingMigration(),
    true, rng);
    islandEvolution.addEvolutionObserver(monitor);

    return islandEvolution.evolve(populationSize, // Population size per island.
    20, // Elitism for each island.
    50, // Epoch length (no. generations).
    15, // Migrations from each island at each epoch.
    terminationConditions;

Everything works fine when I'm setting populationSize on 120 or above. But if i try to use lower value i get following error on the end of first epoch, around 50th generation.

Exception in thread "main" java.lang.IllegalStateException: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Too many seed candidates for specified population size.
    at org.uncommons.watchmaker.framework.islands.IslandEvolution.evolve(IslandEvolution.java:248)
    at pl.agh.edu.evolution.experiment.Experiment.main(Experiment.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Too many seed candidates for specified population size.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.uncommons.watchmaker.framework.islands.IslandEvolution.evolve(IslandEvolution.java:220)
    ... 6 more
Caused by: java.lang.IllegalArgumentException: Too many seed candidates for specified population size.
    at org.uncommons.watchmaker.framework.factories.AbstractCandidateFactory.generateInitialPopulation(AbstractCandidateFactory.java:66)
    at org.uncommons.watchmaker.framework.AbstractEvolutionEngine.evolvePopulation(AbstractEvolutionEngine.java:135)
    at org.uncommons.watchmaker.framework.islands.Epoch.call(Epoch.java:51)
    at org.uncommons.watchmaker.framework.islands.Epoch.call(Epoch.java:27)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

I'm not setting seed candidates count or seeds candidates themselves so I guess error is not on my side. To be sure if it not dependent on elitism and migrations number I have lowered them to 5 and 3 respectively (as in user manual) but it has changed nothing. Still needed at least 120 objects in population to work.

DcortezMeleth avatar Nov 26 '15 22:11 DcortezMeleth

Hi, Can you share FloatGenotypeFactory code?

guliashvili avatar Nov 30 '15 04:11 guliashvili

Sure. It's just class wrapping list of Doubles. AbstractGenotype contains nothing at all.

    public class FloatGenotype extends AbstractGenotype {

        private List<Double> genes;

        public FloatGenotype(final List<Double> genes) {
            super();
            this.genes = genes;
        }

        public FloatGenotype(final FloatGenotype genotype) {
            super();
            this.genes = genotype.getGenes();
        }

        public List<Double> getGenes() {
            return genes;
        }

        public void setGenes(final List<Double> genes) {
            this.genes = genes;
        }

        @Override
        public String toString() {
            String result = "[";
            for(Double f : getGenes()) {
                result += f + " ";
            }
            return result + "] ";
        }
    }

DcortezMeleth avatar Nov 30 '15 07:11 DcortezMeleth

Hi, It's FloatGenotype I was interested in FloatGenotypeFactory

guliashvili avatar Nov 30 '15 07:11 guliashvili

My mistake.

public class FloatGenotypeFactory extends AbstractGenotypeFactory<FloatGenotype> {

    private static final Double UPPERBOUND = 1.0d;

    private static final Double LOWERBOUND = 0.0d;

    private static final Integer DIM = 3;

    private Integer dim;

    public FloatGenotypeFactory() {
        super(LOWERBOUND, UPPERBOUND);
        this.dim = DIM;
    }

    public FloatGenotypeFactory(final Double lowerbound, final Double upperbound, final Integer dim) {
        super(lowerbound, upperbound);
        this.dim = dim;
    }

    @Override
    public FloatGenotype generateRandomCandidate(final Random rng) {
        List<Double> genes = new ArrayList<>();
        for(int i=0; i<dim; i++) {
            genes.add(uniform(rng));
        }
        return new FloatGenotype(genes);
    }
}

public abstract class AbstractGenotypeFactory<T extends AbstractGenotype> extends AbstractCandidateFactory<T> {

    private Double lowerbound;

    private Double upperbound;

    public AbstractGenotypeFactory(final Double lowerbound, final Double upperbound) {
        this.lowerbound = lowerbound;
        this.upperbound = upperbound;
    }

    protected Double uniform(final Random rng) {
        return rng.nextDouble() * (this.upperbound - this.lowerbound) + this.lowerbound ;
    }
}

DcortezMeleth avatar Nov 30 '15 07:11 DcortezMeleth

Hi, I had similar problem but not same. In my case sometimes population size was less then elite count (even in configuration was not). I resolved it in my forked version, seems like it was top of iceberg, and framework for some reasons can keep population on fixed size. If you can provide me with your whole source code, I'll try to resolve the problem in my fork(as this repo is not changed for years)

guliashvili avatar Dec 02 '15 04:12 guliashvili