我想在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])