あなたが自分自身を実装している場合は、オブジェクトはあなたのゲノムとして機能することができます。これをさらに簡素化する
特性
一つの方法は、列挙型にあなたの特性を有効にすることです。このようにして、親の遺伝子の特徴を選択することによって親の遺伝子を簡単に組み替えることができます。また、特性の列挙値の1つをランダムに選択して遺伝子の突然変異を作成することもできます。
これが機能すると、値の範囲でニュアンスを増やすことができますが、列挙型を使用すると、最初はわかりやすくなります。
フィットネス
その後は、パフォーマンスを記述するフィットネス機能を必要とするという意味これらの特性を付与します。特性間の関係はあなた次第ですので、それを意味する方法で記述することができます。これは、2つのゲノムを比較する一貫した方法を提供するだけです。
シミュレーション
その後、シミュレーションを実行するためにわずか数両親で始まり、お互いに完了するために子供たちの束を生成します。これはもちろん自動化することができますが、明確にするための明示的な例があります。
Javaの例
import java.util.PriorityQueue;
class Genome implements Comparable<Genome> {
public enum Mass {
LIGHT(1),
AVERAGE(2),
HEAVY(3);
final Integer value;
Mass(Integer value) {
this.value = value;
}
}
public enum Strength {
WEAK(1),
AVERAGE(2),
STRONG(3);
final Integer value;
Strength(Integer value) {
this.value = value;
}
}
public enum Length {
SHORT(1),
AVERAGE(2),
LONG(3);
final Integer value;
Length(Integer value) {
this.value = value;
}
}
private final Mass mass;
private final Strength strength;
private final Length length;
public Genome(Mass mass, Strength strength, Length length) {
this.mass = mass;
this.strength = strength;
this.length = length;
}
private Integer fitness() {
return strength.value * length.value - mass.value * mass.value;
}
@Override public int compareTo(Genome that) {
// notice the fitter is less in precedence
if(this.fitness() > that.fitness())
return -1;
else if(this.fitness() < that.fitness())
return 1;
else // this.fitness() == that.fitness()
return 0;
}
public static Genome recombine(Genome... parents) {
if(parents.length < 1)
return null;
// Select parents randomly and then characteristics from them
Mass mass = parents[(int)(Math.random() * parents.length)].mass;
Strength strength = parents[(int)(Math.random() * parents.length)].strength;
Length length = parents[(int)(Math.random() * parents.length)].length;;
return new Genome(mass, strength, length);
}
public static Genome mutate(Genome parent) {
// Select characteristics randomly
Mass mass = Mass.values()[(int)(Math.random() * Mass.values().length)];
Strength strength = Strength.values()[(int)(Math.random() * Strength.values().length)];
Length length = Length.values()[(int)(Math.random() * Length.values().length)];
return new Genome(mass, strength, length);
}
public static void main() {
PriorityQueue<Genome> population = new PriorityQueue<Genome>();
Genome parent1 = new Genome(Mass.LIGHT, Strength.STRONG, Length.SHORT);
Genome parent2 = new Genome(Mass.AVERAGE, Strength.AVERAGE, Length.AVERAGE);
Genome parent3 = new Genome(Mass.HEAVY, Strength.WEAK, Length.LONG);
population.add(parent1);
population.add(parent2);
population.add(parent3);
Genome child1 = Genome.recombine(parent1, parent2);
Genome child2 = Genome.recombine(parent1, parent2);
Genome child3 = Genome.recombine(parent1, parent3);
Genome child4 = Genome.recombine(parent1, parent3);
Genome child5 = Genome.recombine(parent2, parent3);
Genome child6 = Genome.recombine(parent2, parent3);
Genome child7 = Genome.recombine(parent1, parent2, parent3);
Genome child8 = Genome.recombine(parent1, parent2, parent3);
Genome child9 = Genome.recombine(parent1, parent2, parent3);
child1 = Genome.mutate(child1);
child2 = Genome.mutate(child2);
child4 = Genome.mutate(child4);
child8 = Genome.mutate(child8);
population.add(child1);
population.add(child2);
population.add(child3);
population.add(child4);
population.add(child5);
population.add(child6);
population.add(child7);
population.add(child8);
population.add(child9);
// and the winner is...
Genome fittest = population.peek();
}
}
エンコーディング
あなたがそれらに由来する配列などで明示的にいくつかの特徴を有する配列に特徴をエンコードしたいのように聞こえるので。
上記の列挙型のような値のrangleを明示的な特性を表す塊のある整数にエンコードすることができます。
たとえば、4つの可能な値を持つ2つの明示的な特性がある場合、それぞれを00XX + XX00という形式の整数としてエンコードすることができます。したがって、例えば0111は、01の質量と11の長さに対応します。これは、シーケンス自体の中のビットを変更することによって変更することができます。
Javaの例
import java.util.PriorityQueue;
class Genome implements Comparable<Genome> {
private final Integer sequence;
private static final Integer bitmaskChunk = 3; // ...0011
private static final Integer shiftMass = 0; // ...00XX
private static final Integer shiftLength = 2; // ...XX00
private static final Integer shiftModulus = 4; // ...0000
private Integer getMass() {
return (sequence >>> shiftMass) & bitmaskChunk;
}
private Integer getLength() {
return (sequence >>> shiftLength) & bitmaskChunk;
}
public Integer getStrength() {
return getMass() * getLength();
}
public Genome(Integer sequence) {
this.sequence = sequence % (1 << Genome.shiftModulus);
}
private Integer fitness() {
// Some performance measure
return getStrength() * getLength() - getMass() * getMass();
}
@Override public int compareTo(Genome that) {
// notice the fitter is less in precedence
if(this.fitness() > that.fitness())
return -1;
else if(this.fitness() < that.fitness())
return 1;
else // this.fitness() == that.fitness()
return 0;
}
public static Genome recombine(Genome... parents) {
if(parents.length < 1)
return null;
Integer sequence = 0;
// Select parents randomly and then characteristics from them
sequence += parents[(int)(Math.random() * parents.length)].getMass() << Genome.shiftMass;
sequence += parents[(int)(Math.random() * parents.length)].getLength() << Genome.shiftLength;
return new Genome(sequence);
}
public static Genome mutate(Genome parent) {
Integer sequence = parent.sequence;
// Randomly change sequence in some way
sequence *= (int)(Math.random() * (1 << Genome.shiftModulus));
return new Genome(sequence);
}
public static void main() {
PriorityQueue<Genome> population = new PriorityQueue<Genome>();
Genome parent1 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));
Genome parent2 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));
Genome parent3 = new Genome((int)(Math.random() * (1 << Genome.shiftModulus)));
population.add(parent1);
population.add(parent2);
population.add(parent3);
Genome child1 = Genome.recombine(parent1, parent2);
Genome child2 = Genome.recombine(parent1, parent2);
Genome child3 = Genome.recombine(parent1, parent3);
Genome child4 = Genome.recombine(parent1, parent3);
Genome child5 = Genome.recombine(parent2, parent3);
Genome child6 = Genome.recombine(parent2, parent3);
Genome child7 = Genome.recombine(parent1, parent2, parent3);
Genome child8 = Genome.recombine(parent1, parent2, parent3);
Genome child9 = Genome.recombine(parent1, parent2, parent3);
child1 = Genome.mutate(child1);
child2 = Genome.mutate(child2);
child4 = Genome.mutate(child4);
child8 = Genome.mutate(child8);
population.add(child1);
population.add(child2);
population.add(child3);
population.add(child4);
population.add(child5);
population.add(child6);
population.add(child7);
population.add(child8);
population.add(child9);
// and the winner is...
Genome fittest = population.peek();
}
}
私は、これはあなたが探しているものであると思います。がんばろう。
ワウ。私は、この答えを無限に高く評価したいと思います。特に、エンコーディングに関する部分は非常に便利です! 私は答えとしてマークするのを待っていますが、それはとても純粋ですが、私はできません。 また、私はその例がコンパイル可能であると信じていますか?これらは小文字の完全な形の段落と同じくらい便利ですが、最も基本的な部分だけにカットできます。 –
ありがとうございます。ええ、これらはEclipseのJDK 1.6と同じようにビルドされているので、それらを出発点として使用できるはずです。再び、幸運。 –