我制作了一个编写目标短语的遗传算法,但我觉得每次迭代都需要太长时间,所以我想知道你是否对如何加速它有任何想法 .

谢谢

from random import randint, random
from time import time

def rescale(X,A,B,C,D,force_float=False):
    retval = ((float(X - A) / (B - A)) * (D - C)) + C
    if not force_float and all(map(lambda x: type(x) == int, [X,A,B,C,D])):
        return int(round(retval))
    return retval

在这里,我创建一个组成短语的随机字符列表

class DNA:
    def __init__(self,num):
        self.genes=[]
        for i in range(num):
            self.genes.append((chr(randint(32,126))))

用字符串转换基因

def getPhrase(self):
        return(''.join(self.genes))

计算适合度(与目标的相似性)

def fitness(self,target):
        score=0
        for i in range(len(self.genes)):
            if (self.genes[i] == target[i]): 
                score+=1

        return score*score/(len(target)*len(target))

混合两个基因(从一个和一些到另一个获得一些角色)

def crossover(self,partner):

        child = DNA(len(self.genes))

        midpoint = randint(0,len(self.genes))

        for i in range(len(self.genes)): 
            if (i > midpoint):
                child.genes[i] = self.genes[i]
            else:              
                child.genes[i] = partner.genes[i]
        return child

突变基因(添加一些随机字符)

def mutate(self,mutationRate):
        for i in range(len(self.genes)):
            if (random() < mutationRate):
                self.genes[i] = chr(randint(32,126))

DNA对象列表

class Population:

    def __init__(self,target,mutationRate,num):
        self.population=[]
        for i in range(num): 
            self.population.append(DNA(len(target)))

        self.mutationRate=mutationRate
        self.calcFitness(target)
        self.generations=0

列出每个基因的适应性

def calcFitness(self,target):
        self.fitness=[]
        for i in range(len(self.population)):
            self.fitness.append(self.population[i].fitness(target))

为交叉功能制作一个列表,其中的条目与适应度成比例

def naturalSelection(self):
        global index, x
        self.matingPool=[]

        self.maxFitness = 0
        for i in range(len(self.population)):
            if (self.fitness[i] > self.maxFitness):
                self.maxFitness = self.fitness[i]
                index=i

        print(DNA.getPhrase(population.population[index]),'            generation: ',self.generations)
        if (DNA.getPhrase(population.population[index]))==target:
            x=False
        for i in range(len(self.population)):
            fitness = rescale(self.fitness[i],0,float(self.maxFitness),0,1)
            n = (fitness * 100)
            for j in range(int(n)):
                self.matingPool.append(population.population[i])

更新人口

def generate(self):
        for i in range(len(self.population)):
            a = randint(0,len(self.matingPool)-1)
            b = randint(0,len(self.matingPool)-1)
            partnerA = self.matingPool[a]
            partnerB = self.matingPool[b]
            child = partnerA.crossover(partnerB)
            child.mutate(self.mutationRate)
            population.population[i] = child
        self.generations+=1

start=time()
target= input("Target:  ")        
population = Population(target, 0.05,300)
x=True
while x==True:
    population.naturalSelection()
    population.generate()
    population.calcFitness(target)
end=time()
print(end-start)