如果您自己实现您的“个体”,那么任何对象都可以充当您的基因组。
特征
进一步简化的一种方法是将您的特征转换为枚举。这样,您可以通过从中选择特征来简单地重组父母的基因,并通过随机选择特征的枚举值之一来对基因进行突变。
一旦这起作用了,您就可以对值范围更加细致入微,但是使用枚举可以帮助我一开始就保持清晰。
健康
然后,要赋予这些特征含义,您需要一个描述性能的适应度函数。特征之间的关系取决于您,因此您可以用任何有意义的方式来描述它。这只是提供了一种比较两个基因组的一致方法。
模拟
然后要运行一个模拟,只需从几个父母开始,然后生成一堆孩子来互相完成。这当然可以自动化,但为了清楚起见,这里是一个明确的例子。
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();
}
}
编码
因为听起来您想将特征编码成一个序列,其中一些特征在序列中显式,而其他特征则从这些特征中派生出来。
你可以这样做,我将你的值的范围(如上面的枚举)编码为一个整数,其中的块代表你的显式特征。
例如,如果您有两个具有四个可能值的显式特征,您可以将集合编码为 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();
}
}
我希望这就是你要找的。祝你好运。