人工智能之遗传算法解决八皇后

1、问题描述
  八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上 放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n1×n1,而皇后个数也变成n2。而且仅当 n2 ≥ 1 或 n1 ≥ 4 时问题有解。
2、方法使用:之前都是图的盲目搜索来进行这个八皇后的问题,这次学习了了这个遗传算法,就用python实现了一下。
适应度函数的定义,种群大小、交叉比例、变异比例、算法终止条件 ;
(1)适应度函数= 28-互相攻击的皇后对的数目;
(2)种群大小设置为 20;
(3)交叉比例 1;
(4)变异比例 0.05;
(5)算法终止条件 当出现一个适应度为28的状态时停止算法或者迭代次数达到3000停止算法;
然后就开始我们的编码过程了,(这里这个可攻击的皇后对的计算函数也是用的之前的DFS解决八皇后的那个代码思路。)

import  random
import copy
def Variataion(Population_list):#种群作为参数,进行变异 变异率为0.05
       # print("准备开始变异",Population_list)
       index1,index2=random.randint(0,19),random.randint(0,7)
       # print(index1,index2)
       value=random.randint(0,7)
       Population_list[index1][index2]=value
       return  Population_list

def Crisscross(Population_list):#种群作为参数,进行交叉
     # print(len(Population_list))
     i=0
     NewPopulation_list=[]
     while True:
         x=[]
         y=[]
         temp1=copy.deepcopy(Population_list[i])
         temp2=copy.deepcopy(Population_list[i+1])
         key=random.randint(0,7)
         # print("测试点",key)
         for j in range(key):
             x.append(temp1[j])
         for j in range(key,len(temp1)):
             x.append(temp2[j])
         for j in range(key):
             y.append(temp2[j])
         for j in range(key,len(temp1)):
             y.append(temp1[j])
         i+=2
         # print(x,y)
         NewPopulation_list.append(x)
         NewPopulation_list.append(y)
         if i==len(Population_list):
             # print(NewPopulation_list)
             return NewPopulation_list

def StartPopulation():#产生一个初始的随机种群,个体数量为20
     Population_list=[]#种群列表
     while True:
         Individual_list=[]#个体列表
         while True:
            x=random.randint(0,7)
            Individual_list.append(x)
            if len(Individual_list)==8:
                Population_list.append(Individual_list)
                # print(Individual_list)
                # print(Population_list)
                break
         if len(Population_list)==20:
             #print(Population_list)
             return Population_list

def tran(Individual):#将序列转化为矩阵
    #print(Individual)
    zt=[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]]
    for i in range(8):
           zt[Individual[i]][i]=8
    #printf(zt)
    return zt
    pass

def Fitness(zt):#参数为矩阵
    ans=0
    for i in range(8):
        for j  in range(8):
            if  zt[i][j]==8:
                for m in range(j):
                    if  zt[i][m]==8:
                        ans+=1
                for  a in range(i):
                    for b in range(8):
                        if zt[a][b]==8:
                            if (a-b==i-j)or (a+b==i+j):  # 判断对角线
                                         ans+=1
    return 28-ans

def printf(chess):#用来输出测试
    for i in range(8):
        for j in range(8):
            print(chess[i][j],end=' ')
        print()

def  Iheritance():#遗传算法
    Population_list=StartPopulation()
    # print(Population_list)
    # for item in Population_list:
    #     print(Fitness(tran(item)),end=' ')
    # print()
    index=0
    while True:
        if index>3000:
            return -1
        for item in Population_list:
            if Fitness(tran(item))==28:
                print("找到一个可行的解")
                return item
        select=[]#选择种群列表
        for item in Population_list:
            if Fitness(tran(item))>=20:
                select.append(item)
        if len(select)!=len(Population_list):
            while True:
                x=random.randint(0,19)
                if Fitness(tran(Population_list[x]))>22:
                    select.append(Population_list[x])
                if len(select)==len(Population_list):

                        break
        # print(select)
        Crisscross_list=Crisscross(select)#交叉遗传产生的种群
        Variataion_list=Variataion(Crisscross_list)#变异之后产生的种群
        Population_list.clear()
        Population_list=copy.deepcopy(Variataion_list)
        index+=1
if  __name__=="__main__":
      reslut=Iheritance()
      if reslut==-1:
          print("到达最大迭代次数")
      else:
          print(reslut)
          printf(tran(reslut))
          print("适应度为",Fitness(tran(reslut)))
      pass

猜你喜欢

转载自blog.csdn.net/qq_44741914/article/details/106182198