Java与提高遗传算法的效率

时间:2011-01-12 23:55:21

标签: java performance genetic-algorithm

嘿伙计们, 我想知道我是否可以就提高实现遗传算法的程序的整体效率提出一些建议。是的,这是一个任务问题,但我已经完成了自己的任务,我只是想找到一种方法让它更好地表现 Problem Description

我的程序此刻读取由成分类型h或p组成的给定链。(例如hphpphhphpphphhpphph)对于每个H和P,它生成一个随机移动(向上,向下,向左,向右)并添加移动到“染色体”对象中包含的arrayList。一开始,该计划为10,000个染色体产生了19个移动

   SecureRandom sec = new SecureRandom();
    byte[] sbuf = sec.generateSeed(8);
    ByteBuffer bb = ByteBuffer.wrap(sbuf);
    Random numberGen = new Random(bb.getLong());
    int numberMoves = chromosoneData.length();
    moveList = new ArrayList(numberMoves);
    for (int a = 0; a < numberMoves; a++) {
        int randomMove = numberGen.nextInt(4);
        char typeChro = chromosoneData.charAt(a);
        if (randomMove == 0) {
            moveList.add(Move.Down);
        } else if (randomMove == 1) {
            moveList.add(Move.Up);
        } else if (randomMove == 2) {
            moveList.add(Move.Left);
        } else if (randomMove == 3) {
            moveList.add(Move.Right);
        }

    }

此后,从群体中选择染色体到交叉。我的交叉函数从最适合的20%的人群中随机选择第一条染色体,另一条从最高的20%之外随机选择。然后交叉选择的染色体并调用突变功能。我相信我受影响最大的领域是计算每个染色体的适应度。目前我的健身功能创建了一个二维数组作为网格,从上面显示的函数生成的移动列表中按顺序放置移动,然后循环遍历数组进行适应度计算。 (IE发现,位置[2,1]的H是Cord [1,1] [3,1] [2,0]或[2,2]也是H,如果找到H,它只增加计数债券发现)

计算完成后,从我的群体中移除最不适合的染色体并添加新的染色体,然后对染色体的阵列列表进行分类。冲洗并重复直至找到目标溶液

如果你们想看到更多我的代码来证明我在寻求帮助之前实际完成了工作,请告诉我(不要发布很多其他学生不能复制意大利面我的东西)

正如评论中所建议的那样,我在我的应用程序中运行了探查器(以前从未使用过它,只有第一年的CS学生),而我对我遇到问题的地方的初步猜测有点不正确。从分析者告诉我的是,大热点是:

1)将新染色体与人群中的其他染色体进行比较以确定其位置。我这样做是通过实现Comparable。

public int compareTo(Chromosome other) {
    if(this.fitness >= other.fitness)
                    return 1;
         if(this.fitness ==other.fitness )
                   return 0;
            else
                    return -1;



}

2)所描述的另一个问题是我的实际演化功能,占用了大约40%的CPU时间。下面所述方法的代码示例

    double topPercentile = highestValue;
    topPercentile = topPercentile * .20;
    topPercentile = Math.ceil(topPercentile);
    randomOne = numberGen.nextInt((int) topPercentile);
    //Lower Bount for random two so it comes from outside of top 20%
    int randomTwo = numberGen.nextInt(highestValue - (int) topPercentile);
    randomTwo = randomTwo + 25;
    //System.out.println("Selecting First: " + randomOne + " Selecting Second: " + randomTwo);
    Chromosome firstChrom = (Chromosome) populationList.get(randomOne);
    Chromosome secondChrom = (Chromosome) populationList.get(randomTwo);
    //System.out.println("Selected 2 Chromosones Crossing Over");
    Chromosome resultantChromosome = firstChrom.crossOver(secondChrom);
    populationList.add(resultantChromosome);
    Collections.sort(populationList);
    populationList.remove(highestValue);
    Chromosome bestResult = (Chromosome) populationList.get(0);

3)另一个主要的绩效指标是初始人口播种,由帖子中的第一个代码样本执行

5 个答案:

答案 0 :(得分:5)

  

我认为我受影响最大的领域是计算每个染色体的适合度

如果你不确定那么我认为你还没有在程序上运行一个分析器。
如果您想提高性能,首先应该进行性能分析。

答案 1 :(得分:2)

不要反复对人口进行排序,而是使用一个维护其内容已经排序的集合。 (例如TreeSet)

答案 2 :(得分:1)

如果您的适应度测量在几代人之间是一致的(即不依赖于其他成员),那么我希望至少您将其存储在染色体对象中,因此您只需为每个成员计算一次。有了它,你只需要在每次迭代时计算新生成/组装染色体的适应度。如果没有关于如何计算适应性的更多信息,那么很难能够在该领域提供任何优化。

答案 3 :(得分:1)

您的随机数生成器种子不需要加密强大。

Random numberGen = new Random();

答案 4 :(得分:1)

播种人口时的小幅加速是删除所有测试和分支:

    static Move[] moves = {Move.Down, Move.Up, Move.Left, Move.Right};

    ...

    moveList.add(moves[randomMove]);