2016-07-05 16 views
1

Ich habe angefangen zu experimentieren mit der Jenetics-Bibliothek, aber ich habe einige Probleme mit dem Versuch, eine sehr einfache "benutzerdefinierte" Reihe von Gen/Chromosomen zu machen. Was ich versuchte, war ein eigenes Chromosom mit einer anderen (zufälligen) Anzahl von benutzerdefinierten Genen zu erstellen. Die Gene enthalten einfach einen ganzzahligen Wert, nur der Einfachheit halber. Aus der gleichen Einfachheit können die Inhalte eines Gens nur Zahlen von 0 bis 9 sein und ein Gen wird nur dann als gültig betrachtet, wenn es NICHT die Zahl 9 enthält (wiederum, im Gegenteil, einfach, aber ich wollte sie nur benutzerdefiniert machen)Jenetics benutzerdefinierte Gen/Chromosom

Hier

ist mein Code:

CustomGene:

public class CustomGene implements Gene<Integer, CustomGene> { 

    private Integer value; 

    private CustomGene(Integer value) { 
     this.value = value; 
    } 

    public static CustomGene of(Integer value) { 
     return new CustomGene(value); 
    } 

    public static ISeq<CustomGene> seq(Integer min, Integer max, int length) { 
     Random r = RandomRegistry.getRandom(); 
     return MSeq.<CustomGene>ofLength(length).fill(() -> 
       new CustomGene(random.nextInt(r, min, max)) 
     ).toISeq(); 
    } 

    @Override 
    public Integer getAllele() { 
     return value; 
    } 

    @Override 
    public CustomGene newInstance() { 
     final Random random = RandomRegistry.getRandom(); 
     return new CustomGene(Math.abs(random.nextInt(9))); 
    } 

    @Override 
    public CustomGene newInstance(Integer integer) { 
     return new CustomGene(integer); 
    } 

    @Override 
    public boolean isValid() { 
     return value != 9; 
    } 
} 

CustomChromosome:

import org.jenetics.Chromosome; 
import org.jenetics.util.ISeq; 
import org.jenetics.util.RandomRegistry; 

import java.util.Iterator; 
import java.util.Random; 

public class CustomChromosome implements Chromosome<CustomGene> { 

    private ISeq<CustomGene> iSeq; 
    private final int length; 

    public CustomChromosome(ISeq<CustomGene> genes) { 
     this.iSeq = genes; 
     this.length = iSeq.length(); 
    } 

    public static CustomChromosome of(ISeq<CustomGene> genes) { 
     return new CustomChromosome(genes); 
    } 

    @Override 
    public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) { 
     this.iSeq = iSeq; 
     return this; 
    } 

    @Override 
    public CustomGene getGene(int i) { 
     return iSeq.get(i); 
    } 

    @Override 
    public int length() { 
     return iSeq.length(); 
    } 

    @Override 
    public ISeq<CustomGene> toSeq() { 
     return iSeq; 
    } 

    @Override 
    public Chromosome<CustomGene> newInstance() { 
     final Random random = RandomRegistry.getRandom(); 
     ISeq<CustomGene> genes = ISeq.empty(); 
     for (int i = 0; i < length; i++) { 
      genes = genes.append(CustomGene.of(Math.abs(random.nextInt(9)))); 
     } 
     return new CustomChromosome(genes); 
    } 

    @Override 
    public Iterator<CustomGene> iterator() { 
     return iSeq.iterator(); 
    } 

    @Override 
    public boolean isValid() { 
     return iSeq.stream().allMatch(CustomGene::isValid); 
    } 
} 

Main:

import org.jenetics.Genotype; 
import org.jenetics.Optimize; 
import org.jenetics.engine.Engine; 
import org.jenetics.engine.EvolutionResult; 
import org.jenetics.util.Factory; 
import org.jenetics.util.RandomRegistry; 

import java.util.Random; 

public class Main { 

    private static int maxSum = - 100; 

    private static Integer eval(Genotype<CustomGene> gt) { 
     final int sum = gt.getChromosome().stream().mapToInt(CustomGene::getAllele).sum(); 
     if(sum > maxSum) 
      maxSum = sum; 
     return sum; 

    } 

    public static void main(String[] args) { 
     final Random random = RandomRegistry.getRandom(); 

     Factory<Genotype<CustomGene>> g = 
       Genotype.of(CustomChromosome.of(CustomGene.seq(0, 9, Math.abs(random.nextInt(9)) + 1))); 

     Engine<CustomGene, Integer> engine = Engine 
       .builder(Main::eval, g) 
       .optimize(Optimize.MAXIMUM) 
       .populationSize(100) 
       .build(); 

     Genotype<CustomGene> result = engine.stream().limit(10000) 
       .collect(EvolutionResult.toBestGenotype()); 

     System.out.println(eval(result)); 
     result.getChromosome().stream().forEach(i -> { 
      System.out.print(i.getAllele() + " "); 
     }); 

     System.out.println(); 

     System.out.println(maxSum); 
    } 
} 

Ich verstehe nicht, warum ich diese Ausgabe erhalten:

13 (evaluated result) 
1 8 0 4 (all the alleles form the genes of the chosen chromosome) 
32 (the actual maximum fitness found) 

Wir deutlich einen Unterschied zwischen dem Genotyp, der die größte Fitness-Funktion und der gewählten Genotyp hatte sehen können. Warum? Ich weiß, dass ich etwas falsch mache und es ist wahrscheinlich ein dummer Fehler, aber ich kann wirklich nicht verstehen, was ich falsch mache. Könnten Sie mir bitte helfen?

Vielen Dank!

Antwort

0

Wie here vom Schöpfer der Bibliothek geschrieben, war die Antwort:

Sie den Vertrag des Chromosome.newInstance (iseq) Verfahren verletzt. Diese Methode muss eine neue Chromosomeninstanz zurückgeben. Nach dem Fixieren

@Override 
public Chromosome<CustomGene> newInstance(ISeq<CustomGene> iSeq) { 
    return new CustomChromosome(iSeq); 
}