`
DigitalSonic
  • 浏览: 214668 次
社区版块
存档分类
最新评论

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

阅读更多

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


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

分享到:
评论

相关推荐

    修道士野人问题

    c++实现的修道士野人问题 河的左岸有N个野人和N个修道士以及一条小船,修道士们想用这条小船把所有的人都运到河的右岸,但又受到以下限制:  修道士和野人都会划船,但船一次只能载C人。  在任何岸边,为了防止...

    C语言实现野人与修道士过河问题 源代码

    总的来说,C语言实现野人与修道士过河问题是一个锻炼编程思维和问题解决技巧的好项目,它涵盖了数据结构、算法设计、逻辑推理等多个编程核心概念。通过实践和学习此类问题,程序员不仅可以提升C语言技能,还能增强...

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

    根据给定的信息,本文将详细解释“修道士与野人渡河问题”的数据结构实现方法,包括使用三维数组表示状态、图的运用等关键概念。 ### 三维数组STATE的使用 在解决“修道士与野人渡河问题”时,采用了一个三维数组`...

    野人与修道士 C++完整工程项目及源代码

    在这个项目中,C++被用来实现野人与修道士问题的解决方案。完整的工程项目包括了源代码文件,这使得学习者可以深入了解如何运用C++的结构和算法来解决复杂问题。 `ClassDiagram.cd`可能是一个类图文件,用于表示...

    修道士与野人问题

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

    java实现野人与传教士过河问题

    "Java实现野人与传教士过河问题"是一个经典的逻辑和算法问题,源自于一个古老的智力谜题。这个问题的基本设定是:三个传教士和三个野人需要通过一条河,他们只有一条小船,每次最多能承载两个人。关键在于,如果野人...

    使用C++语言实现修道士与野人问题

    假设有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。如果两种人都会划船,试设计一个算法,确定他们...

    修道士野人问题C++

    修道士野人问题,也被称为“修道院长老与野人问题”或“修道士、岛民与恶魔问题”,是一个经典的逻辑谜题。在该问题中,一群修道士被困在一个孤岛上,他们需要通过一系列复杂的规则来决定何时离开这座岛。问题的核心...

    传教士和野人问题(MC问题)的A*算法实现

    问题:设有3个传教士和3个野人来到河边,打算乘一只船从右岸渡到左岸去。该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,那么...2、在任何岸边,野人数不能超过修道士数,否则修道士将会被野人吃掉

    修道士与野人问题+图书管理系统

    在"RiverandMan"文件中,可能包含了修道士与野人问题的代码实现,例如使用递归、回溯或者动态规划的方法。而"Library"文件则可能包含了图书管理系统的设计和源代码,可能使用了关系型数据库(如MySQL)存储图书和...

    人工智能prolog语言实验:修道士、野人渡河问题(传教士、野人渡河问题)

    在河的右岸有3个修道士、3个野人和一条船,修道士要把所有人都运到河对岸,但是:...(2)在两个岸边,野人数目不能超过修道士的数目,否则后者被吃掉。野人完全服从修道士的任何渡河方案。 包含prolog代码以及实验报告

    修道士与野人渡河问题源代码

    【修道士与野人渡河问题】是一个经典的逻辑与算法问题,主要涉及到数据结构和算法设计,特别是图的邻接表表示以及广度优先搜索(BFS)的应用。在这个问题中,目标是确保修道士数量始终不少于野人,以防止野人攻击,...

    人工智能实验_人工智能实验-修道士与野人问题_

    在实现A*算法解决修道士与野人问题时,我们首先需要定义状态表示,这可能包括每个人的位置、船只的状态等。接下来,我们需要定义启发式函数h(n),比如可以使用曼哈顿距离或欧几里得距离,但要注意这些可能不是最佳...

    实验一:prolog求解修道士与野人渡河问题(人工智能实验)

    包含prolog求解修道士与野人问题的实验报告、源代码及试验运行截图

    传教士与野人python

    "传教士与野人"问题是一个经典的逻辑谜题,源于数学和计算机科学中的约束满足问题。在这个问题中,有n个传教士和n个野人,他们必须通过一条河,只有一条能载m个人(m小于或等于n)的小船。规则是不允许在任何一侧...

    人工智能-野人与传教士过河.c

    1.问题重述 在河的左岸有N个传教士、N个野人和一条船,传教士们想...(2)在任何岸边野人数目都不能超过修道士,否则修道士会被野人吃掉。 假定野人会服从任何一种过河安排,请规划出一个确保修道士安全过河的计划。

    修道士与野人问题课程设计报告

    "修道士与野人问题"是一个经典的逻辑与算法问题,涉及到状态空间搜索和安全性检查。问题的核心在于确保在任何情况下,修道士的数量都不少于野人,以防止野人对修道士造成威胁。这里,我们有n个修道士和n个野人,以及...

    传教士与野人问题-数据结构

    假设有n个修道士和n个野人准备渡河,但只有一条能容纳c人的小船,为了防止野人侵犯修道士,要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。如果两种人都会划船,试设计一个算法,确定他们...

    修道士&野人_终极测试数据

    "修道士&野人_终极测试数据"这个压缩包文件主要包含了关于修道士和野人问题的多种测试案例。这是一个经典的逻辑推理问题,通常在编程挑战或者数学游戏中出现,旨在测试参与者的问题解决能力和逻辑思维。 修道士和...

    Java解决“野人传教士过河问题”算法源码

    假设有 N 个传教士和 N 个野人准备渡河,但只有一条能容纳 C 人的小船,1 ,为了防止野人伤害传教士,要求无论在何处,传教士的个数不得少于野人的人数(除非传教士个数为 0)。如果两种人都会划船,试设计一个算法...

Global site tag (gtag.js) - Google Analytics