Python:遗传算法性能较差

Python: Genetic algorithm weak performance

我目前正在做一个学校项目,该项目包括在给定固定孔隙率的情况下从多孔介质中找出最大可能的水(因此我们找到了最佳孔隙分布)。我使用遗传算法通过将介质建模为方阵来解决此问题,其中填充 0 表示空隙,1 表示固体介质,2 表示水。我在互联网上查找交叉率、突变率等的最佳值。问题是有时我达到最大值然后它开始下降,有时我在所有世代中都被 0 水从介质中卡住。我不知道我哪里出错了。如果您需要进化过程或交叉的代码,请随时在评论中告诉我。提前致谢。

交叉: 此函数跨越两种介质并保持孔隙率,child 应与 parents.

具有相同的孔隙率
def crossover(g,h,n,p,cp):#crossover(parent1,parent2,size of matrix, porosity,crossover rate)
b=n*n
k=int(b*p)
l=g
if cp>rnd.random():
    l[n//3:2*n//3] = h[n//3:2*n//3]
    count = 0
    for i in range(n):
        for j in range(n):
            if l[i][j] == 1:
                count +=1
    diff = count-k
    if diff>0:
        while diff>0:
            i=rnd.randint(0,n-1)
            j=rnd.randint(0,n-1)
            if l[i][j] == 1:
                l[i][j] = 0
            diff -=1
    if diff<0:
        while diff<0:
            i=rnd.randint(0,n-1)
            j=rnd.randint(0,n-1)
            if l[i][j] == 0:
                l[i][j] = 1
            diff+=1
return l

这个交叉是两点交叉。

进化码:

 def evolve(pop,m,n,p,mp,cp,sp=0.3):#evolve(the population list,population length, matrix size,porosity,mutation probability, crossover probability, rate of individuals to be selected for the upcoming generation)
graded = [ (ratio(pop[i], n), i) for i in range(m)]
graded = [ x[1] for x in sorted(graded)]
retain_length = int(m*sp)
parents = [pop[x] for x in graded[retain_length:]]
# randomly add other individuals to promote genetic diversity
for individual in graded[:retain_length]:
    if 0.025 > rnd.random():
        parents.append(pop[individual])       
# mutate some individuals
for individual in parents:
    if mp>rnd.random():
       individual = mutate(individual,n,mp)
# crossover parents to create children
parents_length = len(parents)
desired_length = m - parents_length
children = []
while len(children) < desired_length:
    male = rnd.randint(0, parents_length-1)
    female = rnd.randint(0, parents_length-1)
    if male != female:
        male = parents[male]
        female = parents[female]
        children.append(crossover(male,female,n,p,cp))
parents.extend(children)
return parents

编辑: 将突变率提高到 0.05 后,GA 给了我很好的结果,但这是否意味着我丢失了一些 parents 基因? 另一个问题,如果我选择人口作为第一个 GA 运行 的结果并在下一个 GA 中使用它,它会提高性能吗?

我认为问题可能出在这里

l[n//3:2*n//3] = h[n//3:2*n//3]

这似乎是您从一条 parent 中取出一些染色体并将它们分配给另一条染色体的地方,但您并不是随机这样做的。我认为如果您生成一个随机交叉点并将 //3 替换为 //k,效果会更好。但是你需要的是两条新的染色体,比如,

m = []
m_cnt = 0
for elem in l:
    if m_cnt < k:
        m[m_cnt] = elem
     m_cnt += 1

m_cnt = k
for elem in h:
    if m_cnt >= k:
        m[m_cnt] = elem
    m_cnt += 1

对下一个 child 染色体做相反的操作。

在任何情况下,都应试验初始随机参数,例如交叉和变异概率,以确保不会达到鞍点。