状态空间法的应用

修道士(Missionaries)和野人(Cannibals)问题

在河的左岸有N个传教士(M)、N个野人(C)和一条船(Boat),传教士们想用这条船把所有人都运过河去,但有以下条件限制:

(1)修道士和野人都会划船,但船每次最多只能运K个人;

(2)在任何岸边野人数目都不能超过修道士,否则修道士会被野人吃掉。

假定野人会服从任何一种过河安排,请规划出一个确保修道士安全过河的计划。

约束条件:① M≧C 任何时刻两岸、船上都必须满足传教士人数不少于野人数(M=0时除外,既没有传教士)② M+C≦K 船上人数限制在K以内

求解:传教士与野人全部安全渡到对岸的解决方案。

解:设N=3,K=2(三个M和三个C,每次渡河二人以下)

L:左岸,R:右岸,

B:是否有船(0:无船,1:有船)

①状态表示

定义:用三元组(ML,CL,BL)表示左岸状态,其中:

0≦ML,CL≦3,BL∈{0,1}

如:(0,3,1)表示左岸有三个野人,船在左岸。

M&C的问题描述: 从(3,3,1)到(0,0,0)的状态转换

状态空间:32 种状态,其中:

12种不合理状态:如(1,0,1)说明右岸有2个M,3个C;4种不可能状态:如(3,3,0)说明所有M和C都在左岸,而船在右岸

∴可用的状态共16种,组成合理的状态空间

②操作集

定义:Pmc操作:从左岸划向右岸

Qmc操作:从右岸划向左岸

船上人数组合(m,c)共5种应P,Q二种操作

∴系统共有 5×(1,0),(1,1),(2,0),(0,1),(0,2)

∵每一种船上的人数组合同时对2=10种操作(规则)

如:P10:if (ML,CL,BL=1) then (ML-1,CL,BL-1)

如果船在左岸,那么一个传教士划船到右岸

Q01:if (ML,CL,BL=0) then (ML,CL+1,BL+1)

如果船在右岸,那么一个野人划船回到左岸

总共有10种操作

F={P10, P20, P11, P01, P02, Q 10, Q 20, Q11, Q 01, Q 02}

③控制策略

最短路径有4条,由11次操作构成。

(P11、Q10、P02、Q01、P20、Q11、P20、Q01、P02、Q01、P02)
(P11、Q10、P02、Q01、P20、Q11、P20、Q01、P02、Q10、P11)
(P02、Q01、P02、Q01、P20、Q11、P20、Q01、P02、Q01、P02)
(P02、Q01、P02、Q01、P20、Q11、P20、Q01、P02、Q10、P11)

④状态空间图

状态空间图是一个有向图,图中的节点代表状态,节点之间的连线代表操作,箭头代表状态的转换方向。

package cn.itAI.YeRenAndXiuDaoShi;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;/*** 野人与修道士* @author **/
/*** 数据结构分析:使用List对象存储code节点信息* @author dell-**/
public class Main {static int N;//N个野人,N个修道士static int K;//船上至多有K个人static int count=0;static List<code>s=new ArrayList<code>();public static void main(String[] args) {Scanner in=new Scanner(System.in);System.out.println("请输入野人/传教士:");N=in.nextInt();System.out.println("请输入船至多载人的个数:");K=in.nextInt();code c=new code(N,N,1);//1:船在左岸 0:船在右岸s.add(c);bfs(c);System.out.println("count:"+count);}public static boolean check(List<code>s,code c){//合法状态的判断//1.不可重复if(!s.isEmpty()){//包含此元素,表中含重复元素for(int i=0;i<s.size();i++){if(s.get(i).Boat==c.Boat&&s.get(i).leftC==c.leftC&&s.get(i).leftM==c.leftM){return false;}}}//2.是否满足m>=cif((c.leftM!=0&&c.leftM<c.leftC)){//((N-c.leftM!=0)&&(N-c.leftM<c.leftC))){return false;}if((N-c.leftM!=0)&&(N-c.leftM<N-c.leftC)){return false;}return true;}/*** 深搜:输出所有满足序列*/public static void bfs(code c){if(c.leftC==0&&c.leftM==0&&c.Boat==0){for(int i=0;i<s.size();i++){s.get(i).toGetString();}count++;System.out.println("==============================");return;}/*** 判断船上至多野人和修道士的数量*/int k,k1;if(c.Boat==1){k=c.leftM>=K?K:c.leftM;k1=c.leftC>=K?K:c.leftC;}else{k=(N-c.leftM)>=K?K:(N-c.leftM);k1=(N-c.leftC)>=K?K:(N-c.leftC);}/*** 枚举过河的所有情况*/for(int i=0;i<=k;i++){int m=i;//船上修道士数量for(int j=0;j<=((K-m)>=k1?k1:(K-m));j++){int n=j;//船上野人数量int tleftM,tleftC,tflag;if(m==0&&n==0) continue;code ct;if(c.Boat==1){//当前状态是合法条件,船在左岸可以开往右岸tflag=0;//m,n是船上的野人和修道士tleftM=N-((N-c.leftM)+m);//tleftC=N-((N-c.leftC)+n);ct=new code(tleftM,tleftC,tflag);if(check(s,ct)){s.add(ct);//加入表bfs(ct);s.remove(ct);//回溯}  }else{//右岸-》左岸tflag=1;tleftM=N-((N-c.leftM)-m);tleftC=N-((N-c.leftC)-n);ct=new code(tleftM,tleftC,tflag);if(check(s,ct)){s.add(ct);bfs(ct);s.remove(ct);}                           }}}return ;}    }
class code{int leftM;//左岸修道士int leftC;//左岸野人int Boat;//船的状态public code(int leftM,int leftC,int Boat){this.leftC=leftC;this.leftM=leftM;this.Boat=Boat;} public void toGetString(){System.out.print("修道士:"+this.leftM+" 野人: "+this.leftC+" 船的方向:");if(this.Boat==1){System.out.println("左岸-->右岸");}else{System.out.println("右岸-->左岸");}}
}

状态空间表示法----野人与修道士相关推荐

  1. 修道士和野人java_野人与修道士问题——详细分析与C++源代码

    前言:这一个经典的问题,可以把问题转换成数据结构中的 图 来解决.本博客节选自我去年7月份的数据结构报告 问题描述 假设有 n 个修道士和 n 个野人准备渡河,但只有一条能容纳 c 人的小船,为了防止 ...

  2. 修道士和野人java_修道士和野人问题

    休闲时刻看看神经网络方面的书,发现了修道士和野人的问题,不禁勾引起我写算法的欲望,曾经的三只大老虎三只小老虎过河问题.人狼羊白菜过河问题.汉诺塔.哈夫曼等等各种算法瞬间在脑海中约隐约现,修道士和野人问 ...

  3. 修道士和野人java_修道士与野人问题(BFS广度搜索)

    #include "iostream.h" #include "string.h" //定义一个状态节点 typedef struct //存储各个状态 { i ...

  4. C++习题:野人与修道士过河问题

    河的左岸有3个野人和3个修道士以及一条小船,修道士们想用这条小船把所有的人都运到河的右岸,但又受到以下限制: 1.修道士和野人都会划船,但船一次只能载2人: 2.在任何岸边,野人数不能超过修道士数,否 ...

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

    目录 一.状态空间表示法回顾 1.问题状态空间的构成 2.用状态空间表示问题的步骤 二.使用状态空间法求解修道士与野人问题 1.问题描述 2.状态空间求解步骤 总结 一.状态空间表示法回顾 状态空间表 ...

  6. 1. A星算法解决修道士与野人问题

    A星算法解决修道士与野人问题 1. 运行环境 CPU:I5-10400 内存:16GB 系统:Win10 64位专业版,20H2 IDE:Vistual Studio 2019专业版 2. 问题描述 ...

  7. 修道士与野人问题——C++源代码,伪代码,详细分析

    前言:这一个经典的问题,可以把问题转换成数据结构中的 图 来解决.本博客节选自我去年7月份的数据结构报告 问题描述 假设有 n 个修道士和 n 个野人准备渡河,但只有一条能容纳 c 人的小船,为了防止 ...

  8. 使用dfs求解修道士和野人问题

    原文链接: 使用dfs求解修道士和野人问题 上一篇: js Set 的使用 下一篇: VMware 挂载U盘 1.问题描述 :这是一个古典问题.假设有n个道士和n个野人准备渡河.但只有一条能容纳c人的 ...

  9. JAVA野人_修道野人 用谓词表示法表示修道士和野人的问题 在河的左岸有三个修道士 联合开发网 - pudn.com...

    修道野人 所属分类:Java编程 开发工具:Java 文件大小:47KB 下载次数:74 上传日期:2004-11-22 12:41:37 上 传 者:xiaohui_82 说明:  用谓词表示法表示 ...

最新文章

  1. linuxquot;/quot;分区名称,linux分区,磁盘系统的管理,文件系统制作
  2. timestamp(6) oracle计算差值_Oracle 计算两个时间的差值
  3. 中越跨国结婚需要什么条件和手续
  4. 深入理解Linux IO复用之epoll
  5. 关于windows消息机制的猜想
  6. ASP.NET Core Identity 实战(3)认证过程
  7. 暗黑破坏神(背包)(内部模拟)
  8. Nginx windows安装部署
  9. 资深面试官解答:大厂月薪过20K的测试工程师,都需要满足哪些要求?
  10. YALMIP学习(一):入门
  11. 神朔 计算机联锁,计算机联锁系统集中操控方式在宁东铁路中的应用
  12. 架构设计 例子和实践 系统设计说明书
  13. 【Java基础】Java集合、泛型和枚举
  14. 我努力了18年,不是为了和你一起喝咖啡姐妹篇
  15. 做一个模仿Windows画板喷漆笔刷效果
  16. 爬虫学习笔记1:爬虫基本概念
  17. 【神经网络架构】Pyramid Convolution(金字塔卷积模块)论文笔记
  18. 树莓4派开机动画_最贵的树莓派单板计算机!8GB内存单板树莓派4上市,售价532元...
  19. python展望_对于Python学习的展望
  20. 玩乐购与京东天猫深度合作 打造云购全网最低价

热门文章

  1. B2B网站排名显示前十名皆出自亚洲
  2. 2019年地理信息产业大会(珠海)信息解读
  3. Android View Binding使用介绍
  4. 黑莓CEO程守宗称转型已完成三分之二
  5. 封闭基金周折价排行表(20060901)[ZT]
  6. 『煮酒论史』 [近代风云]国军抗战的历史,十分震惊
  7. MS SQL 分类汇总参数 grouping(**)=1 rollup cubt
  8. 《奔跑吧Ansible》
  9. 【路径规划】基于卡尔曼滤波、三次插值实现极速赛道赛车路径规划附matlab代码
  10. android root权限破解分析