遗传算法与深度学习实战(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框架初体验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/405323.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub的未来:在微软领导下保持独立与AI发展的平衡

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

20240821 每日AI必读资讯

&#x1f3ae;《黑神话&#xff1a;悟空》震撼上线&#xff0c;英伟达AI技术立功&#xff01; - 中国游戏史上的奇迹&#xff1a;《黑神话&#xff1a;悟空》预售销售额达3.9亿元&#xff0c;刷新国产游戏预售纪录。 - 游戏美学效果惊人&#xff1a;孙悟空形象深入人心&#…

你知道手机零部件尺寸检测的重要性吗?

手机零部件作为手机制造行业的基础&#xff0c;其品质的优劣直接关系到行业的发展&#xff0c;所以加强手机精密零部件尺寸检测非常重要。如今&#xff0c;手机零部件变得更加精细&#xff0c;对质量的要求也在不断提高&#xff0c;随着生产规模逐渐扩大&#xff0c;传统的检测…

网络安全防渗透实战指南【策略、代码与最佳实践】

网络安全防渗透实战指南【策略、代码与最佳实践】 引言 随着互联网的迅猛发展&#xff0c;网络安全问题日益突出。渗透攻击作为网络攻击的一种常见手段&#xff0c;给企业和个人带来了巨大的威胁和损失。因此&#xff0c;如何有效防止渗透攻击成为网络安全领域的重要课题。本…

【python报错解决】ImportError: DLL load failed while importing win32gui: 找不到指定的程序

在 Python 中安装 pywin32 库 pip install pywin32安装完成后找到自己的 Python 根目录&#xff0c;在该目录下打开命令行。 在命令行中输入&#xff1a; python.exe Scripts/pywin32_postinstall.py -install执行后显示以下信息&#xff0c;即问题解决。 Parsed argumen…

订单到期关闭如何实现?

目录 一、被动关闭 二、定时任务 三、JDK自带的DelayQueue 四、Netty的时间轮 五、Kafka的时间轮 六、RocketMQ延迟消息 七、RabbitMQ死信队列 八、RabbitMQ插件 九、Redis过期监听 十、Redis的Zset 十一、Redisson 在电商、支付等系统中&#xff0c;一般都是先创建…

单因子年化23.7%,基于deap的因子挖掘,我改进了fitness和metrics方案(附python代码和数据)

原创文章第626篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 我们目前投入使用的因子挖掘&#xff0c;基于两个框架&#xff0c;deap和gplearn&#xff0c;deap做一点点改动&#xff0c;就可以完美应用于多标的截面因子挖掘。而gplearn如果要支…

C#使用Modbus TCP通讯PLC,实现读写寄存器

一、创建一个Moudbus类&#xff0c;引入NModbus和Modbus这两个包 #region ModbusTCPpublic class NmodbusTcpHelper{// 静态成员变量&#xff0c;用于存储TcpClient实例private static TcpClient tcpClient null;// 静态成员变量&#xff0c;用于存储ModbusIpMaster实例privat…

案例 | 生产制造中的直线度测量

关键词&#xff1a;直线度测量仪,直线度 生产中不仅需要评价产品的外观尺寸&#xff0c;还需要对直线度&#xff08;弯曲度&#xff09;等尺寸加以测量。作为一种评价产品直度的重要指标——直线度&#xff0c;能够对其进行检测是非常重要的。 关于直线度&#xff0c;对于一些弯…

数字人的形象克隆与语音克隆是伪需求

形象克隆与语音克隆技术&#xff0c;在当前的环境上已经可以成熟的实现&#xff0c;但真的解决了痛点问题吗&#xff1f; 普通人或者一般的公司克隆自己内部人的形象有必要吗&#xff1f;对外界而言&#xff0c;克隆的形象与虚拟的形象并无二致&#xff0c;本身并没有什么知名…

Spring Boot 集成 swagger 3.0 指南

Spring Boot 集成 swagger 3.0 指南 一、Swagger介绍1.springfox-swagger 22.SpringFox 3.0.0 发布 二、Spring Boot 集成 swagger 3.01. 添加Maven依赖2. 创建配置类配置Swagger2.1 创建SwaggerConfig 配置类2.1 创建TestInfoConfig信息配置类 3. 在你的Controller上添加swagg…

《黑神话:悟空》的发布是否能打开元宇宙游戏世界的门

四年漫长等待&#xff0c;8月20日&#xff0c;国产3A游戏巨制《黑神话&#xff1a;悟空》正式上线并彻底引爆全球市场。这背后不仅是中国游戏史的里程碑&#xff0c;也将为元宇宙的未来夯实地基&#xff01; 游戏上线后&#xff0c;热度持续飙升&#xff0c;成为了社交媒体和游…

while循环中OLED显示中断中的数据不正确

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

HDRP管线下的开放世界游戏与跨平台优化,《仙剑世界》万字分享

《仙剑世界》作为仙剑 IP 系列的最新⻓篇⼒作&#xff0c;从故事和剧情上延续了仙剑的精髓。在仙剑 33 年的世界观下&#xff0c;《仙剑世界》打造出了⼀个由浪漫唯美的江南全景、磅礴恢弘的蜀⼭、神秘苗疆等区域构成的 384 平⽅公⾥完整的⽆缝开放⼤世界。以东⽅题材为起点&am…

【Deep Live Cam】只需一张图片,就可实现视频的人脸替换。

Deep Live Cam 运用尖端AI技术&#xff0c;将实时换脸和视频深伪推向新的境界。只需一张图片&#xff0c;即可实现高质量的人脸替换。 用户在X上对Deep Live Cam的评价。 如何安装它&#xff1f; 1、环境 python (推荐 3.10 ) pip git ffmpeg https://www.youtube.com…

C\C++ Sqlite3使用详解

C\C++ Sqlite3使用详解 一、源码下载二、sqlite3接口说明C++2.1 项目创建以及sqlite3使用2.1 连接数据库2.2 sqlite创建表2.2.1 示例代码2.2.2 注意事项2.3 sqlite插入数据2.3.1 示例代码2.3.2 注意事项2.4 sqlite数据删除2.5 sqlite数据查询一、源码下载 下载地址: https://…

在选择或推荐数据恢复软件之前,您如何测试和审查它?

数据恢复软件可以帮助您从各种存储设备中检索丢失或删除的文件&#xff0c;例如硬盘驱动器&#xff0c;USB闪存驱动器&#xff0c;存储卡或智能手机。但是&#xff0c;并非所有数据恢复软件都是一样的&#xff0c;根据您的情况和需求&#xff0c;有些软件的性能可能比其他软件更…

目标检测 | yolov9 原理和介绍

相关系列&#xff1a; 目标检测 | yolov1 原理和介绍 目标检测 | yolov2/yolo9000 原理和介绍 目标检测 | yolov3 原理和介绍 目标检测 | yolov4 原理和介绍 目标检测 | yolov5 原理和介绍 目标检测 | yolov6 原理和介绍 目标检测 | yolov7 原理和介绍 目标检测 | yolov8 原理和…

笨鸟先飞(疯狂的小鸟)小游戏自制分享

《Flappy Bird》是一款由越南独立游戏开发者阮哈东&#xff08;Dong Nguyen&#xff09;制作并发布的移动端小游戏。该游戏最初于2013年上线&#xff0c;在2014年初迅速走红&#xff0c;成为全球范围内的热门现象。 游戏的玩法非常简单&#xff0c;玩家只需通过点击屏幕来控制…

【算法专题】双指针算法

个人主页&#xff1a;CSDN_小八哥向前冲 所属专栏&#xff1a;基础算法 目录 移动零 复写零 快乐数 盛最多水的容器 有效三角形的个数 和为s的两个数 三数之和 四数之和 移动零 题目&#xff1a;【LeetCode】移动零 思路&#xff1a; 这里其实就是一个数组分块的问题&…