首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >确认代码是正确的- Java中的交叉方法

确认代码是正确的- Java中的交叉方法
EN

Code Review用户
提问于 2012-02-17 01:34:08
回答 2查看 5.1K关注 0票数 5

我为某人做了这段代码,但是在把它传递给他们之前,我需要对它进行双重检查。代码似乎很好,但我需要有人确认我已经正确地编码了交叉方法。

如果一个熟悉遗传算法和交叉方法的人能确认我有正确的逻辑和代码支持每一种交叉方法,那就太好了。

代码语言:javascript
运行
复制
 //one crossover point is selected, string from beginning of chromosome to the 
 //crossover point is copied from one parent, the rest is copied from the second parent

 // One-point crossover

public void onePointCrossover(Individual indi) {
    if (SGA.rand.nextDouble() < pc) {
        // choose the crossover point 
        int xoverpoint = SGA.rand.nextInt(length);


        int tmp;
        for (int i=xoverpoint; i<length; i++){
            tmp = chromosome[i];
            chromosome[i] = indi.chromosome[i];
            indi.chromosome[i] = tmp;
        }   
    }   
}
//two crossover point are selected, binary string from beginning of chromosome to
//the first crossover point is copied from one parent, the part from
// the first to the second crossover point is copied from the second parent
// and the rest is copied from the first parent

// Two-point crossover
    public void twoPointCrossover(Individual indi) {
        if (SGA.rand.nextDouble() < pc) {
            // choose the crossover point 
            int xoverpoint = SGA.rand.nextInt(length);
            int xoverpoint2 = SGA.rand.nextInt(length);

            int tmp;
            //swap
            if (xoverpoint > xoverpoint2){
                tmp = xoverpoint;
                xoverpoint = xoverpoint2;
                xoverpoint2 = tmp;
            }

            for (int i=xoverpoint; i<xoverpoint2; i++){
                tmp = chromosome[i];
                chromosome[i] = indi.chromosome[i];
                indi.chromosome[i] = tmp;
            }   
        }   
    }

    //  For each gene, create a random number in [0,1]. If
    // the number is less than 0.5, swap the gene values in
    // the parents for this gene; otherwise, no swapping 

// Uniform Crossover
    public void UniformCrossover(Individual indi) {
        if (SGA.rand.nextDouble() < pc) {
        for (int i= 1; i<length; i++){
            boolean tmp =  SGA.rand.nextFloat() < 0.5;
            if(tmp){
                chromosome[i] = indi.chromosome[i];

            }
            }

        }

亲本1=染色体亲本2= indi.chromosome

我要把父母变成孩子。

EN

回答 2

Code Review用户

发布于 2012-02-17 01:55:40

很难仅仅看一看,但是有一些东西会跳出来。比bug更好的改进:

  • 对于单点交叉使用System.arraycopy()将是更可靠的。例如: System.arraycopy(parent1Genes,0,childGenes,0,xoverPoint);System.arraycopy(parent2Genes,xoverPoint,childGenes,xoverPoint,geneSize-xoverPoint);
  • 对于两点,您可以使用相同的方法,但是它会稍微复杂一些。
  • 在统一交叉中,您可以使用rand.nextBoolean(),它返回真或假,而不是比较浮点数。
票数 4
EN

Code Review用户

发布于 2012-02-17 08:26:43

有点超出了问题的范围,但有一件事是,如果你是做交叉直接对父母,那么父母将是不可行的进一步选择。否则,该算法可能会对一个已经被操纵的父母/孩子做几个交叉操作(假设您允许选择同一个个体进行多次繁殖)。

当我亲自执行这个任务的时候,我总是通过个人来进行交叉和返回孩子。这样,两代人就更容易分开了。另一种选择是克隆父代中的个体,对克隆的拷贝进行交叉和突变,并使用原始个体进行选择。

你的实现在我看来还不错。但是,正如注释中所述,您确实需要为这些函数编写测试。通过模拟随机生成函数,您可以控制结果。也就是说,不产生像这样的随机数:

代码语言:javascript
运行
复制
SGA.rand.nextDouble()

你可以在你的班上有一个字段:

代码语言:javascript
运行
复制
pubilc class Crossover {
    private Randomizer randomizer
    public Crossover(Randomizer randomizer) {
         this.randomizer = randomizer;
    }

    public void onePointCrossover(Individual indi) {
        if (randomizer.nextDouble() < pc) {
            // do stuff 
        }
    }
}

其中,随机化器是与您需要的nextXXXX()方法的接口。这样,您就可以在测试中为随机化器创建模拟,并有一个委托给SGA.rand.nextXXXX()的具体实现。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/9077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档