当前位置: 首页 > news >正文

遗传算法与深度学习实战(7)——使用遗传算法解决N皇后问题

遗传算法与深度学习实战(7)——使用遗传算法解决N皇后问题

    • 0. 前言
    • 1. N 皇后问题
    • 2. 解的表示
    • 3. 遗传算法解决 N 皇后问题
    • 小结
    • 系列链接

0. 前言

进化算法 (Evolutionary Algorithm, EA) 和遗传算法 (Genetic Algorithms, GA) 已成功解决了许多复杂的设计和布局问题,部分原因是它们采用了受控随机元素的搜索。这通常使得使用 EAGA 设计的系统能够超越我们的理解进行创新。在本节中,我们将解决一个经典的设计和布局问题:N 皇后问题,这个问题使用大小为 N 的典型棋盘,经典的国际象棋棋盘大小为 8 (即 8×8 )。我们的目标是在棋盘上放置 N 个皇后棋子,使得没有一个棋子可以在不移动的情况下俘获另一个棋子。

1. N 皇后问题

在国际象棋中,皇后棋子是最强大的,可以沿着任何方向和距离移动。通常,每个玩家只有一个皇后棋子,但有一条特殊规则,允许玩家在将兵移动到对手的底线时加冕更多的皇后,皇后游戏的前提是玩家已经加冕了多个皇后(虽然这种情况在真实的比赛中可能永远不会发生,因为当玩家的国王棋子被俘获时,比赛就将结束)。
经典的 N 皇后问题最初被称为八皇后拼图,起源于国际象棋。任务是将八名皇后放置在棋盘上,而且他们中的任何两个都不互相构成威胁。换句话说,没有两个皇后可以在同一行、同一列或同一对角线。概括而言,N 皇后问题使用 N × N 的棋盘和 N (其中 N>3 )个皇后。对于原始的八皇后情形,有 92 个解,消除对称解,则有 12 个唯一解。
使用排列组合,将 8 个皇后放置在 8 × 8 棋盘上的所有可能方式有 4,426,165,368 种。但是,如果通过确保不会在同一行或同一列上放置两个皇后的方式创建候选解决方案,则可能的组合数量将减少到 8 ! = 40320 8!=40320 8!=40320 个。

2. 解的表示

在解决 N 皇后问题时,利用以下前提条件:每行恰好容纳一个皇后,同时没有两个皇后共享同一列。这意味着可以将候选解表示为有序的整数列表或索引列表,每个索引表示皇后之一占据当前行的列数。例如,在 4×4 棋盘上的四皇后问题中,具有以下索引列表:

(3, 2, 0, 1)

表示(索引从 0 开始计数):

  1. 在第一行中,皇后放置在第四列中
  2. 在第二行中,皇后放置在第三列中
  3. 在第三行中,皇后放置在第一列中
  4. 在第四行中,皇后放置在第二列中

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

(1) 首先,导入所需库:

import random
import numpy as npfrom deap import algorithms
from deap import base
from deap import creator
from deap import toolsimport matplotlib.pyplot as plt
from matplotlib.pyplot import figure

(2) 查看国际象棋棋盘上的皇后的初始位置。由于皇后棋子可以沿着任何方向和距离移动,因此这个游戏被限制在皇后的最大数量等于棋盘大小的情况下。在本节中,我们使用 8 个棋子,接下来,绘制皇后的初始位置:

board_size = number_of_queens = 8chessboard = np.zeros((board_size,board_size))
chessboard[1::2,0::2] = 1
chessboard[0::2,1::2] = 1figure(figsize=(6, 6), dpi=80)
plt.imshow(chessboard, cmap='binary')for _ in range(number_of_queens):i, j = np.random.randint(0, board_size, 2)plt.text(i, j, '♕', fontsize=30, ha='center', va='center', color='black' if (i - j) % 2 == 0 else 'white')
plt.show()

下图显示了渲染后的棋盘和皇后棋子的移动方式。可以看到,选定的棋子可以立即俘获其他几个棋子,我们的目标是将所有皇后放置在没有一个棋子可以俘获另一个棋子的位置。

棋盘示例

(3) 皇后游戏的适应度评估函数 evalNQueens 通过采用一种简便方法来评估个体的适应度,而不是迭代运行每一种放置方式。该函数假设只能在一行或一列上放置一个皇后。因此,我们只需要评估皇后是否位于同一对角线,简化了适应度函数代码:

creator.create("FitnessMax", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)def evalNQueens(individual):size = len(individual)#Count the number of conflicts with other queens.#The conflicts can only be diagonal, count on each diagonal lineleft_diagonal = [0] * (2*size-1)right_diagonal = [0] * (2*size-1)#Sum the number of queens on each diagonal:for i in range(size):left_diagonal[i+individual[i]] += 1right_diagonal[size-1-i+individual[i]] += 1#Count the number of non-conflicts on each diagonalsum_ = 0for i in range(2*size-1):if left_diagonal[i] > 1:sum_ += left_diagonal[i] - 1if right_diagonal[i] > 1:sum_ += right_diagonal[i] - 1    return sum_,

(4) 在适应度评估函数之后,编写 eaSimple 函数,它是标准的 DEAPalgorithms.eaSimple 函数的副本。该函数与 OneMax 一节中使用的函数几乎完全相同,可以自定义输出表现最佳的个体,并测试是否可以提前停止。在以下代码中,比较了个体适应度与最大适应度,如果达到了最大适应度,进化过程将会提前停止:

toolbox = base.Toolbox()
toolbox.register("permutation", random.sample, range(number_of_queens), number_of_queens)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.permutation)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)toolbox.register("evaluate", evalNQueens)
toolbox.register("mate", tools.cxPartialyMatched)
toolbox.register("mutate", tools.mutShuffleIndexes, indpb=2.0/number_of_queens)
toolbox.register("select", tools.selTournament, tournsize=3)def plot_board(individual):  plt.imshow(chessboard, cmap='binary')for i in range(number_of_queens):               plt.text(i, individual[i], '♕', fontsize=20, ha='center', va='center', color='black' if (i - individual[i]) % 2 == 0 else 'white')
plt.show()def eaSimple(population, toolbox, cxpb, mutpb, ngen, max, stats=None, halloffame=None, ):  logbook = tools.Logbook()logbook.header = ['gen', 'nevals'] + (stats.fields if stats else [])# Evaluate the individuals with an invalid fitnessinvalid_ind = [ind for ind in population if not ind.fitness.valid]fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)for ind, fit in zip(invalid_ind, fitnesses):ind.fitness.values = fitif halloffame is not None:halloffame.update(population)record = stats.compile(population) if stats else {}logbook.record(gen=0, nevals=len(invalid_ind), **record)    print(logbook.stream)done = False# Begin the generational processfor gen in range(1, ngen + 1):if done: return# Select the next generation individualsoffspring = toolbox.select(population, len(population))offspring = [toolbox.clone(ind) for ind in offspring]# Apply crossover and mutation on the offspringfor i in range(1, len(offspring), 2):if random.random() < cxpb:offspring[i - 1], offspring[i] = toolbox.mate(offspring[i - 1],offspring[i])del offspring[i - 1].fitness.values, offspring[i].fitness.valuesfor i in range(len(offspring)):if random.random() < mutpb:offspring[i], = toolbox.mutate(offspring[i])del offspring[i].fitness.values# Evaluate the individuals with an invalid fitnessinvalid_ind = [ind for ind in offspring if not ind.fitness.valid]fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)for ind, fit in zip(invalid_ind, fitnesses):ind.fitness.values = fit            if fit[0] >= max:print("Solved")done = True# Update the hall of fame with the generated individualsif halloffame is not None:halloffame.update(offspring)            plot_board(halloffame[0])            # Replace the current population by the offspringpopulation[:] = offspring# Append the current generation statistics to the logbookrecord = stats.compile(population) if stats else {}logbook.record(gen=gen, nevals=len(invalid_ind), **record)print(logbook.stream)

(5) 最后,执行种群的演化。首先创建种群和一个用于存储最佳个体的 HallOfFame 容器。然后,注册各种统计数据,最后调用 eaSimple 函数演化种群。在以下代码中,将 max = number_of_queens 作为输入来控制个体达到最大适应度时提前停止种群的进化:

pop = toolbox.population(n=100)
hof = tools.HallOfFame(1)
stats = tools.Statistics(lambda ind: ind.fitness.values)
stats.register("Avg", np.mean)
stats.register("Std", np.std)
stats.register("Min", np.min)
stats.register("Max", np.max)eaSimple(pop, toolbox, cxpb=0.5, mutpb=0.2, ngen=100, max = number_of_queens,stats=stats ,halloffame=hof)

最后,查看进化过程的输出,并查看算法演化解决方案的效果如何。从输出中可以看出,演化过程能够提前停止(在第 5 代生成一个可行的解决方案)。重新查看解决方案,确认每个皇后无法互相攻击。可以增加棋盘大小和皇后数量(如增加到 16 或更大的值),这可能需要同时增加种群大小和演化代数的数量。

运行结果

可以通过完成以下问题进一步理解使用 DEAP 库实现遗传算法的流程:

  • 将要演化的种群大小更改为其他值,然后重新运行,观察较大的种群对演化的影响
  • 更改交叉和突变率,然后重新运行,观察能否在更少的代数中解决问题
  • 增加或减少锦标赛的大小,然后重新运行,观察锦标赛大小对演化的影响

小结

N 皇后问题是一个经典的组合问题,要求在一个( N x N )的棋盘上放置 N 个皇后,使得它们互相不能攻击到对方。遗传算法是解决 N 皇后问题的一种有效方法,本节中,我们使用 DEAP 库实现遗传算法解决了 N 皇后问题。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法详解与实现
遗传算法与深度学习实战(5)——遗传算法框架DEAP
遗传算法与深度学习实战(6)——DEAP框架初体验

相关文章:

遗传算法与深度学习实战(7)——使用遗传算法解决N皇后问题

遗传算法与深度学习实战&#xff08;7&#xff09;——使用遗传算法解决N皇后问题 0. 前言1. N 皇后问题2. 解的表示3. 遗传算法解决 N 皇后问题小结系列链接 0. 前言 进化算法 (Evolutionary Algorithm, EA) 和遗传算法 (Genetic Algorithms, GA) 已成功解决了许多复杂的设计…...

R语言:如何安装包“linkET”

自己在R语言中安装包“linkET”时报错不存在叫‘linket’这个名字的程辑包 尝试了install.packages("linkET")和BiocManager::install("linkET")两种安装办法都不行 >install.packages("linkET") WARNING: Rtools is required to build R pa…...

JSON, YAML, XML, CSV交互可视化

1、jsoncrack https://jsoncrack.com/editor...

Android UI:PopupWindow:源码分析:设置WindowManager.LayoutParams中的各种参数

文章目录 设置flags是否包含某些flag设置gravity设置type设置softInputMode设置windowAnimations设置width/height设置token 在WindowManager.addView之前设置在WindowManager.addView之后,可通过i熬夜难过update方法设置设置format设置flags是否包含某些flag 1666 …...

MySQL:从入门到放弃

基础查询 MySQL&#xff1a;基础查询 Mybatis&#xff1a;基础巩固-DDL 项目实战 MySQL&#xff1a;按照日期分组查询 查询开始时间与结束时间在指定的日期范围之内&#xff0c;并且结束时间可以为NULL的数据...

C++OpenGL三维显示镜面反射光线漫反射实例

程序示例精选 COpenGL三维显示镜面反射光线漫反射实例 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《COpenGL三维显示镜面反射光线漫反射实例》编写代码&#xff0c;代码整洁&#xff0c;…...

【前端面试】从npm 升级到 pnpm的总结

pnpm优势 pnpm 和 npm 在性能上存在一些明显的差异,这也是一些开发者选择从 npm 切换到 pnpm 的原因。以下是一些关键的差异和原因: 1. 速度: pnpm 比 npm 快了近 2 倍,它通过优化的依赖管理,显著提高了安装速度 。 2. 磁盘空间效率: pnpm 使用基于内容寻址的文件系…...

同步外网YUM源-3

在企业实际应用场景中,仅仅靠光盘里面的RPM软件包是不能满足需要,我们可以把外网的YUM源中的所有软件包同步至本地,可以完善本地YUM源的软件包数量及完整性。 获取外网YUM源软件常见方法包括Rsync、Wget、Reposync,三种同步方法的区别Rsync方式需要外网YUM源支持RSYNC协议…...

Linux的oracle数据库导入其他用户导出的数据库文件

如果用户使用的是expdp的命令&#xff0c;导入就要使用impdp命令&#xff0c;本文以impdp为例进行介绍 1、查看当前创建的所有dmp导出目录 select * from dba_directories 2、为创建的目录赋权限 比如咱们将数据库导入到test用户&#xff0c; grant read,write on directo…...

FLUX.1 文生图模型微调指南

FLUX.1 是 Black Forest Labs 今年夏天发布的文本转图像模型系列。FLUX.1 模型为开源图像生成模型树立了新标准&#xff1a;它们可以生成逼真的手、清晰的文本&#xff0c;甚至可以生成搞笑表情包这样异常困难的任务。 现在&#xff0c;你可以使用 Ostris 的 Replicate 上的 A…...

JavaWeb基础:HTTP协议与Tomcat服务器

目录 1. HTTP协议简介 示例代码&#xff1a;创建HTTP GET请求 2. Tomcat服务器介绍 Tomcat的基本操作 示例代码&#xff1a;部署简单Servlet 3. 使用Servlet处理请求 示例代码&#xff1a;处理POST请求 在现代网络开发中&#xff0c;理解HTTP协议和如何使用Tomcat作为服…...

python井字棋游戏设计与实现

python实现井字棋游戏 游戏规则&#xff0c;有三个井字棋盘&#xff0c;看谁连成的直线棋盘多谁就获胜 棋盘的展现形式为 棋盘号ABC和位置数字1-9 输入A1 代表在A棋盘1号位数下棋 效果图如下 部分源码如下&#xff1a; 卫星工纵浩 白龙码程序设计&#xff0c;点 代码获取 …...

据说是可以和 Windows 一拼的 5个 Linux 发行版

现如今有数以千计的 Linux 发行版可供您使用&#xff0c;然而人们却无法选择一个完美的操作系统来替代 Windows。 使用 Windows 时&#xff0c;傻瓜都能操作自如&#xff0c;同样的方法却不适用于 Linux。在这里&#xff0c;您必须具备操作和使用操作系统的基本知识。因此人们经…...

PHP 常用函数

1. ksort&#xff08;&#xff09; 如果你有一个数组 array&#xff08;[11] > array(XX), [6] > array(YYY)&#xff09;&#xff0c;你想要返回按照key重新排序&#xff0c;并不改变键和值之间的关联&#xff0c;处理之后的结果为 array&#xff08;[6] > array(YY…...

如何将MySQL迁移到TiDB,完成无缝业务切换?

当 MySQL 数据库的单表数据量达到了亿级&#xff0c;会发生什么&#xff1f; 这个现象表示公司的业务上了一个台阶&#xff0c;随着数据量的增加&#xff0c;公司规模也进一步扩大了&#xff0c;是非常喜人的一个改变 &#xff0c;然而随之而来的其他变化&#xff0c;就没那么…...

【嵌入式烧录刷写文件】-2.10-为一个Intel Hex文件计算校验和Checksum

案例背景(共6页精讲): 有如下一段Intel Hex文件&#xff0c;为其创建Checksum校验和&#xff1a;CRC16&#xff0c;CRC32(CVN)&#xff0c;SHA-256 Hash算法…, 将Checksum Value填充到指定地址。 :2091000058595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767…...

整体思想以及取模

前言&#xff1a;一开始由于失误&#xff0c;误以为分数相加取模不能&#xff0c;但是其实是可以取模的 这个题目如果按照一般方法&#xff0c;到达每个节点再进行概率统计&#xff0c;但是不知道为什么只过了百分之十五的测试集 题目地址 附上没过关的代码 #include<bits…...

RabbitMQ 消息可靠保障

RabbitMQ 消息可靠保障 消息的可靠性保证生产者重连生产者确认解决思路A-确认机制解决思路B-备份交换机 MQ 服务器宕机导致消息丢失消费端消息的可靠性保障 消费端限流给消息生成唯一id 消息的可靠性保证 实际项目中 MQ 的流程一般是&#xff1a;生产端把消息路由到交换机&…...

Redis 作为 PHP 的会话存储

使用 Redis 作为 PHP 的会话存储&#xff0c;可以实现多个服务器之间的会话共享&#xff0c;提高会话管理的效率&#xff0c;特别是在分布式系统中。这种方法将会话数据存储在 Redis 中&#xff0c;而不是使用默认的文件系统&#xff0c;从而使多个服务器可以访问相同的会话数据…...

基于伏图的数字心脏模拟仿真APP应用介绍

一、背景介绍 心脏是保证人体正常运转最重要的动力&#xff0c;人体内的血液循环通过心血管运输到各个部位&#xff0c;因此&#xff0c;心血管系统的稳定是人体健康的关键。心血管内科领域极具专业性&#xff0c;其理论研究与技术发展日新月异&#xff0c;心血管疾病患者往往…...

智云-一个抓取web流量的轻量级蜜罐docker一键启动

智云-一个抓取web流量的轻量级蜜罐docker安装教程 github地址 https://github.com/xiaoxiaoranxxx/POT-ZHIYUN docker快速启动(v1.4) git clone https://github.com/xiaoxiaoranxxx/POT-ZHIYUN.git cd POT-ZHIYUN docker-compose up -d默认映射到80和8080端口 mysql不对外开放…...

原生HTML5、CSS、JavaScript实现简易网易云音乐播放

1.效果图 2.源码 1.index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>网易云音乐</title><link rel"stylesheet" href"../CSS/index.css"> </head>…...

网上商城小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商品信息管理&#xff0c;商品类型管理&#xff0c;活动专区管理&#xff0c;新品上架管理&#xff0c;用户评价管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包…...

微分方程(Blanchard Differential Equations 4th)中文版Section2.2

动力系统的几何分析 捕食者-猎物系统的向量场 在第2.1节中&#xff0c;我们展示了两个不同捕食者-猎物系统的 R ( t ) R(t) R(t) 和 F ( t ) F(t) F(t) 图形&#xff0c;但没有描述我们是如何生成这些图形的。我们将在第2.5节中解决这个问题&#xff0c;采用欧拉方法推广到…...

Swift 环境搭建

Swift 环境搭建 Swift 是由苹果公司开发的一种强类型编程语言&#xff0c;用于iOS、macOS、watchOS和tvOS应用程序的开发。搭建Swift开发环境是开始使用Swift进行编程的第一步。本文将详细介绍如何在不同的操作系统上搭建Swift开发环境。 在macOS上搭建Swift环境 系统要求 …...

科技与出版

科技与出版 ISSN: 1005-0590 CN: 11-3209/G3 常设栏目&#xff1a;特别策划、产业观察、融媒之光、编辑实务、营销方略、学术探索、创作空间等。 稿件要求 (1)来稿应有创新性&#xff1b;立论科学&#xff0c;主题明确&#xff0c;推理严谨&#xff1b;词语准确&#xff0c;…...

5年前端面试之路

作者&#xff1a;星空海绵 顺便吆喝一声&#xff0c;技术大厂&#xff0c;内推捞人&#xff0c;前/后端or测试←感兴趣 --加班偶尔较多&#xff0c;但周末加班两倍工资。 --15-35K&#xff0c;工资一线城市属于一般&#xff0c;但二线城市很可以。 前言 由于公司要进行&#xf…...

产品运营(一)--产品运营是什么?

1.运营是什么&#xff1f; 通过一系列穿针引线式的行为和资源投入&#xff0c;让一件事能持续良性运转。 运营面向的主体不同&#xff0c;使用的运营手段也是不同的。作用&#xff1a;赋予产品闪耀的光芒。距离用户最近的人&#xff08;体验用户&#xff0c;成为用户?demo:k…...

学习大数据DAY41 Hive 分区表创建

目录 分区表 分区表应用场景 oracle 分区表种类 oracle 分区-范围分区 oracle 分区-列表分区 oracle 分区-散列分区 oracle 分区-组合分区 oracle 分区-分区表操作 hive 分区-创建分区表 hive 分区-分区表操作 hive 分区-动态分区表配置 上机练习 分区表 分区是将一…...

【三维目标检测模型】ImVoteNet

【版权声明】本文为博主原创文章&#xff0c;未经博主允许严禁转载&#xff0c;我们会定期进行侵权检索。 参考书籍&#xff1a;《人工智能点云处理及深度学习算法》 本文为专栏《Python三维点云实战宝典》系列文章&#xff0c;专栏介绍地址“https://blog.csdn.net/suiyin…...