我正在尝试编写一个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();
}
}
如果发生突变,交换突变会交换两个随机字符。
答案 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)。
您需要发布的任何内容我都非常乐意为您提供帮助。