传教士与野人过河问题

代码模块参考文章:传教士与野人过河问题(numpy、pandas)_python过河问题_醉蕤的博客-CSDN博客

问题描述

一般的传教士和野人问题(Missionaries and  Cannibals):有N个传教士和C个野人来到河边准 备渡河。河岸有一条船,每次至多可供K人乘渡。 问传教士为了安全起见,应如何规划摆渡方案,使 得任何时刻,在河的两岸以及船上的野人数目总是 不超过传教士的数目,但允许在河的某一岸只有野 人而没有传教士。

这里讨论基于N=3,C=3,k=2

状态表示:(m,w,B);初始状态: (3, 3, 1);目标状态: (0,0,0)

启发性规则

操作符(产生式规则)
左岸往右岸运载产生式
L10  if(M,W,1) then (M-1,W,0)     (左往右运1传教士)
L01  if(M,W,1) then (M,W-1,0)     (左往右运1野人)
L11  if(M,W,1) then (M-1,W-1,0)  (左往右运1传教士和1野人)
L20  if(M,W,1) then (M-2,W,0)     (左往右运2传教士)
L02  if(M,W,1) then (M,W-2,0)     (左往右运2野人)

右岸往左岸运载产生式
R10  if(M,W,0) then (M+1,W,1)    (右往左运1传教士)
R01  if(M,W,0) then (M,W+1,1)    (右往左运1野人)
R11  if(M,W,0) then (M+1,W+1,1) (右往左运1传教士和1野人)
R20  if(M,W,0) then (M+2,W,1)    (右往左运2传教士)
R02  if(M,W,0) then (M,W+2,1)    (右往左运2野人)

路径方案展示

总共有四种解决方案

实现代码(含具体解释)

import numpy as npM = int(input("请输入传教士的数量:"))  # 传教士数量
C = int(input("请输入野人的数量:"))  # 野人数量
K = int(input("请输入船的最大容量:"))  # 船的最大容量child = []  # child:用于存储所有扩展节点
open_list = []  # open list
closed_list = []  # closed listclass State:def __init__(self, m, c, b):self.m = m  # 左岸传教士的数量self.c = c  # 左岸野人的数量self.b = b  # b为1时船在左岸;b为0时船在右岸self.g = 0  # 该结点所在的层级self.f = 0  # 该结点的启发性层度f = g + h# father这个属性是Stateself.father = Noneself.node = np.array([m, c, b])init = State(M, C, 1)  # 初始节点
goal = State(0, 0, 0)  # 目标节点# 判断状态是否合法
def safe(s):# 下面是要排除的条件,并且给出了为什么要排除的理由# s.m > M or s.m < 0 题目要求传教士的数量# s.c < 0 or (s.m != 0 and s.m < s.c) 有教士时,野兽的数量不能大于教士# s.m != M and M - s.m < C - s.c 对岸不全是怪兽时,对岸上的怪兽不能大于对岸上的教士if s.m > M or s.m < 0 or s.c > C or s.c < 0 or (s.m != 0 and s.m < s.c) or (s.m != M and M - s.m < C - s.c):return Falseelse:# 状态合法return True# 启发函数
def h(s):# 传教士数量+野人数量-船的位置与船的最大容量的乘积# 我们希望这个值越越小越好# 他的含义:岸上传教士数量+岸上野人数量之后# 如果这船在对岸(这是我们希望的,说明顺利渡河),于是我们就减上K*s.b# 如果船不在对岸,这不是我们希望的,所以不进行任何减数的操作(K=0)return s.m + s.c - K * s.b# 判断两个状态是否相同
def equal(a, b):if np.array_equal(a.node, b.node):return 1, belse:return 0, b# 判断当前状态是否与父状态一致
# new 是新结点,s是它的父节点
def back(new, s):if s.father is None:return Falsec = b = s.fatherwhile True:# 不断回溯,去找他的父结点是否与new结点相同a, c = equal(new, b)if a:return Trueb = c.fatherif b is None:# 此时找到的b是根结点,停止搜索return False# 根据f值对open_list进行排序
def open_sort(l):l.sort(key=lambda x: x.f)# 在open_list和closed_list中查找具有相同MCB属性的节点
def in_list(new, l):for item in l:if np.array_equal(new.node, item.node):return True, itemreturn False, None# A*算法
def A_star(s):A = []global open_list, closed_listopen_list = [s]closed_list = []while True:  # open_list不为空for i in open_list:if np.array_equal(i.node, goal.node):  # 判断是否为目标节点A.append(i)open_list.remove(i)if not open_list:breakget = open_list[0]open_list.remove(get)  # 从open_list中移除get节点closed_list.append(get)  # 将get节点加入closed_list# 获取get的子节点并考虑是否将其加入open_listfor i in range(M + 1):  # 船上传教士数量for j in range(C + 1):  # 船上野人数量# 船上人数非法: 1:船上无人或者2:船上的人大于规定的载客数或者3:船上有教士并且野怪的数量大于教士if i + j == 0 or i + j > K or (i != 0 and i < j):continue# 找到满足要求的相对于刚遍历完的结点get的下一个状态if get.b == 1:  # 当前船在左岸,下一个状态船在右岸new = State(get.m - i, get.c - j, 0)child.append(new)else:  # 当前船在右岸,下一个状态船在左岸new = State(get.m + i, get.c + j, 1)child.append(new)# safe(new)判断是否非法# back(new, get)这个相对于get结点的孩子回到父状态? TODOif not safe(new) or back(new, get):  # 状态非法或已经回到父状态child.pop()else:# 定义它的上一个状态的结点new.father = get# 孩子结点层级加1new.g = get.g + 1# 父亲的结点层级+父亲的启发性层度new.f = get.g + h(get)open_list.append(new)open_sort(open_list)return A# 递归打印路径
def print_path(f):if f is None:return# 先递归打印父结点的,再打印自己的结点print_path(f.father)print(f.node)# print(f.f)if __name__ == '__main__':print('传教士数量:%d, 野人数量:%d, 船的最大容量:%d' % (M, C, K))final = A_star(init)print("共有%d种方案" % len(final))if final:c = 1for i in final:print('第%d个方案如下' % c)print_path(i)c += 1else:print('没有找到解决方案!')

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

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

相关文章

【分布式事务】Seata 开源的分布式事务解决方案

1. 什么是seata Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。 2. seata发展历程 阿里巴巴作为国内最早一批进行应用分…

视频中的文字水印怎么去除?这三招学会轻松去视频水印

短视频与我们生活&#xff0c;工作息息相关&#xff0c;日常在在刷短视频时&#xff0c;下载保存后发现带有文字logo水印&#xff0c;如果直接拿来进行二次创作&#xff0c;不仅影响观看效果&#xff0c;平台流量还会受限制。怎么去除视频中的文字水印就成为了当下热门话题之一…

【代码】CNN-GRU-Attention基于卷积神经网络和门控循环单元网络结合注意力机制的多变量回归预测

程序名称&#xff1a;CNN-GRU-Attention基于卷积神经网络和门控循环单元网络结合注意力机制的多变量回归预测 实现平台&#xff1a;matlab 代码简介&#xff1a;为更准确地预测&#xff0c;提出基于注意力机制的CNN-G&#xff32;U预测模型。该模型主要借助一维卷积单元提取数…

浅聊langchain-chatchat

个人的一点经验和总结&#xff0c;希望能帮助到大家。有不对的地方请留言和指正&#xff01; langchain-GLM是什么 langchain-GLM是一个本地知识库应用解决方案&#xff0c;支持以cli、web、api方式提供以本地知识库或在线资源为知识素材的对话服务&#xff0c;对中英文场景对…

【AIOps】一种全新的日志异常检测评估框架:LightAD,相关成果已被软工顶会ICSE 2024录用

深度学习&#xff08;DL&#xff09;虽然在日志异常检测中得到了不少应用&#xff0c;但在实际轻量级运维模型选择中&#xff0c;必须仔细考虑异常检测方法与计算成本的关系。具体来说&#xff0c;尽管深度学习方法在日志异常检测方面取得了出色的性能&#xff0c;但它们通常需…

【Linux】awk 使用

awk 输出 // 打印所有列 $ awk {print $0} file // 打印第一列 $ awk {print $1} file // 打印第一和第三列 $ awk {print $1, $3} file // 打印第三列和第一列&#xff0c;注意先后顺序 $ cat file | awk {print $3, $1} …

探索数据之美:深入学习Plotly库的强大可视化

1. 引言&#xff1a; Plotly 是一个交互性可视化库&#xff0c;可以用于创建各种漂亮的图表和仪表板。它支持多种编程语言&#xff0c;包括Python、R、JavaScript。在Python中&#xff0c;Plotly提供了Plotly Express和Graph Objects两个主要的绘图接口。 2. Plotly库简介&am…

音乐播放器Swinsian mac功能介绍

Swinsian mac是一款音乐播放器&#xff0c;它的特点是轻量级、快速、易用。Swinsian支持多种音频格式&#xff0c;包括MP3、AAC、FLAC、WAV等。它还具有iTunes集成功能&#xff0c;可以自动导入iTunes音乐库中的音乐&#xff0c;并支持智能播放列表、标签编辑、自定义快捷键等功…

STM32Cube高效开发教程<基础篇>(十)----USART/UART通信

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    本专栏博客参考《STM32Cube高效开发教程(基础篇)》,有意向的读者可以购买正版书籍进行学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。 一、 功能概述…

Linux shell for jar test

Linux shell 脚本&#xff0c;循环解析命令行传入的所有参数&#xff0c;并按照不同的传参实现对不同的 java jar文件 进行测试执行。 [rootlocalhost demo]# cat connTest.sh #!/bin/bash# Linux shell for qftool java jar test# modes DEFAULT_MODE2jarfiles[1]common-1.0…

OpenAI公布CEO和董事会成员:微软加入,Ilya出局

11月30日&#xff0c;OpenAI在官网公布了新一届领导层和初始董事会成员&#xff1a;Sam Altman重新担任CEO&#xff0c;Mira Murati继续担任首席技术官&#xff0c;Greg Brockman继续担任总裁。 新的董事会成员包括&#xff1a;Bret Taylor&#xff08;主席&#xff09;、Larr…

docker部署elasticsearch+kibana+head

前言 最近&#xff0c;项目需要使用elasticsearch&#xff0c;所以就想快速安装一个使用&#xff0c;最开始是docker安装了7.10.1版本。 后面计划使用Java开发&#xff0c;发现有 RestHighLevelClient 和 Elasticsearch Java API Client两种客户端连接方式。 然后网上查阅了一…

深入剖析:知识付费系统源码解读与技术实现

知识付费系统源码是构建一个高效、稳定平台的关键。在本文中&#xff0c;我们将深入解析知识付费系统的源码&#xff0c;同时提供一些关键技术代码&#xff0c;以助你更好地理解和实现这一系统。 1. 知识付费系统的基本结构 首先&#xff0c;让我们看一下知识付费系统的基本…

论文学习-Bert 和GPT 有什么区别?

Foundation Models, Transformers, BERT and GPT 总结一下&#xff1a; Bert 是学习向量表征&#xff0c;让句子中某个词的Embedding关联到句子中其他重要词。最终学习下来&#xff0c;就是词向量的表征。这也是为什么Bert很容易用到下游任务&#xff0c;在做下游任务的时候&a…

经验分享:JMeter控制RPS

一、前言 ​ RPS (Request Per Second)一般用来衡量服务端的吞吐量&#xff0c;相比于并发模式&#xff0c;更适合用来摸底服务端的性能。我们可以通过使用 JMeter 的常数吞吐量定时器来限制每个线程的RPS。对于RPS&#xff0c;我们可以把他理解为我们的TPS&#xff0c;我们就…

数组?NO 系Vector啊!

文章目录 前言一、vector的介绍二、vector的使用2.1 vector求容量的用法2.2 vector的增删查改用法2.2.1 尾插2.2.2 尾删2.2.3 头插2.2.4 任意位置删除 2.3 vector的iterator是什么以及失效问题 三、vector的模拟实现3.1 成员变量3.2 成员函数3.2.1 构造函数3.2.2 拷贝构造3.2.3…

一起学docker系列之十五深入了解 Docker Network:构建容器间通信的桥梁

目录 1 前言2 什么是 Docker Network3 Docker Network 的不同模式3.1 桥接模式&#xff08;Bridge&#xff09;3.2 Host 模式3.3 无网络模式&#xff08;None&#xff09;3.4 容器模式&#xff08;Container&#xff09; 4 Docker Network 命令及用法4.1 docker network ls4.2 …

MSSQL注入

目录 基本的UNION注入&#xff1a; 错误基于的注入&#xff1a; 时间基于的盲注入&#xff1a; 堆叠查询&#xff1a; 理解MSSQL注入是学习网络安全的一部分&#xff0c;前提是您在合法、授权的环境中进行&#xff0c;用于了解如何保护您的应用程序免受此类攻击。以下是有关…

【linux】/etc/security/limits.conf配置文件详解、为什么限制、常见限制查看操作

文章目录 一. limits.conf常见配置项详解二. 文件描述符&#xff08;file descriptor&#xff09;简述三. 为什么限制四. 相关操作1. 展示当前资源限制2. 查看系统当前打开的文件描述符数量3. 查看某个进程打开的文件描述符数量4. 各进程占用的文件描述符 /etc/security/limits…

大势智慧与四川资源测绘签署战略合作协议

战略合作 11月27日上午&#xff0c;武汉大势智慧科技有限公司&#xff08;后简称“大势智慧”&#xff09;和四川省自然资源测绘地理信息有限责任公司&#xff08;后简称“测绘公司”&#xff09;在成都成功签订战略合作协议&#xff0c;大势智慧董事长黄先锋&#xff0c;测绘…