野人与修道士问题的Ruby实现

修道士野人问题的python求解 修道士野人问题的python求解问题描述状态空间表示程序设计执行结果源代码(Python3.5) 问题描述 修道士(Missionaries)和野人(Cannibals)问题 修道士野人过河问题是人工智能领域一个典型的问题,其经典描述为如下。 在河的左岸有N个传教士(M)、N个野人(C)和一条船(Boat),修道士们想用这条船把所有人都运过河去,但有以下条件限制: 修道士和野人都会划船,但船每次... 阅读详情

问题描述:
河左岸有三个修道士,三个野人和一条船,假定船最多只能运两个人,且任何岸边的野人数目不得超过修道士,否则修道士就会被野人吃掉。
如何才能把修道士和野人都运到右岸?


Savage.rb



SAVAGE    = 0
BOANERGES = 1
DEEP      = 5

#记录状态
class Status
 @@StatusList = Array.new
 @@Pos = -1
 
  attr_writer :nSavage          #岸边野人的数量,全部到对岸为0
  attr_writer :nBoanerges       #岸边传教士的数量,全部到对岸为0
  attr_writer :nSide            #船的位置,在此岸为-1,对岸为1
  attr_writer :nMoveSavage      #渡河的野人的数量,用于递归时记录操作状态
  attr_writer :nMoveBoanerges   #渡河的传教士的数量,用于递归时记录操作状态 

  attr_reader :nSavage          
  attr_reader :nBoanerges       
  attr_reader :nSide            
  attr_reader :nMoveSavage      
  attr_reader :nMoveBoanerges   
 
  def initialize()
   @nSavage        =  3
   @nBoanerges     =  3
   @nSide          = -1
   @nMoveSavage    =  0
   @nMoveBoanerges =  0
 end
 
  def Status.getList()
   return @@StatusList
 end
 
  def Status.getPos()
   return @@Pos
 end
 
  def Status.addStatus(stat)
   @@StatusList.push(stat)
   @@Pos += 1
 end
 
 def Status.delStatus()
  @@StatusList.pop()
  @@Pos -= 1
 end
end

class Ship
 def Ship.hasNextStep(stat)
  store = [[],[],[],[],[]]
  
  if stat.nSide == -1 then
   store[0][SAVAGE]    = 2
      store[0][BOANERGES] = 0
      store[1][SAVAGE]    = 1
      store[1][BOANERGES] = 1
      store[2][SAVAGE]    = 0
      store[2][BOANERGES] = 2
     store[3][SAVAGE]    = 1
      store[3][BOANERGES] = 0
      store[4][SAVAGE]    = 0
     store[4][BOANERGES] = 1
  elsif stat.nSide == 1
      store[0][SAVAGE]    = 0
      store[0][BOANERGES] = 1
      store[1][SAVAGE]    = 1
      store[1][BOANERGES] = 0
      store[2][SAVAGE]    = 0
      store[2][BOANERGES] = 2
      store[3][SAVAGE]    = 1
      store[3][BOANERGES] = 1
      store[4][SAVAGE]    = 2
      store[4][BOANERGES] = 0  
  end

  iStart = 0
    if stat.nMoveSavage == 0 && stat.nMoveBoanerges == 0
     iStart = 0
    else
     for iStart in 0...DEEP
       puts iStart
    if stat.nMoveSavage == store[iStart][SAVAGE] && stat.nMoveBoanerges == store[iStart][BOANERGES]
         break
        end
      end
      iStart += 1
  end
   
  if (iStart < DEEP)
   i = 0
   for i in iStart...DEEP
    nSideSavage      = stat.nSavage + stat.nSide * store[i][SAVAGE]
        nSideBoanerges   = stat.nBoanerges + stat.nSide * store[i][BOANERGES]
        nBesideSavage    = 3 - nSideSavage
        nBesideBoanerges = 3 - nSideBoanerges

        #传教士数量大于等于野人或为零
        if ((nSideSavage   <= nSideBoanerges   || nSideBoanerges   == 0) &&
            (nBesideSavage <= nBesideBoanerges || nBesideBoanerges == 0) &&
             nSideSavage   >= 0 && nSideBoanerges >= 0 && nBesideSavage >= 0 && nBesideBoanerges >= 0) then
         #如果本此解等于上次,放弃
          if Status.getPos > 0
           if (Status.getList()[Status.getPos - 1].nMoveBoanerges == store[i][BOANERGES] &&
                Status.getList()[Status.getPos - 1].nMoveSavage    == store[i][SAVAGE])
               next
            end
          end
          break
        end
   end
   
   if i < DEEP
     stat.nMoveSavage    = store[i][SAVAGE]
        stat.nMoveBoanerges = store[i][BOANERGES]
        return true
      end
    end

    return false;  
 end
 
 #递归函数
 def Ship.find(stat)
   if hasNextStep(stat)
     pNew = Status.new
      pNew.nSavage        = stat.nSavage + stat.nMoveSavage * stat.nSide
      pNew.nBoanerges     = stat.nBoanerges + stat.nMoveBoanerges * stat.nSide
      pNew.nSide          = stat.nSide * -1
      pNew.nMoveSavage    = 0
      pNew.nMoveBoanerges = 0
      Status.addStatus(pNew)
     
      if pNew.nSavage == 0 && pNew.nBoanerges == 0
        Status.delStatus()
       return true
      end
      return find(pNew)
    else
      if Status.getPos == 0
       return false
      end
      Status.delStatus()

      return find(Status.getList()[Status.getPos])
    end
    return true
 end
end

initStat = Status.new
Status.addStatus(initStat)
if (Ship.find(initStat))
 puts "渡河过程如下:"
 Status.getList().each do |stat|
  print "下次渡河方向:", (stat.nSide == -1) ? "-->" : "<--", " 人数:野人", stat.nMoveSavage, " 传教士", stat.nMoveBoanerges, " 当前此岸野人数:", stat.nSavage, " 传教士数:", stat.nBoanerges, "/n"
 end
else
 puts "此题无解"
end
print "Press ENTER to return."
$stdin.gets

传教士与野人过河问题(numpy、pandas) 传教士与野人过河问题(numpy、pandas) 可自定义输入 有完整代码 A*算法 阅读详情

相关推荐

人工智能——状态空间搜索及状态空间表示法

图中,节点Sk表示状态,状态之间的连接采用有向弧(Arc),弧上标以操作数OK来表示状态之间的转换关系。根据上述分析,共有16个合法状态和允许的操作,可以划出传教士和食人者问题的状态空间图,如图所示。(5)当状态数量不是很大时,按问题的有序元组画出状态空间图,依照状态空间图搜索求解。(5)当状态数量不是很大时,按问题的有序元组画出状态空间图,依照状态空间图搜索求解。(4)估计全部的状态空间数,并尽可能列出全部的状态空间或予以描述之。问题的状态可以用一个三元数组来描述,以左岸的状态来标记,即。

人工智能AI技术 2万+

修道士和野人问题:所有解、启发求解、简单界面

一.作业任务 修道士和野人问题:设有三个修道士和3个野人来到河边,打算用一条船从河的左岸渡到河的右岸去。但该船每次只能装载两个人,在任何岸边野人的数目都不得超过修道士的人数,否则修道士就会被野人吃掉。假设野人服从任何一种过河安排,请规划出使全部6人安全过河的方案。 问题提示:应用状态空间表示和搜索方法时,可用(Nm,Nc)来表示状态描述,其中Nm,Nc分别为传教士和野人的人数。初始状态为(3,3)...

weixin_44001813的博客 1万+

传教士与野人python

"传教士与野人"问题是一个经典的逻辑谜题,源于数学和计算机科学中的约束满足问题。在这个问题中,有n个传教士和n个野人,他们必须通过一条河,只有一条能载m个人(m小于或等于n)的小船。规则是不允许在任何一侧出现野人多于传教士的情况,以防传教士被野人杀害。这个问题的目的是找出一种安全的渡河策略。 在Python中解决这个问题,通常会用到搜索算法,如深度优先搜索(DFS)、广度优先搜索(BFS)或者A*搜索。这些算法能够遍历所有可能的状态,寻找满足条件的解决方案。我们需要定义状态,包括当前在河的哪一侧、船上的人数以及各有多少传教士和野人。接着,我们会定义一个转移函数,用于模拟小船在河两岸间移动,并检查每个状态是否符合安全规则。我们需要一个搜索策略来遍历状态空间,找到目标状态(所有人都到达对岸)。

修道士和野人问题——人工智能的状态空间图问题

问题:为什么将状态空间的约束条件定为 m=3或m=0或m=n?3. 左右两边同时都有野人和修道士,此时只能使m=n。1. 左边全野人,右边全修道士,此时m=3。2. 左边全修道士,右边全野人,此时m=0。

Aiden_Tyler的博客 6661

修道士野人问题

c++实现的修道士野人问题 河的左岸有N个野人和N个修道士以及一条小船,修道士们想用这条小船把所有的人都运到河的右岸,但又受到以下限制:  修道士和野人都会划船,但船一次只能载C人。  在任何岸边,为了防止野人侵犯修道士,野人数不能超过修道士数,否则修道士将会被野人吃掉。 假定野人愿意服从任何一种过河的安排,本设计的主要任务是规划出一种确保修道士安全的过河方案。

修道士与野人问题

修道士与野人过河问题,包括界面编写。

用状态空间方法求解修道士与野人问题

用状态空间图求解修道士与野人问题

jjsd__gulugulu的博客 1万+

修道士与野人渡河问题 数据结构

用三维数组STATE(0:n,0:n,0:n)代表渡河过程中所有状态(合法的和非法的)。STATE(x1,x2,x3)为真,表示该状态已经出现过(“已达”);为假,表示未曾出现过(“未达”)。

修道士和野人问题

题目: 设在河的一岸有三个野人、三个修道士和一条船,修道士想用这条船把所有的人运到河对岸,但受以下条件的约束: 一是修道士和野人都会划船,但每次船上至多可载两个人; 二是在河的任一岸,如果野人数目超过修道士数,修道士会被野人吃掉。 如果野人会服从任何一次过河安排,请规划一个确保修道士和野人都能过河,且没有修道士被野人吃掉的安全过河计划。 代码一(暴力搜索): #include <iostre...

qq_30534935的博客 1万+

GD32F450以太网(2-2): PHY芯片IP101GR介绍

IP101是台湾省九阳电子公司生产制造的,符合IEEE 802.3/802.3u标准单端口快速以太网收发器100Mbps和10Mbps操作,它支持自动MDI/MDIX功能,简化网络安装和减少系统维护成本。支持Auto MDI/MDIX已内置4个49.9欧的精密电阻支持中断功能支持 MII/RMII 接口超低功耗

Zhichao_Zhang的博客 1万+

拆解歌尔2718硅麦:2.75mm超小封装背后的MEMS技术解析

本文深度解析歌尔2718硅麦的2.75mm超小封装技术,探讨MEMS麦克风在微型化过程中的声学性能与结构可靠性平衡。通过ASIC芯片堆叠、纳米级应力控制等创新技术,歌尔2718在TWS耳机和智能手机中实现卓越性能,同时克服微型化带来的声学挑战。

weixin_28292761的博客 610

状态空间表示法----野人与修道士

状态空间法的应用修道士(Missionaries)和野人(Cannibals)问题   在河的左岸有N个传教士(M)、N个野人(C)和一条船(Boat),传教士们想用这条船把所有人都运过河去,但有以下条件限制:  (1)修道士和野人都会划船,但船每次最多只能运K个人;  (2)在任何岸边野人数目都不能超过修道士,否则修道士会被野人吃掉。   假定野人会服从任何一种过河安排,请规划出一个确保修道士安...

轻尘 2万+

新能源充电桩充电枪口标准

建立的标准确保了新能源汽车充电的安全性、兼容性和效率,促进了新能源汽车产业的发展。

网络安全的研究者、新能源行业的追求者 4686

人工智能:状态空间图(超详细经典例题讲解,通过例题教会你如何解决状态空间图问题)

状态空间常记为三元组:。 其中,S为初始状态的集合,F为操作的集合,G为目标状态的集合。 问题的状态空间图是一个描述该问题全部可能的状态及相互关系的有向图。 如考虑操作的代价,状态空间图就是一个赋值有向图。1、一个猎人要带着一只狼、一只羊、一捆草过河,但是人不在的时候,狼会吃羊、羊会吃草,猎人每次只能带一样东西过河。试构造状态空间图,并给出他们能顺利过河的方案。对于这种过河的题目,我们一般默认刚开始都在左岸,也只用分析左岸的情况,因为右岸的情况可以根据左岸的情况推出,比如左岸有一个狼人和一只羊......

俊夫小瞳的博客 2万+

【数学模型】灰色关联分析

数学模型-灰色关联分析

suic009的博客 1万+

用Docker-Compose三节点部署生产级Doris集群:从配置文件到故障转移

本文详细介绍了如何使用Docker-Compose部署一个生产级的三节点Apache Doris集群。内容涵盖从核心架构理解、配置文件编写到集群初始化验证的全过程,并重点讲解了如何实现高可用、数据持久化、健康检查以及故障转移等生产级运维关键点,为中小团队提供了一种在容器化便利性与系统稳定性间取得平衡的可靠部署方案。

kkk56的博客 856

状态空间法——野人和传教士的问题

设有3 个传教士和3 个野人来到河边,打算乘一只船从右岸渡到左岸去。该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,那么野人就会把传教士吃掉。如何用状态空间法来表示该问题?给出具体的状态表示和算符。 第一步 根据题目要求设置好约束条件 例如通过船的负载能力为两人得出: 船上的人M(传教士)+C(野人)小于等于2 第二步 用三个参数表示左岸转状态 并且列出所有可用的状态 第三步 列出所有的操作集 从左岸划向右岸 +从右岸划向左岸 =共10种操作集合(详情请参考图片) 第四步列出最短

qq_43063093的博客 1万+

2024年上半年网络工程师下午真题及答案解析

位于MPLS域边缘、连接其他网络的LSR称为( 3 ),区域内部的LSR称为核心LSR(CoreLSR)IP报文进入MPLS网络时,MPLS入口设备分析IP报文的内容并为其添加合适的标签,所有MPLS网络中的LSR根据标签转发数据,当该IP报文离开MPLS网络时,标签由出口LER弹出。LSP的出口LER称为( 6 )。某高校网络拓扑如下图所示,两校区核心(CORE-1、CORE-2),出口防火墙(NGFW-1、NGFW-2)通过校区间光缆互联,配置OSPF实现全校路由收敛,两校区相距40km。

bsefef的博客 2471

传教士与野人问题(完整状态搜索图)

传教士与野人问题 传教士和野人问题。三个传教士和三个野人在河的一岸, 有一条能载一个人或者两个 人的船。请设法使所有人都渡到河的另一岸, 要求在任何地方野人数都不能多于传教 士的人数。这个问题在AI 领域中很有名, 是因为它是第一个从分析的观点探讨问题。 对问题作如下抽象,以列表state=[c,a,b]分别代表初始岸边的传教士人数,野人人数,船只数目,有 初始状态:state=[3,3,1] agent所有可能行动: 当b==1时,在以下五种状态中选择一种执行, a=a-1,b=b-1,c=

南柯一梦的博客 3万+

电压抬升电路设计

一、实验目的 掌握集成运放电压放大电路设计基本方法。 掌握基本仪器使用方法(电源、信号发生器、示波器)。 二、实验内容及结果 实验内容 基于集成运放设计一传感器信号采集电路。传感器输出信号在±50mV,频率为100Hz以内,模数转换器允许输入电压在0~5V,要求设计传感器与模数转换器之间的信号采集电路,实现传感器信号放大10倍,并适合模数转换器的输入。模数转换器的输入电阻为1KHz,设计电路时,可使用1KHz电阻作为信号采集电路负载,代替模数转换器。 实验具体要求如下: (1)确定电路形式,说明电压转

Safaearth的博客 4万+

Android 15.0 Launcher3中去掉Hotseat功能实现

在15.0系统产品定制化开发中,在Launcher3的定制化需求也是特别多的,由产品是小屏幕的产品,所以产品需求Launcher3 页面布局的原因,要求Launcher3 需要去掉Hotseat 不显示Hotseat下面几个图标,而做满屏app的显示,从而达到美观的效果,下面就来分析去掉Hotseat从而实现这个功能

安卓兼职framework和app工程师的博客 554

请教“修道士与野人问题”

有N个修道士和N个野人准备渡河,但只有一条能容纳C人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士的个数为0)。两种人都会划船,设计一算法,确定他们能否过河,若能,找出一个小船来回次数最少的方案。

colwater的专栏 2982

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: 八数码游戏的Ruby实现
下一篇: 野人与修道士问题的Ruby实现
dingx
博客等级 码龄24年 67粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值