Java 将进化算法转换为遗传算法

Java 将进化算法转换为遗传算法,java,algorithm,genetic-algorithm,evolutionary-algorithm,Java,Algorithm,Genetic Algorithm,Evolutionary Algorithm,从这里我可以看出,进化算法和遗传算法最大的区别之一是进化算法使用变异函数来生成新的种群,而遗传算法使用交叉函数 我发现了一种通过如下突变尝试生成目标字符串的方法: private static double newMutateRate(){ return (((double)perfectFitness - fitness(parent)) / perfectFitness * (1 - minMutateRate)); } private static String mu

从这里我可以看出,进化算法和遗传算法最大的区别之一是进化算法使用变异函数来生成新的种群,而遗传算法使用交叉函数

我发现了一种通过如下突变尝试生成目标字符串的方法:

  private static double newMutateRate(){
    return (((double)perfectFitness - fitness(parent)) / perfectFitness * (1 - minMutateRate));
  }

  private static String mutate(String parent, double rate){
    String retVal = "";
    for(int i = 0;i < parent.length(); i++){
      retVal += (rand.nextDouble() <= rate) ?
        possibilities[rand.nextInt(possibilities.length)]:
        parent.charAt(i);
    }
    return retVal;
  }
private static double newmutatate(){
返回(((双)perfectFitness-fitness(父项))/perfectFitness*(1-最小变异));
}
私有静态字符串变异(字符串父级,双速率){
字符串retVal=“”;
对于(int i=0;iretVal+=(rand.nextDouble()不,您的交叉函数不符合术语的常规含义。交叉应该从两个父母那里获取基因。您现在拥有的更像是一个突变函数

统一交叉是两个基因组的一种常见交叉实现,其中孩子获得了每个父母的大约50%的基因。这里我假设基因组长度是固定的

private String crossover(String parent1, String parent2){

    String child = "";
    for(int i = 0; i < parent1.length(); i++){
        if (rand.nextFloat() >= 0.5){
            child += parent1[i];
        }
        else {
            child += parent2[i];
        }
    }
}
private字符串交叉(字符串parent1、字符串parent2){
字符串child=“”;
对于(int i=0;i=0.5){
子女+=父母1[i];
}
否则{
子女+=父母2[i];
}
}
}

我认为使用目标函数构造交叉函数是不合适的,但您应该使用当前总体中的两个最佳字符串进行交叉

下面是一个此类交叉的伪代码:-

Crossover(String parent1,String parent2) {

 for(i=0;i<parent1.length;i++) {

       if(parent1[i]==target[i]) {
              child[i] = parent1[i]
       }
       else if(parent2[i]==target[i]) {
            child[i] = parent2[i]
       }
 } 

 insert remaining elements into child randomly

}
交叉(字符串parent1、字符串parent2){

对于(i=0;i我同意Junuxx,我只想补充一点。与其他进化算法相比,遗传算法更倾向于使用交叉算子,但并不是复制算子使算法遗传!我发现剪草机的例子很好地解释了这一点(不必担心实现代码,只需阅读说明即可):


您第一段中的假设(“进化算法使用变异函数生成新种群,而遗传算法使用交叉函数”)是错误的。不同之处在于遗传算法是进化算法的一种亚类型,明确使用“基因”为个体特征建模。阅读EAs比较。@Junuxx此问题不是GA要解决的最实际的问题,而只是学习目的之一,因为你已经知道用于计算适应度的最佳目标字符串。“两个最佳字符串”听起来像是一种。这通常是一种很好的方法,但对交叉原理来说并不是必不可少的。@Junuxx上述方法总能从任何两个父级生成更好的字符串,它们不一定是最好的。如果使用最好的字符串,在许多情况下收敛得更快。绝对同意第二部分(我在之前的评论中也说过同样的话)“但是,第一部分只是在看目标时。这是一种欺骗行为,”Nick说,“在EA. @ Junuxx的实际应用中,它是未知的,但不知道目标字符串是不可能的,而不是应用遗传ALGO的理想问题。不,这是不可能的。例如,适合度的目标不是通过比较基因组和理想基因组来衡量的(我们不知道它看起来像什么)但通过测量实际性能:汽车在撞车前行驶了多远,或者完成一圈需要多长时间?你能提供一些关于有效交叉的伪代码吗?过去我们使用轮盘赌的方法来确定哪些基因更有利,但在如何实现这一点上不是100%。@Nick:见e上面的dit。不要混淆交叉和选择;交叉只会产生新的基因组,应该关注哪些基因更有利。只有通过消除最脆弱的个体,你才能获得自然选择,从而随着时间的推移而改善。
Crossover(String parent1,String parent2) {

 for(i=0;i<parent1.length;i++) {

       if(parent1[i]==target[i]) {
              child[i] = parent1[i]
       }
       else if(parent2[i]==target[i]) {
            child[i] = parent2[i]
       }
 } 

 insert remaining elements into child randomly

}