遗传算法健身评分问题

时间:2017-07-11 19:48:31

标签: java genetic-algorithm genetic-programming

我正在尝试编写一个java程序,它生成一组随机字符,并最终落在输入的字符串上,以模拟无限猴子定理(https://en.wikipedia.org/wiki/Infinite_monkey_theorem)之类的东西。我正在测试的问题是,当我测试它时,所有起始种群的健康水平都为0,因此在自然选择过程中没有任何东西被添加到交配池中。这是项目所需要的。

目标:字符串“Hello”

突变率: 0.01

Population Max: 100个DNA对象,每个对象包含基因的char []数组。

这是我计算健身的功能:

public void calcFitness(String target){
        double score = 0.0;
        for(int i = 0; i < this.genes.length; i++){
            if(this.genes[i] == target.charAt(i)){
                score++;
            }
        }
        this.fitness = score/this.genes.length;
    }

我是遗传编程的新手,并不确定我做错了什么,任何帮助都会受到赞赏,任何关于遗传编程的提示或见解也会受到赞赏。

修改

以下是选择过程的代码:

 public void naturalSelection(){
        ArrayList<DNA> selection = new ArrayList<>();
        Random rand = new Random();
        String child = "";
        DNA[] newPop = new DNA[popMax];
        for(int i = 0; i < population.length; i++){
            for(int j = 0; j < population[i].getFitness(); j++){
                selection.add(population[i]);
            }
        }
        for(int i = 0; i < selection.size(); i++){
            int parentSelect = rand.nextInt(selection.size());
            DNA parent1 = selection.get(parentSelect);
            child = parent1.split(true);
            parentSelect = rand.nextInt(selection.size());
            DNA parent2 = selection.get(parentSelect);
            child += parent2.split(false);
            newPop[i] = new DNA(child);
        }
        double mutation = rand.nextDouble();
        if(mutation < this.mutationRate){
            this.population = swapMutation(newPop);
            calcFittest();
        }
        else{
            this.population = newPop;
            calcFittest();
        }
    }

如果发生突变,交换突变会交换两个随机字符。

2 个答案:

答案 0 :(得分:1)

我建议使用测量从候选者到目标字符串的距离的适应度函数。然后,您将最大限度地降低整体适应度,而不是最大化。

要做到这一点:

class JogadorAdivinha extends Jogador<JogadorAdivinha> {
  boolean melhor (JogadorAdivinha outro) { return true; }
}

这应该更好,因为它会更好地区分每个候选人。如果没有看到你正在使用的随机字符串生成器很难说,但可能的候选人数很可能是天文数字,他们中任何一个人的健身功能得分都很低。

也可能值得指出,您的代码可能是遗传算法的一部分,而不是遗传编程。

如果你想改进选择,我建议作为一种易于编程的技术锦标赛选择 - 从人群中选择n个随机个体,然后从n个人中选择最佳健身个体。这使得更好的候选人比其他人更有可能被选中,并且有额外的奖励,你不需要计算人口中每个人的适合度。

答案 1 :(得分:0)

我刚刚完成了无限猴子定理的GA。您可以在https://github.com/Willtl/infinite_monkey_theorem

找到

它是用C ++编写的,但在Java中做同样的事情并不困难。您可以使用Eclipse CPP打开它。

void Individual::calculateFitness(vector<char> chromosomePlate) {
fitness = 0;

for (int i = 0; i < chromosome.size(); i++) {
    int gene = (int) chromosome[i];
    int genePlate = (int) chromosomePlate[i];
    if (gene == genePlate && gene != 32) {
            fitness++;
    }
}

首先,当我读取输入时,我把它放到小写字母中。然后为了便于随机化和比较,我使用ASCII。因此,当我考虑小写时,我的字符范围从97到122.我也将空格保留在染色体上,但是在健身功能中我忽略了它(32)。

您需要发布的任何内容我都非常乐意为您提供帮助。