0
我正在編寫一些東西來模擬進化,但有一個方程被測試來找到算法的數字。基本上它是,它創造GENERATION
Organisms
,其中有DNABITS
int
秒,它執行方程的演變
((dna[0] & i)/i) + ((dna[1] & i)/i)...
,然後進行比較,要真正digitsum,和隊友的兩種生物具有最小差異。不過由於某種原因,一代人的平均差異開始在486,000/487,000附近,然後有時會下降,但總是回到這個範圍。什麼導致了這種行爲?
public class CodeEvolution {
public static final int DNABITS = 30;
public static final int MUTATION = 5;
public static final int PARENT = 1000;
public static final int GENERATION = 10;
public static final int TEST = 1000;
public static final int RETURNTHRESHOLD = 10;
public static Random rand = new Random();
static boolean firsttime = true;
static Organism[] generation;
static int[] difference;
public static void main(String[] args) throws NumberFormatException, IOException {
long time = System.currentTimeMillis();
Organism finalorg = iterate();
System.out.println("TIME: " +(System.currentTimeMillis() - time));
for(int i = 0; i < finalorg.DNA.length; ++i){
System.out.println(finalorg.DNA[i]);
}
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
while(true)
System.out.println(finalorg.digitSum(Integer.parseInt(r.readLine())));
}
public static Organism iterate(){
while(true){
if (firsttime){
firsttime = false;
generation = new Organism[GENERATION];
for (int i = 0; i < GENERATION; i++){
generation[i] = Organism.parent(); //spawn first organisms
}
}
difference = getDifferences(generation);
int closest1 = Integer.MAX_VALUE;
int closest2 = Integer.MAX_VALUE;
Organism orgclosest1 = Organism.parent();
Organism orgclosest2 = Organism.parent();
System.out.println(average(difference));
for (int i = 0; i < GENERATION; i++){
if(Math.abs(difference[i]) <= RETURNTHRESHOLD && Math.abs(difference[i]) >= -RETURNTHRESHOLD){
return generation[i];
}
if(Math.abs(difference[i]) < closest1){
orgclosest2 = orgclosest1;
orgclosest1 = generation[i];
closest2 = closest1;
closest1 = Math.abs(difference[i]);
}
else if (Math.abs(difference[i]) < closest2 && Math.abs(difference[i]) != closest1){
closest2 = Math.abs(difference[i]);
orgclosest2 = generation[i];
}
}
//orgclosest1 = parent 1, etc
for(int i = 0; i < GENERATION; ++i)
generation[i] = Organism.child(orgclosest1, orgclosest2);
}
}
private static double average(int[] data) {
int sum = 0;
for (int d : data) sum += d;
return 1.0d * sum/data.length;
}
public static int[] getDifferences(Organism[] parents){
int[] differencescore = new int[parents.length];
for(int i = 0; i < parents.length; ++i){
for(int x = 1; x < TEST; ++x){
int sum = realSumDigits(x);
int orgSum = parents[i].digitSum(x);
differencescore[i] += orgSum - sum;
}
}
return differencescore;
}
private static int realSumDigits(int digits) {
int sum = 0;
while (digits > 0)
{
sum += digits % 10;
digits /= 10;
}
return sum;
}
}
Organism.java
public class Organism {
int[] DNA; //((i & d)/d) +...
public Organism(int[] DNA){
this.DNA = DNA;
}
public int digitSum(int x){
for (int i = 0; i < DNA.length; ++i){
if (DNA[i] != 0)
x += (x & DNA[i])/DNA[i];
}
return x;
}
public static Organism child(Organism p1, Organism p2){
int[] DNA = new int[CodeEvolution.DNABITS];
for (int i = 0; i < DNA.length; i++){
DNA[i] = average(p1.DNA[i], p2.DNA[i]) + random(CodeEvolution.MUTATION);
}
return new Organism(DNA);
}
public static Organism parent(){
int[] DNA = new int[CodeEvolution.DNABITS];
for (int i = 0; i < DNA.length; i++){
DNA[i] = random(CodeEvolution.PARENT) + (CodeEvolution.PARENT/2);
}
return new Organism(DNA);
}
private static int random(int mutation) {
return CodeEvolution.rand.nextInt(mutation) - (mutation/2);
}
private static int average(int i, int j) {
return (i + j)/2;
}
}
編輯: 也許我應該改變DNA基於方程找到每個生物體的digitsum?你會建議什麼?