实现周期交叉的最简单方法

时间:2019-08-15 12:14:30

标签: python

我想在python中实现循环转换,并且我想以最简单的方式做到这一点。在循环交叉中,顶点应从一个父对象复制到子对象中,但其位置应从另一父对象继承。
p1 = <1,2,3,4,5,6,7,8,9>
p2 = <4,1,2,8,7,6,9,3,5>
c1 = <1,2,3,4,7,6,9,8,5>
c2 = <4,1,2,8,5,6,7,3,9>
以下是其工作方式的链接:
http://www.rubicite.com/Tutorials/GeneticAlgorithms/CrossoverOperators/CycleCrossoverOperator.aspx
我想知道有没有更简单的方法来做到这一点。
谢谢

import numpy as np
from copy import deepcopy

class chromosome():
    def __init__(self, genes, id=None, fitness=-1, flatten= False, lengths=None):
        self.id = id
        self.genes = genes
        self.fitness = fitness   

    def describe(self):
        print('ID=#{}, fitenss={}, \ngenes=\n{}'.format(self.id, self.fitness, self.genes))        

    # gives the length of a chromosome
    def chrom_length(self):
        return len(self.genes)

"Cycle crossover" 
def CX(pop, pop_size, selection_method, pc):
    p1 = chromosome(genes= np.array([8,4,7,3,6,2,5,1,9,0]),id=0,fitness = 125.2)  
    p2 = chromosome(genes= np.array([0,1,2,3,4,5,6,7,8,9]),id=1,fitness = 125.2)     
    chrom_length = chromosome.chrom_length(p1)
    print("\nParents")
    print("=================================================")
    chromosome.describe(p1)
    chromosome.describe(p2)
    c1 = chromosome(genes= np.array([-1]*chrom_length),id=0,fitness = 125.2)  # childs
    c2 = chromosome(genes= np.array([-1]*chrom_length),id=1,fitness = 125.2)

    if np.random.random() < pc:  # if pc is greater than random number
        p1_copy = p1.genes.tolist()
        p2_copy = p2.genes.tolist()
        swap = True
        count = 0
        pos = 0   

        while True:
            if count>chrom_length: break
            for i in range(chrom_length):
                if c1.genes[i]==-1:
                    pos=i
                    break

            if swap==True:
                while True:
                    c1.genes[pos] = p1.genes[pos]
                    count+=1
                    pos = p2.genes.tolist().index(p1.genes[pos])
                    if p1_copy[pos] == -1:
                        swap = False
                        break
                    p1_copy[pos] = -1
            elif swap==False:
                while True:
                    c1.genes[pos] = p2.genes[pos]
                    count+=1
                    pos = p1.genes.tolist().index(p2.genes[pos])
                    if p2_copy[pos] == -1:
                        swap = True
                        break
                    p2_copy[pos] = -1

        for i in range(chrom_length): #for the second child
            if c1.genes[i]==p1.genes[i]:
                c2.genes[i]=p2.genes[i]
            else:
                c2.genes[i]=p1.genes[i]

        for i in range(chrom_length): #Special mode
            if c1.genes[i]==-1:
                if p1_copy[i]==-1: #it means that the ith gene from p1 has been already transfered 
                    c1.genes[i]=p2.genes[i]
                else:
                    c1.genes[i]=p1.genes[i]                               

    else:  # if pc is less than random number then don't make any change
        c1 = deepcopy(p1)
        c2 = deepcopy(p2)
    return c1, c2

cross = CX(20, 10,"tour",1)
print("\nChilds")
print("=================================================")
for i in range(len(cross)):
    chromosome.describe(cross[i])

0 个答案:

没有答案