爬山法实现 八皇后问题 (Python 实现)

article/2025/11/10 11:40:44

本文主要简单阐述爬山法的基本算法思想,并给出用此算法实现八皇后问题详细过程

最基本的爬上搜索算法表示:(节选自《人工智能》第二版):

function HILL-CLIMBING(problem) return a state thate is a locak maximum
    inputs: problem
    local variables: current, a node 
                         neighbor,a node
    current = MakeNode(INITAL-STATE(problem));
    loop do
        neighbor = a highest-valued successor of current ;
        if VALUE[neighbor] <= VALUE[current] then return STATE[current];
        current = neighbor ;

算法特点:

        爬山法是一个向值增加的方向持续移动的简单循环过程--类似于登高,它将会在到达一个“峰顶”时终止,此时相邻状态中没有比它更高的值。这个算法不会维护搜索树,因此当前节点的数据结构只需要记录当前状态和它的目标函数值,它不会前瞻与当前状态不直接相邻的那些状态的值。这里更高的值是根据具体的应用场景来定的,准确的说是更接近目标状态的值,由我们设置的启发式函数来决定哪个值更好,比如我们求解八皇后问题更高的值就是当前格局中皇后冲突对数最少的情况


算法局限性:

      爬山法属于一种局部的贪婪搜索方法,当它在搜索过程中遇到了局部最大值就很难继续向下搜索了,局部极大值是一个比它的每个邻居状态都高得到峰顶,但是比全局最大值(我们要到达的最终状态)要低,爬山法算法到达局部极大值附近就会被拉向峰顶,然后卡在局部极大值处无处可走。因此产生了爬山法的变种如随机爬山法及其变种如随机爬山法,随机重新开始的爬山法,模拟退火搜索能够非常有效的解决N皇后问题。

求解八皇后问题:

  1. #-*- coding: utf-8 -*-
  2. import random
  3. #函数一:参数为当前棋盘布局状态,根据布局判断当前八皇后布局存在冲突的皇后对数
  4. def get_numof_conflict(status):
  5. num = 0
  6. for i in range(len(status)):
  7. for j in range(i + 1,len(status)):
  8. if status[i] == status[j]:
  9. num += 1
  10. offset = j - i
  11. if abs(status[i]-status[j]) == offset:
  12. num += 1
  13. return num
  14. #函数二:参数为当前棋盘布局状态,利用爬山法思想选择邻居状态最好的布局并返回
  15. def hill_climbing(status):
  16. convert = {}
  17. length = len(status)
  18. for col in range(length):
  19. best_move = status[col]
  20. for row in range(length):
  21. if status[col] == row:
  22. continue
  23. status_copy = list(status)
  24. status_copy[col] = row
  25. convert[(col,row)] = get_numof_conflict(status_copy)
  26. answers = [] #最佳后继集合
  27. conflict_now = get_numof_conflict(status) #当前皇后冲突对数
  28. #遍历存储所有可能后继的字典,找出最佳后继
  29. for key,value in convert.iteritems():
  30. if value < conflict_now:
  31. conflict_now = value
  32. for key,value in convert.iteritems():
  33. if value == conflict_now:
  34. answers.append(key)
  35. #如果最佳后继集合元素大于一个 随机选择一个
  36. if len(answers) > 0:
  37. x = random.randint(0,len(answers)-1)
  38. col = answers[x][0]
  39. row = answers[x][1]
  40. status[col] = row
  41. return status
  42. #函数三:求得八皇后满足冲突数为0的一个解,循环输出每一步的后继集合 直到不存在冲>突为止
  43. def Queens():
  44. status = [0,1,2,3,4,5,6,7] #初始状态所有皇后都在对角线
  45. #当存在冲突的个数大于0时 循环求解最佳后继 直到找到八皇后解
  46. while get_numof_conflict(status) > 0:
  47. status = hill_climbing(status)
  48. print status
  49. print get_numof_conflict(status)
  50. print "the answer is"
  51. print
  52. print status
  53. if __name__ == '__main__':
  54. Queens()
代码说明 :

(1)启发式耗散函数 get_numof_conflict求出可以彼此攻击2的皇后对的数  hill_climbing是算法中爬山过程的实现,convert字典中存储的键是所有可能后继状态,值是此状态对应的皇后冲突对数,后面通过遍历来找到最佳后继。爬山法算法通常在最佳后继集合中随机选择一个进行扩展,如果这样的后继多于一个的话

(2)  棋盘的排列用列表 status 表示, 依次表示第一列第二列到第n列的摆放位置。 如列表[0,2,1] 表示3*3矩阵第一列皇后放在最下面一格,第二列放在最上面一格,第三列放在中间一格

(3) 运行结果说明:初始状态每个皇后都在次对角线上 每次运行程序将输出求解一个八皇后正确解的爬山法实现过程 ,依次输出求解过程每一个最佳选择的邻居状态和其存在的皇后冲突对数,可以看出在求解过程中 不断爬山的过程--每进行一步都达到一个更好的格局,冲突次数更少,最后一行显示的是八皇后的一个正确解 冲突数为 0

运行截图



本文主要简单阐述爬山法的基本算法思想,并给出用此算法实现八皇后问题详细过程

最基本的爬上搜索算法表示:(节选自《人工智能》第二版):

function HILL-CLIMBING(problem) return a state thate is a locak maximum
    inputs: problem
    local variables: current, a node 
                         neighbor,a node
    current = MakeNode(INITAL-STATE(problem));
    loop do
        neighbor = a highest-valued successor of current ;
        if VALUE[neighbor] <= VALUE[current] then return STATE[current];
        current = neighbor ;

算法特点:

        爬山法是一个向值增加的方向持续移动的简单循环过程--类似于登高,它将会在到达一个“峰顶”时终止,此时相邻状态中没有比它更高的值。这个算法不会维护搜索树,因此当前节点的数据结构只需要记录当前状态和它的目标函数值,它不会前瞻与当前状态不直接相邻的那些状态的值。这里更高的值是根据具体的应用场景来定的,准确的说是更接近目标状态的值,由我们设置的启发式函数来决定哪个值更好,比如我们求解八皇后问题更高的值就是当前格局中皇后冲突对数最少的情况


算法局限性:

      爬山法属于一种局部的贪婪搜索方法,当它在搜索过程中遇到了局部最大值就很难继续向下搜索了,局部极大值是一个比它的每个邻居状态都高得到峰顶,但是比全局最大值(我们要到达的最终状态)要低,爬山法算法到达局部极大值附近就会被拉向峰顶,然后卡在局部极大值处无处可走。因此产生了爬山法的变种如随机爬山法及其变种如随机爬山法,随机重新开始的爬山法,模拟退火搜索能够非常有效的解决N皇后问题。

求解八皇后问题:

  1. #-*- coding: utf-8 -*-
  2. import random
  3. #函数一:参数为当前棋盘布局状态,根据布局判断当前八皇后布局存在冲突的皇后对数
  4. def get_numof_conflict(status):
  5. num = 0
  6. for i in range(len(status)):
  7. for j in range(i + 1,len(status)):
  8. if status[i] == status[j]:
  9. num += 1
  10. offset = j - i
  11. if abs(status[i]-status[j]) == offset:
  12. num += 1
  13. return num
  14. #函数二:参数为当前棋盘布局状态,利用爬山法思想选择邻居状态最好的布局并返回
  15. def hill_climbing(status):
  16. convert = {}
  17. length = len(status)
  18. for col in range(length):
  19. best_move = status[col]
  20. for row in range(length):
  21. if status[col] == row:
  22. continue
  23. status_copy = list(status)
  24. status_copy[col] = row
  25. convert[(col,row)] = get_numof_conflict(status_copy)
  26. answers = [] #最佳后继集合
  27. conflict_now = get_numof_conflict(status) #当前皇后冲突对数
  28. #遍历存储所有可能后继的字典,找出最佳后继
  29. for key,value in convert.iteritems():
  30. if value < conflict_now:
  31. conflict_now = value
  32. for key,value in convert.iteritems():
  33. if value == conflict_now:
  34. answers.append(key)
  35. #如果最佳后继集合元素大于一个 随机选择一个
  36. if len(answers) > 0:
  37. x = random.randint(0,len(answers)-1)
  38. col = answers[x][0]
  39. row = answers[x][1]
  40. status[col] = row
  41. return status
  42. #函数三:求得八皇后满足冲突数为0的一个解,循环输出每一步的后继集合 直到不存在冲>突为止
  43. def Queens():
  44. status = [0,1,2,3,4,5,6,7] #初始状态所有皇后都在对角线
  45. #当存在冲突的个数大于0时 循环求解最佳后继 直到找到八皇后解
  46. while get_numof_conflict(status) > 0:
  47. status = hill_climbing(status)
  48. print status
  49. print get_numof_conflict(status)
  50. print "the answer is"
  51. print
  52. print status
  53. if __name__ == '__main__':
  54. Queens()
代码说明 :

(1)启发式耗散函数 get_numof_conflict求出可以彼此攻击2的皇后对的数  hill_climbing是算法中爬山过程的实现,convert字典中存储的键是所有可能后继状态,值是此状态对应的皇后冲突对数,后面通过遍历来找到最佳后继。爬山法算法通常在最佳后继集合中随机选择一个进行扩展,如果这样的后继多于一个的话

(2)  棋盘的排列用列表 status 表示, 依次表示第一列第二列到第n列的摆放位置。 如列表[0,2,1] 表示3*3矩阵第一列皇后放在最下面一格,第二列放在最上面一格,第三列放在中间一格

(3) 运行结果说明:初始状态每个皇后都在次对角线上 每次运行程序将输出求解一个八皇后正确解的爬山法实现过程 ,依次输出求解过程每一个最佳选择的邻居状态和其存在的皇后冲突对数,可以看出在求解过程中 不断爬山的过程--每进行一步都达到一个更好的格局,冲突次数更少,最后一行显示的是八皇后的一个正确解 冲突数为 0

运行截图




http://chatgpt.dhexx.cn/article/IVDl3aT0.shtml

相关文章

爬山法求解八皇后问题的全部解法

爬山法求解八皇后问题的全部解法 程序的概要设计思想初始状态冲突函数寻找邻居状态寻找全部解集 程序主要函数的作用运行结果截图Python源代码 程序的概要设计思想 爬山算法是一种局部贪婪算法&#xff0c;每次更新一次状态&#xff0c;都对相邻状态的冲突状态进行排序&#x…

Python启发式算法中爬山法的讲解及解方程问题实战(超详细 附源码)

一、启发式算法 还有一类重要的迭代法&#xff0c;它的迭代关系式不依赖问题的数学性能&#xff0c;而是受某种自然现象的启发而得到&#xff0c;称为启发式算法&#xff08;Heuristic Algorithm&#xff09;&#xff0c;如爬山法、遗传算法、模拟退火算法、蚁群算法等。 启发…

人工智能:爬山法、随机重启爬山法、模拟退火算法、遗传算法、启发式搜索方法解决八数码和八皇后问题

摘要 本文主要分为两个部分&#xff0c;分别采用实验对比对不同的方法进行分析。第一&#xff0c;以八数码问题和八皇后问题为例&#xff0c;对比爬山法&#xff0c;随机重启爬山法&#xff0c;模拟退火算法&#xff0c;遗传算法的搜索性能。第二&#xff0c;以八数码问题为例…

进化优化算法--第二章:爬山法

算法2.1&#xff1a; 最快上升爬山法 x0 <- 随机生成的个体 while not ( 终止准则)计算x0的适应度f(x0)For 每一个解的特征 q1,2,,...nxq <- x0 用一个随机变异替换xq的第q个特征计算xq的适应度f(xq)获取下一个更优的解:寻找使f(xq)最大的xq, 令其等于x, x <- argma…

Python:爬山法/随机重启爬山法/允许侧移的爬山法解决八皇后问题

文章目录 1 八皇后问题2 程序代码2.1 程序12.2 程序22.3 程序32.3.1 爬山法2.3.2 随机重启爬山法2.3.3 允许皇后侧移的爬山法 3 评价 1 八皇后问题 有一个8乘8的棋盘&#xff0c;现在要将八个皇后放到棋盘上&#xff0c;满足&#xff1a;对于每一个皇后&#xff0c;在自己所在…

爬山法和模拟退火

文章目录 前言一、爬山法1.算法步骤2.算法局限性 二、模拟退火1.算法步骤2.注意点3.例题求费马点保龄球均分数据 总结 前言 爬山法和模拟退火都为随机化算法&#xff0c;考场想不到正解时可用来骗分&#xff0c;通常效果较好。模拟退火是基于爬山法的优化。 一、爬山法 爬山法是…

搜索算法——爬山法

不断更新中...... 一、 爬山算法&#xff1a;爬山算法是一种简单的贪心搜索算法&#xff0c;该算法每次从当前位置的临近空间中选择一个最优解作为当前解&#xff0c;直到达到一个局部最优解。爬山算法可以类比成一个有失忆的人在浓雾中爬山。这里就揭示了爬山算法的两个问题…

搜索 —— 启发式搜索 —— 爬山法

【概述】 爬山法&#xff08;Hill Climbing&#xff0c;HC&#xff09;是一种局部择优的贪心搜索算法&#xff0c;其本质上是梯度下降法。 该算法每次从当前的节点开始&#xff0c;与周围的邻接点进行比较&#xff1a; 若当前节点是最大的&#xff0c;那么返回当前节点&…

Linux:快速查看IP地址及修改IP地址

导读Linux下如何快速查看IP地址及修改IP地址&#xff0c;有一个方法供参考 查ip 方法/步骤1: 打开linux操作系统在进入到界面 方法/步骤2: 在桌面右击打开终端。 方法/步骤3: 终端里输入ifconfig -a命令在回车键 方法/步骤4: 如下图可以看到了ip地址。 修改ip 方法/…

Linux Ubuntu查看IP信息的两种方式Ubuntu中检查你的 IP 地址

论使用什么系统&#xff0c;都有用到ip地址的时候&#xff0c;习惯了windows系统的人很容易就能查找出系统的ip&#xff0c;但是在linux系统如何查看ip呢&#xff1f;作为Linux新手&#xff0c;以Ubuntu的使用经验&#xff0c;我知道Ubuntu查看IP有两种方式。 第一种是在终端中…

Linux查询出口IP

查询的方式是通过Linux的curl访问查询ip的网站进行查询 具体步骤&#xff1a; 1.查询查询ip网站的ip 2.配置Linux的hosts文件 在/etc中的hosts文件增加上面的域名和ip&#xff08;注意&#xff1a;是ifconfig&#xff0c;不是ipconfig&#xff09; 3.在ssh命令下执行 curl ifc…

Linux 查看本地ip

Linux 查看本地ip 终端中输入指令ifconfig -a终端中输入指令hostname -I通过图形界面查看IP地址&#xff08;还未试通&#xff09; 终端中输入指令ifconfig -a 弹出的IP地址有点多 。 终端中输入指令hostname -I 会直接显示本机在局域网内的IP地址&#xff0c;但可能会显示多…

Linux服务器查看Ip地址

在服务器的网络配置中&#xff0c;需要同时配置这两种网络&#xff0c;才能使服务器正常使用。使用内网是为了保证我们的服务器处在一个安全的网络环境中&#xff0c;可以减少外部病毒的影响&#xff0c;而访问外网是为了方便我们配置服务器一些资源&#xff0c;如驱动程序&…

Linux 查看IP

UBuntu 系统下 按CtrlAltT 唤出终端 在终端输入: ifconfig 命令 点击回车 就可以看到自己电脑在局域网的IP地址了 图中第二行 inet 地址&#xff1a;192.168.1.101 就是你的电脑在局域网的IP地址了 如果输入 ifconfig 提示 找不到命令 那就在终端输入&#xff1a;sudo apt-get …

linux查看本机ip地址

linux中哪个命令可以查看自己的IP地址 50 我的主机是通过宽带联网的&#xff0c;主机的IP通过那个本地连接可以看到&#xff0c;但在虚拟机Debian linux5.0终端下输入route -n显示的是destination的IP&#xff0c;怎么查看属于虚拟机linux的IP呢&#xff1f;&#xff08;linux通…

Linux系统下怎么查询自己的ip和port

Linux系统下如何查询自己的ip和port 前言&#xff1a;在Linux系统中&#xff0c;学习网络协议之后&#xff0c;就需要经常查看自己系统的ip和port是否正常开启,那么怎么快速查找它们呢&#xff1f; 我现在就把它们列出来&#xff0c;以解我的心头之恨&#xff01;&#xff01;…

Linux查看IP地址命令

Linux查看公有&#xff08;运营商&#xff09;IP地址&#xff1a;下面两个命令都可以查 curl http://ifconfig.io curl ident.me Linux查看私有IP地址&#xff1a;可以使用以下四个命令中的任一一个 ip addr hostname -I | awk {print $1} ip route get 1.2.3.4 | awk {print…

linux怎么查看ip地址

linux怎么查看IP地址&#xff0c;怎么使用命令来查看IP地址&#xff1f;如下图教您怎么操作。 演示环境&#xff1a;centos7 方法一&#xff1a; 首先打开linux操作系统在进入到界面。 桌面右键打开终端 在终端里输入命令后按下回车键 ifconfig -a我们将看到ens33 位置处的…

linux 查看IP地址

参考资料整理 一.在 linux 下可以通过两个命令来查看本机的 IP 地址&#xff1a; 1.支持包括 Linux 在内的所有 Unix 系统。 # /sbin/ifconfig 2. 对于Linux 而言&#xff0c;也可以使用 ip 命令查看&#xff0c;提示&#xff1a;没有ifconfig命令时可以…

linux查看ip命令

参考文章&#xff1a;https://www.linuxidc.com/Linux/2017-10/147449.htm 摘要&#xff1a; 1、ifconfig 查看ip 2、vi 编辑 /etc/sysconfig/network-scripts 下的配置文件&#xff0c;设置动态分配IP有效 一、查看ip命令&#xff1a;ifconfig &#xff08;ip add 命令也行&…