【问题标题】:How to apply test functions to genetic algorithm如何将测试函数应用于遗传算法
【发布时间】:2017-05-13 20:45:03
【问题描述】:

我为种群进化(遗传算法实现)编写了以下代码:

Individual.java

import java.util.Random;

public class Individual {

    public static int SIZE = 500;
    private int[] genes = new int[SIZE];
    private double fitnessValue = 0.0;


    // Getters and Setters
    public void setGene(int index,int gene){
        this.genes[index] = gene;
    }

    public int getGene(int index){
        return this.genes[index];
    }

    public void setFitnessValue(double fitness){
        this.fitnessValue = fitness;
    }

    public double getFitnessValue(){
        return this.fitnessValue;
    }

    //Function to generate a new individual with random set of genes
    public void generateIndividual(){
        Random rand = new Random();
        for(int i=0;i<SIZE;i++){
            this.setGene(i, rand.nextInt(2));
        }
    }

    //Mutation Function
    public void mutate(){
        Random rand = new Random();
        int index = rand.nextInt(SIZE);
        this.setGene(index, 1-this.getGene(index)); // Flipping value of gene 
    }

    //Function to set Fitness value of an individual
    public int evaluate(){

        int fitness = 0;
        for(int i=0; i<SIZE; ++i) {
            fitness += this.getGene(i);
        }
        this.setFitnessValue(fitness);
        return fitness;
    }

}

Population.java

import java.util.Random;

public class Population {

    final static int ELITISM = 5;
    final static int POP_SIZE = 200+ELITISM; //Population size + Elitism (1)
    final static int MAX_ITER = 10000;
    final static double MUTATION_RATE = 0.05;
    final static double CROSSOVER_RATE = 0.7;
    public static int generation = 2;

    private static Random rand = new Random(); 
    private double totalFitness;
    private  Individual[] pop;

    //Constructor
    public Population(){
        pop = new Individual[POP_SIZE];
        //Initialising population
        for(int i=0;i<POP_SIZE;i++){
            pop[i] = new Individual();
            pop[i].generateIndividual();

        }
        //Evaluating current population
        this.evaluate();
    }

    //Storing new generation in population
    public void setPopulation(Individual[] newPop) {
        System.arraycopy(newPop, 0, this.pop, 0, POP_SIZE);
    }


    //Method to find total fitness of population
    public double evaluate(){
        this.totalFitness = 0.0;
        for (int i = 0; i < POP_SIZE; i++) {
            this.totalFitness +=  pop[i].evaluate();
        }


       return this.totalFitness;
    }


    //Getters
    public Individual getIndividual(int index) {
        return pop[index];
    }


    //Function to find fittest individual for elitism
    public Individual getFittest() {
        Individual fittest = pop[0];
        for (int i = 0; i < POP_SIZE; i++) {
            if (fittest.getFitnessValue() <= getIndividual(i).getFitnessValue()) {
                fittest = getIndividual(i);
            }
        }
        return fittest;
    }

    //CROSSOVER Function : Takes 2 individuals and returns 2 new individuals
    public static Individual[] crossover(Individual indiv1,Individual indiv2) {
        Individual[] newIndiv = new Individual[2];
        newIndiv[0] = new Individual();
        newIndiv[1] = new Individual();
        int randPoint = rand.nextInt(Individual.SIZE);
        int i;
        for (i=0; i<randPoint; ++i) {
            newIndiv[0].setGene(i, indiv1.getGene(i));
            newIndiv[1].setGene(i, indiv2.getGene(i));
        }
        for (; i<Individual.SIZE; ++i) {
            newIndiv[0].setGene(i, indiv2.getGene(i));
            newIndiv[1].setGene(i, indiv1.getGene(i));
        }

        return newIndiv;
    }

    //Roulette Wheel Selection Function
    public Individual rouletteWheelSelection() {

        double randNum = rand.nextDouble() * this.totalFitness;
        int idx;

        for (idx=0; idx<POP_SIZE && randNum>0; idx++) {
            randNum -= pop[idx].getFitnessValue();
        }
        return pop[idx-1];
    }

    //Main method

    public static void main(String[] args) {
        Population pop = new Population();
        Individual[] newPop = new Individual[POP_SIZE];
        Individual[] indiv = new Individual[2];
        //Current Population Stats
        System.out.print("Generation #1");
        System.out.println("Total Fitness = "+pop.totalFitness);
        System.out.println("Best  Fitness = "+pop.getFittest().getFitnessValue());

        int count;
        for(int iter=0;iter<MAX_ITER;iter++){
            count =0;

                //Elitism
                newPop[count] = pop.getFittest();
                count++;

           //Creating new population
            while(count < POP_SIZE){
                //Selecting parents
                indiv[0] = pop.rouletteWheelSelection();
                indiv[1] = pop.rouletteWheelSelection();

                // Crossover
                if (rand.nextDouble() < CROSSOVER_RATE ) {
                    indiv = crossover(indiv[0], indiv[1]);
                }

                // Mutation
                if ( rand.nextDouble() < MUTATION_RATE ) {
                    indiv[0].mutate();
                }
                if ( rand.nextDouble() < MUTATION_RATE ) {
                    indiv[1].mutate();
                }

                // add to new population
                newPop[count] = indiv[0];
                newPop[count+1] = indiv[1];
                count += 2;
            }
            // Saving new population in pop
            pop.setPopulation(newPop);
            //Evaluating new population
            pop.evaluate();
            System.out.println("Generation #"+ generation++);
            System.out.print("Total Fitness = " + pop.totalFitness);
            System.out.println(" ; Best Fitness = " +pop.getFittest().getFitnessValue()); 

            }


        Individual bestIndiv = pop.getFittest();
    }

}

我被要求使用以下函数测试我的算法: https://en.wikipedia.org/wiki/Test_functions_for_optimization 单目标优化的测试函数

谁能解释它是如何完成的?对列表中任何一项功能的解释都会有所帮助。

【问题讨论】:

  • 这与您几个小时前发布的问题有何不同? stackoverflow.com/questions/41374297/…您可以编辑之前的问题并添加此代码,而不是创建新问题。
  • 那是 Easom 函数特有的,但现在我想如果我得到任何函数的解释,我可以自己做剩下的事情。所以现在问题不是特定于功能的。
  • 我不明白这段代码试图完成什么。遗传算法使个体发生变异以试图提高他们的适应度。现在你的适应度被定义为基因的总和,参见evaluate()(BTW 的命名很糟糕)。个体不会只是倾向于拥有越来越高的基因吗?您链接的维基百科页面上的函数都是具有两个输入 x 和 y 的函数。我建议给您的个人 2 个基因,我会将适合度定义为您正在测试的功能的结果。你能告诉我我的假设是否正确,以便我写下答案吗?
  • 我指的这本书把 y 取为 0 把 2 个变量函数变成了一个更简单的单变量函数。例如,它在 Easom fn 中取 y=0 并使其在 x=π 处达到全局最大值。我不明白你取 2 个基因的想法(你的意思是 2 组基因?)但是是的,适应度值肯定是要检查的测试函数的结果。
  • Cont.. 而我在评估中所做的只是通过为每个人分配一个适应度值来测试代码,以确保 prog 的所有部分都能正常工作,我只需要改变将适应度值分配给个体的方法。你能详细说明服用 2 个基因的含义吗?

标签: java algorithm genetic-programming genetics genetic


【解决方案1】:

基因应该代表什么

我假设你的遗传算法的实现是正确的,因为这超出了这个问题的范围。

现在你的适应度函数被定义为所有基因的总和:

double fitness = 0;
for(int i=0; i<SIZE; ++i) {
  fitness += this.getGene(i);
}
this.setFitnessValue(fitness);

这是一件很奇怪的事情:让我们想想一个单独的女巫会有很高的适应度。我希望你看到没有真正的最优,个体只会倾向于增加他们的每一个基因,因为这将存档更高的适应度。

第二个问题是基因应该代表什么:基因数组中的双精度值实际上是什么意思?我们为什么关心?一个可能的例子是让它们代表模拟中个体的行为。这当然是另外一个话题了,所以我们需要它们的意思很简单,这样就可以很容易地计算它们的适应度。

让我们让数组的大小为 1,假设为x = genes[0]。个体将只有一个基因:x 坐标。现在我们需要定义我们的适应度函数,我们将使用y = 0 选择 Easom。这就是我定义新适应度函数的方式:

double fitness = -cos(x)*cos(0)*exp(-(pow(x-PI,2)+pow(0-PI,2)));

当然在类的顶部有适当的导入:

import static java.lang.Math.*;

如果您的程序确实针对适应度进行了优化,它应该收敛到x = PI。我很快写了我自己的(诚然非常丑陋)implementation,它确实收敛正确。

还有一点:基因应该是double[] 而不是int[],因为当x 只能是int 时,增量优化函数实际上并不奏效。

为什么是基因阵列?

认为您的任务希望您使用double 数组作为基因,因此您最终得到的程序可以优化具有任意数量变量的任何函数。在编程中,编写可用于多种不同事物的代码总是一个好主意。

如有任何问题,请随时提出!

我试图尽可能清楚地解释所有内容,但如果您有不明白的地方,请随时提问!

【讨论】:

  • 感谢您的回答。我的疑问是,如果我们采用只有一个元素的基因数组,那么交叉就没有意义(意味着一些基因来自一个父母,而其余基因来自另一个)。新一代个体应该具有父母的品质(基因),除了那些变异的(非常低的机会0.001-0.05)。
  • 好吧,如果你检查了它是否适用于一个变量,你可以尝试更多,例如,你可以说y=genes[1]
  • 是的,这正是我想问的。我是否应该创建自己的函数(例如,总结一个人的所有基因并取 mod 5 并使其等于 x)并根据它找到个体的适应度,或者我应该将 x 作为随机数在其域中并使用它计算适应度?
  • 恐怕你对遗传算法有误解。它们是一种解决优化问题的方法,看起来像这样:“x_1x_2、...、x_n 的值是多少,使得f(x_1, x_2, ..., x_n) 最大?”当我们尝试使用遗传算法解决这个问题时,我们称x_i为基因,我们称f(...)为适应度。当我们想要测试我们的程序时,我们可以选择easom(x, 0) 作为我们要优化的函数。然后我们说x 是我们的单基因,easim(x) 是适应度。
  • 你能不能写一个Easom函数的伪代码,其中个体的基因是整数数组。我想我会更好地理解代码。我不明白为什么我们只考虑一个人的一个基因或两个基因来进行功能评估,而他有这么多基因存储在阵列中。我明白 f(...) 将是个体的适应度,随着进化的发生和世代的变化,我们必须最大化适应度。但我不明白的一点是 x 的值(假设书中给出的 y 0 )和
猜你喜欢
  • 2010-11-05
  • 2020-05-12
  • 2019-03-01
  • 1970-01-01
  • 2012-03-16
  • 2023-02-20
  • 2011-06-30
  • 2017-04-16
  • 2019-12-26
相关资源
最近更新 更多