Python:遗传算法性能弱

Python:遗传算法性能弱

问题描述:

我目前正在研究一个学校项目,该项目包括在给定固定孔隙度(因此我们找到最佳孔隙分布)的情况下寻找可能的最大多孔介质。我使用遗传算法来解决这个问题,方法是将介质建模为一个填充0表示空洞,1表示固体介质和2表示水的方阵。我查找了互联网以获得交叉率,变异率等的最佳值。问题是,有时我达到最大值,然后开始下降几代人,有时我被所有世代中的0水排除在介质之外。我不知道我哪里错了。如果你需要进化过程或交叉的代码,请随时在评论中告诉我。提前致谢。Python:遗传算法性能弱

交叉点: 该功能交叉两种介质并保持孔隙度,小孩应该具有与父母双方相同的孔隙率。

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给了我很好的效果,但并不意味着我失去了一些父母的基因? 另一个问题,如果我选择第一次GA运行的结果并在下一次使用它,那么它会提高性能呢?

+0

请始终显示代码 - 对于任何人来说,如果没有可行的示例数据,尤其是没有代码的情况下帮助您很难。 – flyingmeatball

+0

在这里显示你的代码总是一个好主意,但是这听起来像你可能碰到了一个鞍点,你可能想用不同的变异和交叉概率再试一次。 –

+0

@MattCremeens我尝试了很多费率。起初它给出了令人满意的结果,但现在具有相同的值,我什么也得不到 –

我相信问题可能会在这里

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

这似乎是你从父母一方采取一些染色体,并将它们分配到另一个,但你没有这样做,随意。我认为会更好的是,如果您生成一个随机交叉点,并用//k替换//3。但你需要的是两条新的染色体,如

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 

并且对下一个子染色体做相反的处理。

在任何情况下,初始随机参数(例如交叉和变异概率)都应该进行试验,以确保没有达到鞍点。

+0

但是我应该保持交叉点的数量吗?或改变它?例如,我在随机地方执行两点交叉吗?此外,您可能已经注意到,由于在交叉后保持相同孔隙度的必要性,后者确实有点突变 –

+0

两个亲本的染色体应该每次随机分裂并组合以形成新的(后代)染色体或被克隆。无论哪种方式,您每次都会创建两个新的染色体。我不确定孔隙是多少。 –

+0

孔隙度是介质的一个属性,它表示固体节点与矩阵中元素数量的比率,即:黑色方块的数量除以矩阵的平方的大小。我认为我发现了我的问题。问题在于初始人口的弱点,这可能会导致非常缓慢的收敛,这就是为什么我没有看到明显的变化,所以更高的变异概率适合更快地收敛到解决方案。你怎么看? –