当前位置: 首页 > 面试题库 >

用Java编写的GA

邵兴庆
2023-03-14
问题内容

我正在尝试根据从《
AI游戏程序员的技术》一书中选取的技术编写一种遗传html" target="_blank">算法,该技术对种群的基因使用二进制编码和适应性比例选择(也称为轮盘选择)。在程序内以二维数组随机生成。

最近,我遇到了一段伪代码并尝试实现它,但是遇到了一些我需要做的事情方面的问题。我检查了许多书籍和一些开源代码,但仍在努力取得进展。我了解我必须获得总体适应度的总和,在总和与零之间选择一个随机数,然后如果该数字大于父母数,则将其覆盖,但是我正在努力实现这些想法。

由于我的Java生锈,对实现这些想法的任何帮助将不胜感激。


问题答案:

以下是GA的完整概述。我确保要非常详细,以便可以轻松地将其编码为C / Java / Python /。

/* 1. Init population */
POP_SIZE = number of individuals in the population
pop = newPop = []
for i=1 to POP_SIZE {
    pop.add( getRandomIndividual() )
}

/* 2. evaluate current population */
totalFitness = 0
for i=1 to POP_SIZE {
    fitness = pop[i].evaluate()
    totalFitness += fitness
}

while not end_condition (best fitness, #iterations, no improvement...)
{
    // build new population
    // optional: Elitism: copy best K from current pop to newPop
    while newPop.size()<POP_SIZE
    {
        /* 3. roulette wheel selection */
        // select 1st individual
        rnd = getRandomDouble([0,1]) * totalFitness
        for(idx=0; idx<POP_SIZE && rnd>0; idx++) {
            rnd -= pop[idx].fitness
        }
        indiv1 = pop[idx-1]
        // select 2nd individual
        rnd = getRandomDouble([0,1]) * totalFitness
        for(idx=0; idx<POP_SIZE && rnd>0; idx++) {
            rnd -= pop[idx].fitness
        }
        indiv2 = pop[idx-1]

        /* 4. crossover */
        indiv1, indiv2 = crossover(indiv1, indiv2)

        /* 5. mutation */
        indiv1.mutate()
        indiv2.mutate()

        // add to new population
        newPop.add(indiv1)
        newPop.add(indiv2)
    }
    pop = newPop
    newPop = []

    /* re-evaluate current population */
    totalFitness = 0
    for i=1 to POP_SIZE {
        fitness = pop[i].evaluate()
        totalFitness += fitness
    }
}

// return best genome
bestIndividual = pop.bestIndiv()     // max/min fitness indiv

请注意,当前您缺少适应功能(取决于域)。交叉将是一个简单的单点交叉(因为您使用的是二进制表示形式)。变异可以是随机的简单翻转。

编辑 :考虑到您当前的代码结构和符号,我已经在Java中实现了上述伪代码(请记住,我比Java更喜欢ac / c
++的人)。请注意,这绝不是最有效或最完整的实现,我承认我写得很快。

个人.java

import java.util.Random;

public class Individual
{
    public static final int SIZE = 500;
    private int[] genes = new int[SIZE];
    private int fitnessValue;

    public Individual() {}

    public int getFitnessValue() {
        return fitnessValue;
    }

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

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

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

    public void randGenes() {
        Random rand = new Random();
        for(int i=0; i<SIZE; ++i) {
            this.setGene(i, rand.nextInt(2));
        }
    }

    public void mutate() {
        Random rand = new Random();
        int index = rand.nextInt(SIZE);
        this.setGene(index, 1-this.getGene(index));    // flip
    }

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

        return fitness;
    }
}

人口.java

import java.util.Random;

public class Population
{
    final static int ELITISM_K = 5;
    final static int POP_SIZE = 200 + ELITISM_K;  // population size
    final static int MAX_ITER = 2000;             // max number of iterations
    final static double MUTATION_RATE = 0.05;     // probability of mutation
    final static double CROSSOVER_RATE = 0.7;     // probability of crossover

    private static Random m_rand = new Random();  // random-number generator
    private Individual[] m_population;
    private double totalFitness;

    public Population() {
        m_population = new Individual[POP_SIZE];

        // init population
        for (int i = 0; i < POP_SIZE; i++) {
            m_population[i] = new Individual();
            m_population[i].randGenes();
        }

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

    public void setPopulation(Individual[] newPop) {
        // this.m_population = newPop;
        System.arraycopy(newPop, 0, this.m_population, 0, POP_SIZE);
    }

    public Individual[] getPopulation() {
        return this.m_population;
    }

    public double evaluate() {
        this.totalFitness = 0.0;
        for (int i = 0; i < POP_SIZE; i++) {
            this.totalFitness += m_population[i].evaluate();
        }
        return this.totalFitness;
    }

    public Individual rouletteWheelSelection() {
        double randNum = m_rand.nextDouble() * this.totalFitness;
        int idx;
        for (idx=0; idx<POP_SIZE && randNum>0; ++idx) {
            randNum -= m_population[idx].getFitnessValue();
        }
        return m_population[idx-1];
    }

    public Individual findBestIndividual() {
        int idxMax = 0, idxMin = 0;
        double currentMax = 0.0;
        double currentMin = 1.0;
        double currentVal;

        for (int idx=0; idx<POP_SIZE; ++idx) {
            currentVal = m_population[idx].getFitnessValue();
            if (currentMax < currentMin) {
                currentMax = currentMin = currentVal;
                idxMax = idxMin = idx;
            }
            if (currentVal > currentMax) {
                currentMax = currentVal;
                idxMax = idx;
            }
            if (currentVal < currentMin) {
                currentMin = currentVal;
                idxMin = idx;
            }
        }

        //return m_population[idxMin];      // minimization
        return m_population[idxMax];        // maximization
    }

    public static Individual[] crossover(Individual indiv1,Individual indiv2) {
        Individual[] newIndiv = new Individual[2];
        newIndiv[0] = new Individual();
        newIndiv[1] = new Individual();

        int randPoint = m_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;
    }


    public static void main(String[] args) {
        Population pop = new Population();
        Individual[] newPop = new Individual[POP_SIZE];
        Individual[] indiv = new Individual[2];

        // current population
        System.out.print("Total Fitness = " + pop.totalFitness);
        System.out.println(" ; Best Fitness = " + 
            pop.findBestIndividual().getFitnessValue());

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

            // Elitism
            for (int i=0; i<ELITISM_K; ++i) {
                newPop[count] = pop.findBestIndividual();
                count++;
            }

            // build new Population
            while (count < POP_SIZE) {
                // Selection
                indiv[0] = pop.rouletteWheelSelection();
                indiv[1] = pop.rouletteWheelSelection();

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

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

                // add to new population
                newPop[count] = indiv[0];
                newPop[count+1] = indiv[1];
                count += 2;
            }
            pop.setPopulation(newPop);

            // reevaluate current population
            pop.evaluate();
            System.out.print("Total Fitness = " + pop.totalFitness);
            System.out.println(" ; Best Fitness = " +
                pop.findBestIndividual().getFitnessValue()); 
        }

        // best indiv
        Individual bestIndiv = pop.findBestIndividual();
    }
}


 类似资料:
  • 问题内容: 有人可以指出我正确的方向,以便在Java中写入Excel文件吗?我不了解我在网上找到的链接。您能给我发送链接还是我可以遵循的任何方式? 谢谢J 问题答案: 并不是平庸,但是Apache POI可以做到。您可以在此处找到一些代码示例: http //poi.apache.org/spreadsheet/examples.html

  • 问题内容: Sun 用什么语言写? 问题答案: Sun实际上有多个JVM。所述热点JVM在C ++主要被写,因为热点在很大程度上基于所述Animorphic Smalltalk的VM被用C ++编写 。 比HotSpot更有趣的是IMHO Maxine Research VM ,它几乎完全用Java编写。

  • 问题内容: 一切在命令行上都可以正常运行,但是当我将所需的内容转换为Java时,接收过程在stdin上什么都收不到。 这是我所拥有的: 脚本“ count-the-bytes”很简单: 输出表明该函数挂在’wc -c’行-永远不会到达’counted stdin bytes’行。 这是怎么回事?使用Jsch会有所帮助吗? 问题答案: 您可能希望在wc -c返回之前尝试关闭输出流。

  • 问题内容: 我简要阅读了有关Maxine的信息,这是一个用Java编写的开源JVM实现。这对我来说听起来很圆。如果java要求运行虚拟机,那么如何用Java编写虚拟机本身(VM代码是否需要运行VM的虚拟机,依此类推?)。 编辑 :好的,所以我看到我忽略了Java不必在VM中运行的事实。那如何解释如何用LISP编写LISP编译器呢?还是这完全是一个新问题? 问题答案: 最初,您认为Java需要虚拟机

  • 问题内容: 谁能向我推荐最好,最可靠的CRM软件,它是开源的Java技术。 在我发布此问题之前,我做了一些Google搜索和Stackoverflow搜索,我正在获取基于PHP的CRM,但我特别在寻找Java技术。谢谢你 问题答案: 我有以下链接 内部客户关系管理 Java Source-开源ERP和CRM软件 manageability.org Hipergate -Intranet CRM,销

  • 问题内容: 在HACKERRANK中,这行代码非常频繁地出现。我认为这是跳过空格,但那是什么意思 问题答案: Scanner.skip跳过与模式匹配的输入,这里的模式是:- ?精确匹配零或前一个字符。 | 另类 []匹配出现在单个字符 \ r匹配回车符 \ n换行符 \ u2028将字符与索引为2018的基数16(8232的基数10或20050的基数8)区分大小写 \ u2029将字符与索引为20