Java 遗传算法:仅在部分基因型中进行均匀交叉

Java 遗传算法:仅在部分基因型中进行均匀交叉,java,genetic-algorithm,Java,Genetic Algorithm,我需要实现一个“均匀交叉”遗传算子 编辑:我意识到,如果一个数字出现在两个人身上,那么有重复的(因为随机交换)是正常的。 所以我加了一句: if(anyDuplicate(p0_genome,minIndex) || anyDuplicate(p1_genome,minIndex)){ //rollback: swap again swap(p0

我需要实现一个“均匀交叉”遗传算子

编辑:我意识到,如果一个数字出现在两个人身上,那么有重复的(因为随机交换)是正常的。 所以我加了一句:

            if(anyDuplicate(p0_genome,minIndex) || anyDuplicate(p1_genome,minIndex)){
                                //rollback: swap again
                                swap(p0_genome,p1_genome,i);
                            }
但它仍然会产生重复(大多数情况下,基因位于minIndex位置(被排除在循环之外!!!)。当然,我测试了anyDuplicate的功能,效果非常好

我用这个密码试过了

> Note: Individual 1 and 2 have the same length but a different number
> of valid bits.
> 
> Foe example: genotype length (of both individuals) = 10 ,
> representation as numbers from 1 to 10 without anyone repeated,the
> start delimiter is 1 and the end delimiter should be 2. Not used genes
> are = 0
> 
> individual 1(p0_genome) = {1,4,5,3,2,0,0,0,0,0}
> individual 2(p1_genome) = {1,4,6,3,8,2,0,0,0,0}
设计输出:

Individual 1(p0_genome): **1** <some genes ALL DIFFERENTS> **2** 0,0,0,.....
Individual 2(p1_genome): **1** <some genes ALL DIFFERENTS> **2** 0,0,0,.....
            int indexOfLastP0 = findLast(p0_genome,gl); // last valid bit (the one = 2) of first individual
            int indexOfLastP1 = findLast(p1_genome,gl); // last valid bit (the one = 2) of second individual

            int minIndex = Math.min(indexOfLastP0,indexOfLastP1); // last valid bit of the "smaller" of the inviduals

    // Building sons
  /* exchange bit without considering delimiters bit (1 and 2)
   and according to the smaller individual */
            int threshold = 0.60;

    for (int i=1; i<minIndex; i++) {
        if (Math.Random()>threshold) {
            swap(p0_genome,p1_genome,i);
        }
    // when exiting the loop the remaining of genes remain the same
    public void swap(int[] array1, int[] array2 ,int i){
        int aux=array1[i];
        if (array2[i]!=2){
        array1[i]=array2[i];
                }
        if (aux!=2){
        array2[i]=aux;
                }            
 public boolean anyDuplicate(int[] genoma,int min){
        for (int i=0;i<=min;i++){
            for (int j=0;j<=min;j++){
               if (genoma[i]==genoma[j] && i!=j){
                  return true;
               }
            }
        }
        return false;
    }        
    public int findLast(int[] mgenome,int genotypeLength){
        int k=1; // 1 element is not considered
        while (k<genotypeLength && mgenome[k]!=0){
            k++;
        }
        return k-1; // **I also tried returning k;**
    }
anyDuplicate()代码:

Individual 1(p0_genome): **1** <some genes ALL DIFFERENTS> **2** 0,0,0,.....
Individual 2(p1_genome): **1** <some genes ALL DIFFERENTS> **2** 0,0,0,.....
            int indexOfLastP0 = findLast(p0_genome,gl); // last valid bit (the one = 2) of first individual
            int indexOfLastP1 = findLast(p1_genome,gl); // last valid bit (the one = 2) of second individual

            int minIndex = Math.min(indexOfLastP0,indexOfLastP1); // last valid bit of the "smaller" of the inviduals

    // Building sons
  /* exchange bit without considering delimiters bit (1 and 2)
   and according to the smaller individual */
            int threshold = 0.60;

    for (int i=1; i<minIndex; i++) {
        if (Math.Random()>threshold) {
            swap(p0_genome,p1_genome,i);
        }
    // when exiting the loop the remaining of genes remain the same
    public void swap(int[] array1, int[] array2 ,int i){
        int aux=array1[i];
        if (array2[i]!=2){
        array1[i]=array2[i];
                }
        if (aux!=2){
        array2[i]=aux;
                }            
 public boolean anyDuplicate(int[] genoma,int min){
        for (int i=0;i<=min;i++){
            for (int j=0;j<=min;j++){
               if (genoma[i]==genoma[j] && i!=j){
                  return true;
               }
            }
        }
        return false;
    }        
    public int findLast(int[] mgenome,int genotypeLength){
        int k=1; // 1 element is not considered
        while (k<genotypeLength && mgenome[k]!=0){
            k++;
        }
        return k-1; // **I also tried returning k;**
    }
public boolean anyDuplicate(int[]基因组,int min){

对于(int i=0;i好的,因此您尝试交换一次,如果结果基因组中的任何一个包含重复值,您将再次尝试交换。如果第二次尝试后仍然存在重复值,您将放弃。这是无效的,而且您的基因组越长,这就越不可能起作用

解决方案A:如果交换的值不在目标基因组中,则只能尝试进行交换。这将提供如下交换功能:

public void swap(int[] array1, int[] array2 ,int i){
    int aux=array1[i];
    if (array2[i]!=2 && !Arrays.asList(array1).contains(array2[i]){
    array1[i]=array2[i];
            }
    if (aux!=2 && !Arrays.asList(array2).contains(array1[i]){
    array2[i]=aux;
            }
问题是它可能会完全锁定在不同位置包含相同值的基因组

g1 = {1, 4, 8, 9, 3, 2, 0, 0}
g2 = { 1, 3, 9, 8, 4, 2, 0, 0}
根本没有有效的交换,交叉将返回原始基因组

解决方案B:如果要交换的值已经存在于目标基因组中,那么在目标基因组中找到该基因的索引,并交换该索引。这可能会导致在大部分基因组中需要交换,当然,当i=j时不应该发生


某种程度上取决于所需的行为。对于上面的示例基因组,成功的交叉会是什么样子?

数学方面,作为旁注。随机比随机更具偏见和效率。我建议您使用随机类。或者更好的是,使用基于/dev/Random或类似的纯随机生成器;任何PRNG将最终导致可能导致意外但微妙的事情发生的模式。
swap()
的代码在哪里?重复是什么意思,期望的结果是什么样子?我尝试了“解决方案A,但问题是相同的。在尝试解决方案B之前,它甚至“更糟”这个问题似乎是由“统一交叉”的副作用引起的。不过我会再试一次,我会接受你的答案effort@dragonmnl:只要获得重复项,您就可以尝试继续交换(将
if(anyDuplicate…
更改为
while(anyDuplicate…
),但这可能需要很长时间,或者如果不可能没有重复的交叉,则可能根本不会终止。在这方面,我解决了从0重写代码并在应用程序中更改更多内容的问题。非常感谢您的努力!