遗传算法解决八皇后问题

  • 程序设计的概要思想
    • 编码方案
    • 适应度的计算
    • 初始种群
    • 选择算子
    • 交叉算子
    • 变异算子
    • 终止策略
  • 程序的主要函数及其作用
  • 运行结果截图
  • Python源代码

程序设计的概要思想

遗传算法是模拟自然选择和遗传学机理的生物进化过程的一种计算模型,主要特点为直接对结构对象进行操作,无需求导和对函数连续性的限定,具有较好的并行性和全局寻优能力。采用概率化的寻优方法,不需要确定的规则就能自动获取和指导优化的搜索空间,自适应地调整搜索方向。
其中,选择、交叉和变异构成了遗传算法的遗传操作;编码方案、初始群体的设定、适应度函数的设计、遗传操作的设计、控制参数的设定5个要素组成遗传算法的核心。

编码方案

遗传算法常用的编码方案有排列编码、二进制编码和实值编码等等,考虑到编码方案要更好地对应国际象棋棋盘上8个皇后的排列,并且不涉及到浮点数层面的逼近问题,本程序采用排列编码。
用一元n维数组x[i]表示一个个体,i∈{1,2,3,4,5,6,7,8}。例如X[0]=1,X[7]=8,分别表示第一行第一列放置一个皇后,第八行第八列放置一个皇后。
为了方便遗传交叉操作,本程序采用允许编码数组内元素重复的编码方式。

适应度的计算

对于n皇后问题,我们可以把适应度抽象成不攻击度。对于一个皇后,若其余七个皇后不能俘获它,则它的不攻击度为7。所以总的遗传终止条件为最后一代的算子中产生了适应度为n*(n-1)/2的算子,总适应度除以2是为了消除重复计算。在八皇后问题中n=8,即循环终止条件为产生了适应度为28的遗传算子。
每个算子的初始适应度(不攻击度)设置为28,若此算子中的皇后行列有冲突,则适应度减一;若此算子中的皇后对角线上有冲突,即两个皇后之间行号相减的绝对值等于列号相减的绝对值,则适应度减一。

初始种群

本程序中的初始种群数量为4,对它们进行适应度排序,适应度最高的最为父代,次高的为第一个母代,再次的是第二个母代。父代与母代交叉产生两个子代。

选择算子

本程序采用竞技选择的方式,竞技规模同初始种群的规模,为4。将这4个算子按适应度排序,适应度高的成为下一代算子的亲代。

交叉算子

本程序采用顺序交叉的方式,随机产生一个交叉点,父代算子在交叉点之前的序列加上母代交叉点之后的序列产生一个子代,父代算子在交叉点之后的序列加上母代交叉点之前的序列产生第二个子代。
这种交叉方式有助于保持亲代中算子的相对位置,有助于遗传优良的基因信息。

变异算子

本程序为了降低交叉算子带来的重复率,采用交换变异的方法。随机产生两个交换点,将子代算子的相应变异点的元素相互交换,产生变异后的算子。

终止策略

产生适应度为28的算子,程序终止

程序的主要函数及其作用

初始化初始种群,生成互不相同的编码:
Initiate(a)
适应度的计算:
FitnessFunction(list)
竞技选择亲代:
ChooseParents(a,b,c,d)
交叉算子:
cross(parents)
变异算子:
mutation(children)

运行结果截图


Python源代码

import random
import matplotlib.pyplot
#初始化生成种群,种群容量为4,为了提高迭代效率,使初始群体的8个编码各不相同
def Initiate(a):while len(a)<8:b=random.randint(1,8)if not(b in a):a.append(b)return a#适应度的计算,即不攻击度。若一个皇后不攻击其余皇后,则其不攻击度为8-1=7。终止条件为8个皇后不攻击度之和为8*7/2(考虑重复计算)
def FitnessFunction(list):FitnessIndex=[28,28,28,28]for i in range(0, 4):for j in range(0, 7):for k in range(j+1, 8):if list[i][j]==list[i][k]:FitnessIndex[i] -= 1if list[i][j]-list[i][k] == j-k or list[i][j]-list[i][k] == k-j:FitnessIndex[i] -= 1fitness = {'a': FitnessIndex[0], 'b': FitnessIndex[1], 'c': FitnessIndex[2], 'd': FitnessIndex[3]}return fitness#选择亲代算子,这里使用竞争选择
def ChooseParents(a,b,c,d):stack=[]stack.append(a)stack.append(b)stack.append(c)stack.append(d)fitness = FitnessFunction(stack)sort=sorted(fitness.items(), key=lambda e : e[1], reverse=True)if sort[0][0] == 'a':firstfather = aelif sort[0][0] == 'b':firstfather = belif sort[0][0] == 'c':firstfather = celse:firstfather = dif sort[1][0] == 'a':firstmother = aelif sort[1][0] == 'b':firstmother = belif sort[1][0] == 'c':firstmother = celse:firstmother = dparents=[]parents.append(firstfather)parents.append(firstmother)parents.append(firstfather)if sort[0][0] == 'a':secmother = aelif sort[0][0] == 'b':secmother = belif sort[0][0] == 'c':secmother = celse:secmother = dparents.append(secmother)return parents#交叉算子,本程序采用顺序交叉
def cross(parents):children = []crosspoint=random.randint(1,7)firstfather,firstmother,secfather,secmother=parents[0],parents[1],parents[2],parents[3]ch1 = firstfather[0:crosspoint]ch1.extend(firstmother[crosspoint:])ch2 = firstmother[0:crosspoint]ch2.extend(firstfather[crosspoint:])ch3 = secfather[0:crosspoint]ch3.extend(secmother[crosspoint:])ch4 = secmother[0:crosspoint]ch4.extend(secfather[crosspoint:])children.append(ch1)children.append(ch2)children.append(ch3)children.append(ch4)return children#变异,这里采用交换变异
def mutation(children):muchildren=[]mtpoint1=random.randint(0,7)mtpoint2=random.randint(0,7)ch1, ch2, ch3, ch4 = children[0], children[1], children[2], children[3]ch1[mtpoint1], ch1[mtpoint2] = ch1[mtpoint2], ch1[mtpoint1]mtpoint1=random.randint(0,7)mtpoint2=random.randint(0,7)ch2[mtpoint1], ch2[mtpoint2] = ch2[mtpoint2], ch2[mtpoint1]mtpoint1=random.randint(0,7)mtpoint2=random.randint(0,7)ch3[mtpoint1], ch3[mtpoint2] = ch3[mtpoint2], ch3[mtpoint1]mtpoint1=random.randint(0,7)mtpoint2=random.randint(0,7)ch4[mtpoint1], ch4[mtpoint2] = ch4[mtpoint2], ch4[mtpoint1]muchildren.append(ch1)muchildren.append(ch2)muchildren.append(ch3)muchildren.append(ch4)return muchildrena,b,c,d=[],[],[],[]
Initiate(a)
Initiate(b)
Initiate(c)
Initiate(d)
parents=ChooseParents(a,b,c,d)
#为防止程序陷入死循环,设置最大繁衍次数
maxGenerations=100000
generations=0
for i in range(maxGenerations):cparents=cross(parents)mparents=mutation(cparents)generations+=1fitness = FitnessFunction(mparents)if fitness['a'] == 28 or fitness['b'] == 28 or fitness['c'] == 28 or fitness['d'] == 28:answer = []if fitness['a'] == 28:answer.append(mparents[0])if fitness['b'] == 28:answer.append(mparents[1])if fitness['c'] == 28:answer.append(mparents[2])if fitness['d'] == 28:answer.append(mparents[3])print("This answer is {0}".format(answer))print("Find if after {0} times".format(generations))#可行解的可视化for i in answer:y=[i.index(1)+0.5, i.index(2)+0.5, i.index(3)+0.5, i.index(4)+0.5, i.index(5)+0.5, i.index(6)+0.5, i.index(7)+0.5, i.index(8)+0.5]x=[0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5]matplotlib.pyplot.title("Using Genetic Algorithm to Solve 8-Queens' Problem")matplotlib.pyplot.axis([0,8,0,8])matplotlib.pyplot.grid()matplotlib.pyplot.plot(x, y, '*')matplotlib.pyplot.show()breakelse:parents=mparents
if maxGenerations==generations and answer==[]:print("Cannot find the answer")

遗传算法解决八皇后问题相关推荐

  1. 遗传算法解决八皇后问题(java源码)

    本文源码下载链接:https://download.csdn.net/download/goulvjiang3176/11221063 另有贪心算法解决八皇后问题的源码下载链接:https://dow ...

  2. 八皇后问题遗传算法c语言,遗传算法解决八皇后问题

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 八皇后问题描述 19 世纪著名的数学家 Gauss 在 1850 年提出八皇后问题后, 该问题成为各类语言程序设计的经典 ...

  3. 用遗传算法解决八皇后问题

    一.问题描述 八皇后问题的目标是在国际象棋棋盘中放置8个皇后,使得任何一个皇后都不会攻击到其他任一皇后.(皇后可以攻击和它在同一行,同一列或者同一对角线的任何棋子) 二.编程语言及算法 编程语言:py ...

  4. 使用遗传算法解决N皇后问题

    使用遗传算法解决N皇后问题 N皇后问题 解的表示 问题的表示 遗传算法解决N皇后问题 常量及遗传算子定义 使用精英主义策略 遗传流程 结果 N皇后问题 经典的N皇后问题最初被称为八皇后拼图,起源于国际 ...

  5. 遗传算法求解八皇后问题—matlab

    目录 题目要求 设计思路 1.染色体编码 2.适应度函数 3.选择算子 4.交叉算子 5.变异算子 6.精英替换 运行结果 源程序 题目要求 在8*8的国际象棋棋盘上放置了八个皇后,要求没有一个皇后能 ...

  6. Python:各种算法解决八皇后问题

    文章目录 1 八皇后问题 2 解决方案 3 性能对比 4 总结 1 八皇后问题 问题:有一个8乘8的棋盘,现在要将八个皇后放到棋盘上,满足:对于每一个皇后,在自己所在的行.列.两个对角线都没有其他皇后 ...

  7. Python解决八皇后问题

    Python解决八皇后问题 参考文章: (1)Python解决八皇后问题 (2)https://www.cnblogs.com/littleseven/p/5362791.html 备忘一下.

  8. 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案

    回溯算法解决八皇后 4-皇后问题 (4 - Queen's problem) In 4- queens problem, we have 4 queens to be placed on a 4*4 ...

  9. 回溯法在解决八皇后问题中的应用

    回溯法:有这样一类题目,它们要求在相对问题的输入规模按照指数速度增长(或者更快)的域中,找出一个具有指定特性的元素.例如:在图顶点的所有排列中求一个哈密顿回路,在背包问题的一个实例中求其中最有价值的物 ...

最新文章

  1. 单林多域群集环境中将Exchange 2003迁移到Exchange 2010系列之五
  2. 科学计算机程序 字表处理软件都是,计算机应用基础知识_计算机应用基础试题及答案【最新资料】.doc...
  3. php微信分享时好时坏,手机端微信分享前几天都是正常的今天发现分享出去就不正常了设置,迅睿CMS,CodeIgniter技术文档,PHP开发文档,迅睿CMS框架官方教程...
  4. 在Tomcat中部署seam工程
  5. Netflix: 从 Batch ETL 到 Stream Processing 的转型之路
  6. mysql多表查询详解_MySQL多表查询详解上
  7. Java之IO操作总结
  8. 枚举函数enumerate
  9. 【Maven】mvn install 本地jar 或者 项目 添加到maven仓库中
  10. java test20006_Java单例7种测试实践
  11. 一篇非常 Nice 的 UmiJS 教程
  12. 系统运维数据存储知识-系统数据误删除恢复
  13. ai人工智能_人工智能能否赢得奥运
  14. 使用telnet和ssh登录linux
  15. c语言打开文件报错 13,求帮忙看一段打开文件的代码~~真心无力了
  16. 软件加入使用时间_【安卓】换了这么多影视软件,还是这个老牌站点最靠谱
  17. 2013年第四届C B组蓝桥杯省赛真题
  18. gcs服务 oracle,gcs resource
  19. 用手机模拟加密门禁卡【不用电脑】
  20. 腾讯打击QQ宠物外挂颁布Q宠打工新规定(转)

热门文章

  1. 「算法与数据结构」时间与空间复杂度
  2. 【闲侃】解析行业专家咨询
  3. python罗马数字转换_Python练习【3】【罗马数字转换/查找公共前缀】
  4. 算法日记(四)之回文字符串
  5. TCP与UDP首部及字段
  6. 【推荐】有哪些没什么卵用,又很沙雕无聊的网站,沙雕的快乐!你不懂
  7. 能动的电脑配件「GitHub 热点速览 v.22.11」
  8. FLUENT精典案例#320-管壳式换热器仿真
  9. 阿里短信服务 php实例,阿里大鱼发送sms 短信 php demo示例
  10. 3.用swi指令验证异常处理流程(四大步三小步)