方程演化

时间:2014-03-03 05:54:47

标签: java math evolutionary-algorithm

我正在编写一些东西来模拟进化,但是使用经过测试的方程式来找到算法的digitum。基本上它的作用是创建GENERATION Organisms,其中DNABITS int s,并执行

((dna[0] & i) / i) + ((dna[1] & i) / i)...

然后将其与真实的数字进行比较,并将两个有机体的差异最小化。但是出于某种原因,一代​​人的平均差异从大约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的方程式来找到每个生物的数字?你会建议什么?

1 个答案:

答案 0 :(得分:0)

没有&#34;正确&#34;这样做的方式。我的建议是创建一个锦标赛选择功能(你目前没有我看到的)来匹配两(2)个足够好的父母来创造下一个生物。这就是你的进化如何运作:)