당신이 당신 자신의 '개인'을 구현한다면, 어떤 물체도 당신의 게놈 역할을 할 수 있습니다. 더이 문제를 단순화하기
한 가지 방법은 열거 형으로 특성을 설정하는 것입니다. 이 방법을 사용하면 특성에 대한 열거 형 값 중 하나를 무작위로 선택하여 부모형 유전자의 특성을 선택하고 유전자의 돌연변이를 선택하여 부모 유전자를 간단하게 재조합시킬 수 있습니다.
일단 이것이 작동하면 가치 범위와 더 미묘한 차이가 날 수 있지만 열거 형을 사용하면 처음에는 일을 명확하게 유지할 수 있습니다.
자바 예
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();
}
}
인코딩
당신이 그에서 파생 된 순서와 다른 사람에 명시 적으로 어떤 특성을 갖는 순서로 특성을 인코딩하려는 것처럼 소리입니다.
위에서 설명한 enum과 같은 값의 rangle을 명시 적 특성을 나타내는 청크가있는 정수로 인코딩 할 수 있습니다.
예를 들어 네 개의 가능한 값이있는 두 개의 명시적인 특성이있는 경우 각각을 00XX + XX00 형식의 정수로 인코딩 할 수 있습니다. 예를 들어 0111은 01의 질량과 11의 길이에 해당 할 수 있습니다. 이것은 시퀀스 자체 내의 비트를 변경하여 변경할 수 있도록합니다.
자바 예
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();
}
}
나는 이것이 당신이 찾고있는 무엇인가를 바란다. 행운을 빕니다.
와우. 나는이 답변을 무한정 더 높게 투표 할 수 있었으면 좋겠다. 특히 엔코딩에 관한 부분이 매우 유용하다! 대답으로 표시하는 것을 기다리고 싶지만 정말 멋지다. 나는 할 수 없다. 또한 예제를 컴파일 할 수 있다고 생각합니까? 그것들은 소화 할 수있는 텍스트의 완벽한 모양의 단락처럼 유용하지만, 가장 기본적인 부분으로 잘라낼 수 있습니다. –
감사에 감사드립니다. 예, JDK 1.6을 사용하여 이클립스에서 빌드되므로 시작 지점으로 사용할 수 있어야합니다. 다시 한번, 행운을 빈다. –