MC牧师过河问题

合集下载

传教士和野人问题

传教士和野人问题

传教士和野人问题(Missionaries and Cannibals)

传教士和野人问题是一个经典的智力游戏问题。在这个问题中,实际上隐含了这样一个条件:如果在河

的某一岸只有野人,而没有传教士,也同样被认为是合法状态。在具体书写某些条件时,为了简便,这一

点有时并没有考虑,但我们默认这个条件是被考虑了的。

有N个传教士和N个野人来到河边准备渡河,河岸有一条船,每次至多可供k人乘渡。问传教士为了安全起见,应如何规划摆渡方案,使得任何时刻,在河的两岸以及船上的野人数目总是不超过传教士的数目。即求解传教士和野人从左岸全部摆渡到右岸的过

程中,任何时刻满足M(传教士数)≥C(野人数)和M+C≤k的摆渡方案。

设N=3,k=2,则给定的问题可用图1.2

表示,图中L和R表示左岸和右岸,B=1或0分别表示有船或无船。约束条件是:两岸上M≥C,船上M+C≤2。

图1.2 M-C问题实例

由于传教士和野人数是一个常数,所以知道了一岸的情况,另一岸的情况也就知道了。因此为了简便

起见,在描述问题时,只描述一岸--如左岸--的情况就可以了。

另外,该问题我们最关心的是在摆渡过程中,两岸状态的变化情况,因此船上的情况并不需要直接表

达出来。在一次摆渡过程中,船上究竟有几个传教士和野人,可以通过两个相连的状态简单得到。这样表

达更简练,突出了问题的重点。

(1)综合数据库:用三元组表示左岸的情况,即

(,,),其中0≤,≤3,∈{0,1},其中表示在左岸的传教士人数,表示在左岸的野人数,=1表示船在左岸,=0表示船在右岸。则此时问题描述可以简化为:

传教士野人过河问题-两种解法思路

传教士野人过河问题-两种解法思路

实验 传教士野人过河问题

37030602 王世婷

一、实验问题

传教士和食人者问题(The Missionaries and Cannibals Problem )。在河的左岸有3个传教士、1条船和3个食人者,传教士们想用这条船将所有的成员运过河去,但是受到以下条件的限制:(1)传教士和食人者都会划船,但船一次最多只能装运两个;(2)在任何岸边食人者数目都不得超过传教士,否则传教士就会遭遇危险:被食人者攻击甚至被吃掉。此外,假定食人者会服从任何一种过河安排,试规划出一个确保全部成员安全过河的计划。

二、解答步骤

(1) 设置状态变量并确定值域

M 为传教士人数,C 为野人人数,B 为船数,要求M>=C 且M+C <= 3,L 表示左岸,R 表示右岸。 初始状态 目标状态

L R L R

M 3 0 M 0 3

C 3 0 C 0 3

B 1 0 B 0 1

(2) 确定状态组,分别列出初始状态集和目标状态集

用三元组来表示f S :(ML , CL , BL )(均为左岸状态)

其中03,03ML CL ≤≤≤≤,BL ∈{ 0 , 1}

0S :(3 , 3 , 1) g S : (0 , 0 , 0)

初始状态表示全部成员在河的的左岸;

目标状态表示全部成员从河的左岸全部渡河完毕。

(3) 定义并确定规则集合

仍然以河的左岸为基点来考虑,把船从左岸划向右岸定义为Pij 操作。其中,第一下标i 表示船载的传教士数,第二下标j 表示船载的食人者数;同理,从右岸将船划回左岸称之为Qij 操作,下标的定义同前。则共有10种操作,操作集为

传教士过河答案

传教士过河答案

有三个食人族人和三个传教士要过河,现在只有一条船,但一次只能载两个人,而无论在河的哪一边,只要食人族人比传教士多,食人族人就会把传教士吃掉。问他怎么样才能安全的过河?

设:要从河的a岸到河的b岸。

1、一食人族和一传教士开船过河,到了b岸后食人族留在河的b岸,传教士把船开回a岸;(现在是三个传教士和两个食人族在a岸,一食人族在b岸)。

2、船开回a岸后,两个食人族开船过河,到了b岸后,一食人族留在河的b岸,让一名食人族把船开回a岸;(现在是三个传教士和一个食人族在a岸,两个食人族在b岸)

3、其中一食人族把船开回a岸后,食人族下船,让两名传教士开船过河,过河后(到b岸后)又让一食人族和一传教士把船开a岸;(现在是两个传教士和两个食人族在a岸,一传教士一食人族在b岸)

4、船到a岸后,让两个传教士开船过河,到了b岸后,传教士下船让在b岸的那个食人族把船开回a岸;(现在是三传教士在b岸,三食人族在a岸)

5、船回到a岸后,两食人族过河,到b岸后一食人族把船开回a岸,再两食人族开船渡河。

MC牧师过河问题

MC牧师过河问题

MC牧师过河问题

⼈⼯智能上机实验报告

学号:姓名:所在系:信息学院班级:

实验名称:实验⽇期2016年12⽉3⽇

实验指导教师实验机房A401

------------------------------------------------------------------------------------------------------ 1.实验⽬的:

(1)在掌握状态空间搜索策略的基础上,理解知识表⽰的⽅法。

(2)能够应⽤知识表⽰⽅法,解决实际问题

2. 实验内容:

(1)M-C问题描述

有n个牧师和n个野⼈准备渡河,但只有⼀条能容纳c个⼈的⼩船,为了防⽌野⼈侵犯牧师,要求⽆论在何处,牧师的⼈数不得少于野⼈的⼈数(除⾮牧师⼈数为0),且假定野⼈与牧师都会划船,试设计⼀个算法,确定他们能否渡过河去,若能,则给出⼩船来回次数最少的最佳⽅案。

3.算法设计(编程思路或流程图或源代码)

#include

#include

#include

#define maxloop 100 /* 最⼤层数,对于不同的扩展⽅法⾃动调整取值*/

#define pristnum 3 /*初始化时设定有3个野⼈3个牧师,实际可以改动*/

#define slavenum 3

struct SPQ

{ int sr,pr; /* 船运⾏⼀个来回后河右岸的野⼈、牧师的⼈数*/

int sl,pl; /* 船运⾏⼀个来回后河左岸的野⼈、牧师的⼈数*/

int ssr,spr; /* 回来(由左向右时)船上的⼈数*/

int sst,spt; /* 去时(由右向左时)船上的⼈数*/

C++实现传教士与野人过河问题实验报告

C++实现传教士与野人过河问题实验报告

传教士与野人过河问题实验报告

1 问题定义

河的两岸有三个传教士和三个野人需要过河,目前只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于传教士的人数,那么传教士就会被野人攻击,怎么找出一种安全的渡河方案呢?

2 算法分析

首先,先来看看问题的初始状态和目标状态,定义河的两岸分别为左岸和右岸,设定状态集合为(左岸传教士人数,右岸野人数,右岸传教士人数,右岸野人数,船的位置),船的位置:-1表示船在左岸,1表示船在右岸。

初始状态:(3,3,0,0,0,-1)

目标状态:(0,0,3,3,1)

然后,整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):

渡1野人、渡1传教士、渡1野人1传教士、渡2野人、渡2传教士根据船的位置,向左移或向右移通过递归依次执行5种算符,判断是否找到所求,并排除不符合实际的状态,就可以找到所有可能的解,如图1所示为递归函数流程图。

数据结构方面采用如下所示的结构体存储当前传教士、野人、船三者的状态。struct riverSides {

int churchL;//左岸传教士数

int wildL;//左岸野人数

int churchR; //右岸传教士数

int wildR; //右岸野人数

int boat;//船的位置,-1在左岸,1在右岸

};

图 1 传教士与野人过河递归函数流程图

3 编程实现

牧师与野人课程设计

牧师与野人课程设计

数据结构课程设计报告

设计题目: 牧师和野人问题

院系:经济管理学院

专业班级:电子商务2010-2

学生姓名:孙印民、王倩、续琳琳

指导教师:周长红

2012年7月6日

指导教师评语

指导教师:

年月日

成绩评定

学号姓名任务分工成绩1001060423 孙印民概要、详细设计、调试分析、测试结果1001060429 王倩设计内容、总结、排版

1001060433 续琳需求分析、设计成果展示、总结、排版

目录

1.设计内容

1.1

1.4研究思路

有N1个牧师和N2个野人来到河边准备渡河,河岸有一条船,每次至多可供M人乘渡。问牧师为了安全起见,应如何规划摆渡方案,使得任何时刻,在河的两岸以及船上的野人数目总是不超过牧师的数目。即求解牧师和野人从左岸全部摆渡到右岸的过程中,任何时刻满足N1(牧师数)≥N2(野人数)和N1+N2≤M的摆渡方案。

首先从比较简单的入手,先设N1=N2=3,M=2,则给定的问题可用图1.2表示,图中L和R表示左岸和右岸,B=1或0分别表示有船或无船。约束条件是:两岸上N1≥N2,船上N1+N2≤2。

图1.2 N1-N2问题实例

由于牧师和野人数是一个常数,所以知道了一岸的情况,另一岸的情况也就知道了。因此为了简便起见,在描述问题时,只描述一岸(如左岸)的情况就可以了。

另外,该问题我们最关心的是在摆渡过程中,两岸状态的变化情况,因此船上的情况并不需要直接表达出来。在一次摆渡过程中,船上究竟有几个牧师和野人,可以通过两个相连的状态简单得到。这样表达更简练,突出了问题的重点。

(1)综合数据库:用三元组表示左岸的情况,即(N1,N2,B),其中0≤N1,N2≤3,B∈{0,1},其中N1表示在左岸的牧师人数,N2表示在左岸的野人数,B=1表示船在左岸,B=0表示船在右岸。则此时问题描述可以简化为:(3,3,1)→(0,0,0)N=3的N1-N2问题,状态空间的总状态数为4×4×2=32,根据约束条件的要求,可以看出只有20个合法状态。再进一步分析后,又发现有4个合法状态实际上是不可能达到的。因此实际的问题空间仅由16个状态构成。下表列出分析的结果:

野人过河问题算法分析

野人过河问题算法分析

野人过河问题算法分析

野人过河问题属于人工智能学科中的一个经典问题,问题描述如下:有三个牧师(也有的翻译为传教士)和三个野人过河,只有一条能装下两个人的船,在河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险. 你能不能找出一种安全的渡河方法呢?

一、算法分析

先来看看问题的初始状态和目标状态,假设和分为甲岸和乙岸:初始状态:甲岸,3野人,3牧师;

乙岸,0野人,0牧师;

船停在甲岸,船上有0个人;

目标状态:甲岸,0野人,0牧师;

乙岸,3野人,3牧师;

船停在乙岸,船上有0个人;

整个问题就抽象成了怎样从初始状态经中间的一系列状态达到目标状态。问题状态的改变是通过划船渡河来引发的,所以合理的渡河操作就成了通常所说的算符,根据题目要求,可以得出以下5个算符(按照渡船方向的不同,也可以理解为10个算符):

渡1野人、渡1牧师、渡1野人1牧师、渡2野人、渡2牧师算符知道以后,剩下的核心问题就是搜索方法了,本文采用深度优先搜索,通过一个FindNext(…)函数找出下一步可以进行的渡河操作中的最优操作,如果没有找到则返回其父节点,看看是否有其它兄弟节点可以扩展,然后用Process(…)函数递规调用FindNext(…),一级一级的向后扩展。

搜索中采用的一些规则如下:

1、渡船优先规则:甲岸一次运走的人越多越好(即甲岸运多人优先),同时野人优先运走;

乙岸一次运走的人越少越好(即乙岸运少人优先),同时牧师优先运走;

2、不能重复上次渡船操作(通过链表中前一操作比较),避免进入死循环;

3、任何时候河两边的野人和牧师数均分别大于等于0且小于等于3;

野人和传教士过河问题的实现1

野人和传教士过河问题的实现1
{"code":"InvalidRange","message":"The reque来自百度文库ted range cannot be satisfied.","requestId":"74dc96bc-157d-4524-b6c9-8e19142b69c9"}

第04章三种基本控制结构(上)--2012年12月

第04章三种基本控制结构(上)--2012年12月

return 0; /* 返回语句 */
}
总结两个变量的交换算法
不能完成交换: a = b; b = a;
43
3
出错
a
b
总结两个变量的交换算法
完成交换: temp = a; a = b; b = temp;
4
4
3
temp
a
b
正确
如何判断一个算法(程序)的优劣?
需要考虑两个方面的问题: 一、保证算法正确:如果一个算法对其每一个输
化为0,表示存放酱油*/
int b = 1; /* 定义变量b表示杯子b ,并初始
化为1,表示存放醋*/
int c;
/* 定义新杯子 */
c = a;
/* c和a中都是0 */
a = b; /* a和b中都是1 */
b = c; /* b和c中都是0 */
/* 输出a和b,检验是否完成交换*/
printf (“a: %d b: %d\n”,a,b);
注意:%d %o %0x 是按整型数据在内存中的二进 制存储格式进行十进制、八进制、十六进制换算后 的格式输出。
4. u 格式符:输出无符号型十进制数据。
格式
功能
%u
按无符号整型数据格式和数据的实际长度输出
%lu
按无符号长整型数据格式和数据的实际长度输出

野人传教士过河问题

野人传教士过河问题

一、对N=5、k≤3时,求解传教士和野人问题的产生式系统各组成部分进行描述(给出综合数据库、规则集合的形式化描述,给出初始状态和目标条件的描述),并画出状态空间图。答:用M表示传教士,C表示野人,B表示船,L表示左岸,R表示右岸。

初始状态:

目标状态:

1,综合数据库

定义三元组:(M,C,B)

其中:0=

0=

B l属于集合(0,1),B l=1,表示船在左岸,B l=0,表示船在右岸。

2,规则集

规则集可以用两种方式表示,两种方法均可。

按每次渡河的人数分别写出每一个规则,共(3 0)、(0 3)、(2 1)、(1 1)、(1 0)、(0 1)、(2 0)、(0 2)八种渡河的可能(其中(x y)表示x个传教士和y个野人上船渡河),因此共有16个规则(从左岸到右岸、右岸到左岸各八个)。注意:这里没有(1 2),因为该组合在船上的传教士人数少于野人人数。

规则集如下:

IF (M l, C l, 1) THEN (M l -3, C l, 0) p30

IF (M l, C l, 1) THEN (M l, C l -3, 0) p03

IF (M l, C l, 1) THEN (M l -2, C l -1, 0) p21

IF (M l, C l, 1) THEN (M l -1, C l -1, 0) p11

IF (M l, C l, 1) THEN (M l -1, C l, 0) p10

IF (M l, C l, 1) THEN (M l, C l -1, 0) p01

IF (M l, C l, 1) THEN (M l -2, C l, 0) p20

牧师与野人课程设计

牧师与野人课程设计

数据结构课程设计报告

设计题目: 牧师和野人问题

院系:经济管理学院

专业班级:电子商务2010-2

学生姓名:孙印民、王倩、续琳琳

指导教师:周长红

2012年7月6日

指导教师评语

指导教师:

年月日

成绩评定

学号姓名任务分工成绩1001060423 孙印民概要、详细设计、调试分析、测试结果1001060429 王倩设计内容、总结、排版

1001060433 续琳琳需求分析、设计成果展示、总结、排版

目录

1. 设计内容 (1)

1.1问题描述 (1)

1.2设计要求 (1)

1.3开发环境 (1)

1.4研究思路 (1)

2. 设计步骤 (4)

2.1需求分析\ (4)

2.2概要设计 (4)

2.3详细设计 (6)

2.4调试分析 (14)

2.5测试结果 (16)

3.设计成果展示 (16)

3.1用户手册 (16)

3.2程序运行部分截图 (17)

4.总结与心得体会 (20)

附录 (22)

1.设计内容

1.1问题描述

有三个牧师和三个野人过河,只有一条能装下两个人的船,在河的任一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险。你能不能找出一种安全的渡河方法呢?这个问题还可以扩展为N1个牧师和N2个野人,而船一次可以装下M个人的情况。

1.2设计要求

(1)给出可能的方法总数,并描述每种方法的具体实现过程;

(2)当输入N1,N2,M的值时,输出程序的运行结果。

1.3开发环境

C-free

1.4研究思路

有N1个牧师和N2个野人来到河边准备渡河,河岸有一条船,每次至多可供M人乘渡。问牧师为了安全起见,应如何规划摆渡方案,使得任何时刻,在河的两岸以及船上的野人数目总是不超过牧师的数目。即求解牧师和野人从左岸全部摆渡到右岸的过程中,任何时刻满足N1(牧师数)≥N2(野人数)和N1+N2≤M的摆渡方案。

3.2 信息的编程加工

3.2 信息的编程加工
3.2 信息的编程加工
1
野人过河的故事
问题描述如下:
有三个牧师和三个野人过河,只有一条能装下两 个人的船,在河的任何一方或者船上,如果野人的人 数大于牧师的人数,那么牧师就会有危险。 你能不 能找出一种安全的渡河方法呢?
2
渡河的方法与步骤
第一步:去两野人; 第二步:回一野人; 第三步:去两个野人; 第四步:回 1 野人; 第五步:去 2 牧师; 第六步:回 1 牧师 1 野人; 第七步:去 2 牧师; 第八步:回 1 野人; 第九步:去 2 野人; 第十步:回 1 野人; 第十一步:去 2 野人。
m x y
6
算法的流程图描述
7
算法的流程图描述
图形符号 名称 起止框 输入、输出框
处理框 判断框 带箭头的流线
说明
表示一个算法的开始或结 束
框内标明输入、输出内容
框内标明所进行的处理
框内标明判断条件,框外标明 条件成立或不成立的不同流向
表示从某一框到另一框的 流向
8
思考:我们学过用描点法画抛物线,具体的过程怎样?
12
信息的编程加工过程
分析问题 算法设计 编程实现 调试运行
13
思考,并做一做
Private Sub cmdSwap_Click() Dim x As Single, y As Single

传教士野人过河问题-两种解法思路

传教士野人过河问题-两种解法思路

实验 传教士野人过河问题

37030602 王世婷

一、实验问题

传教士和食人者问题(The Missionaries and Cannibals Problem )。在河的左岸有3个传教士、1条船和3个食人者,传教士们想用这条船将所有的成员运过河去,但是受到以下条件的限制:(1)传教士和食人者都会划船,但船一次最多只能装运两个;(2)在任何岸边食人者数目都不得超过传教士,否则传教士就会遭遇危险:被食人者攻击甚至被吃掉。此外,假定食人者会服从任何一种过河安排,试规划出一个确保全部成员安全过河的计划。

二、解答步骤

(1) 设置状态变量并确定值域

M 为传教士人数,C 为野人人数,B 为船数,要求M>=C 且M+C <= 3,L 表示左岸,R 表示右岸。 初始状态 目标状态

L R L R

M 3 0 M 0 3

C 3 0 C 0 3

B 1 0 B 0 1

(2) 确定状态组,分别列出初始状态集和目标状态集

用三元组来表示f S :(ML , CL , BL )(均为左岸状态)

其中03,03ML CL ≤≤≤≤,BL ∈{ 0 , 1}

0S :(3 , 3 , 1) g S : (0 , 0 , 0)

初始状态表示全部成员在河的的左岸;

目标状态表示全部成员从河的左岸全部渡河完毕。

(3) 定义并确定规则集合

仍然以河的左岸为基点来考虑,把船从左岸划向右岸定义为Pij 操作。其中,第一下标i 表示船载的传教士数,第二下标j 表示船载的食人者数;同理,从右岸将船划回左岸称之为Qij 操作,下标的定义同前。则共有10种操作,操作集为

传教士野人过河问题-两种解法思路

传教士野人过河问题-两种解法思路

实验 传教士野人过河问题

37030602 王世婷

一、实验问题

传教士和食人者问题(The Missionaries and Cannibals Problem )。在河的左岸有3个传教士、1条船和3个食人者,传教士们想用这条船将所有的成员运过河去,但是受到以下条件的限制:(1)传教士和食人者都会划船,但船一次最多只能装运两个;(2)在任何岸边食人者数目都不得超过传教士,否则传教士就会遭遇危险:被食人者攻击甚至被吃掉。此外,假定食人者会服从任何一种过河安排,试规划出一个确保全部成员安全过河的计划。

二、解答步骤

(1) 设置状态变量并确定值域

M 为传教士人数,C 为野人人数,B 为船数,要求M>=C 且M+C <= 3,L 表示左岸,R 表示右岸。 初始状态 目标状态

L R L R

M 3 0 M 0 3

C 3 0 C 0 3

B 1 0 B 0 1

(2) 确定状态组,分别列出初始状态集和目标状态集

用三元组来表示f S :(ML , CL , BL )(均为左岸状态)

其中03,03ML CL ≤≤≤≤,BL ∈{ 0 , 1}

0S :(3 , 3 , 1) g S : (0 , 0 , 0)

初始状态表示全部成员在河的的左岸;

目标状态表示全部成员从河的左岸全部渡河完毕。

(3) 定义并确定规则集合

仍然以河的左岸为基点来考虑,把船从左岸划向右岸定义为Pij 操作。其中,第一下标i 表示船载的传教士数,第二下标j 表示船载的食人者数;同理,从右岸将船划回左岸称之为Qij 操作,下标的定义同前。则共有10种操作,操作集为

教学设计:计算机解决问题的过程

教学设计:计算机解决问题的过程

课题:计算机解决问题的过程

标准模块:选修· 算法与程序设计

教材:教育科学出版社《算法与程序设计》第一章第一节计算机解决问题的过程课时安排:1课时

【教学目标】

1.知识与技能:

①知道人类是如何分析问题、解决问题的;

②了解用计算机解决问题的基本步骤;

③体验用计算机编程解决问题的一般过程;

④熟悉Scratch软件的基本界面,学会用Scratch语言编写接球小游戏。

2.过程与方法:

①借助现实生活中的多媒体技术应用实例,了解多媒体技术表达信息的过程与方法;

②培养学生用正确的方法处理解决问题。

3.情感态度和价值观

培养学生的高阶思维能力,如综合、评价、分析、思辨等。

【教学重点和难点】

计算机编程解决问题的过程体验,以及用Scratch语研设计和编写程序。

【教学过程】

探究任务一:了解人是如何解决问题的?通过解决“过河”问题,思考人分析、解决问题的过程。

“过河”问题:三个牧师和三个野人过河,只有一条能装下两人的船,在河的任一边或者船上,若野人人数大于牧师人数,那么牧师就会有被吃掉的危险。你能不能找出一种安全的渡河方法呢?

探究任务二:了解用计算机解决问题的基本步骤,了解用计算机编程解决问题的一般步过程。

(1)完成连线题:

⏹用计算机写一篇文稿⏹Photoshop、美图秀秀等

(2)总结用计算机解决问题的步骤,以及用计算机编程解决问题的一般过程:

探究任务三:通过具体实例接球小游戏的编写,体验用计算机编程解决问题的一般过程。

●具体任务:用scratch语言编写接球小游戏。

●基本步骤:

1)运行游戏,对游戏基本功能进行分析;

人工智能+野人传教士过河问题c程序+深度优先

人工智能+野人传教士过河问题c程序+深度优先

//******************************问题描述***************************************//有三个牧师(也有的翻译为传教士)和三个野人过河,只有一条能装下两个人的船,在//河的任何一方或者船上,如果野人的人数大于牧师的人数,那么牧师就会有危险.//初始状态:左岸,3野人,3牧师;// 右岸,0野人,0牧师;// 船停在左岸,船上有0个人//目标状态:左岸,0野人,0牧师;// 右岸,3野人,3牧师;// 船停在右岸,船上有0个人;//****************************************************************************** #include #include #define MAX 50 //定义open数组的大小 open数组用来存储所有出现的合法状态 #define MAX1 5 //定义 boatState数组的大小 boatState数组用来存储求解过程中合法的算符 #define M 3 //定义野人的数目 #define C 3 //定义传教士的数目 #define B 2 //定义船的容量 #define S -1 //定义船在哪岸 -1代表左 1代表右 void expand(); //声明函数 void find();struct state //定义结构体 存储当前状态 其中m表示野人数 c表示传教士数 s表示船在哪岸{ // f标记该状态是否被扩展过 pre指向该状态的前一状态 int m; int c;int s;int f;struct state *pre; };struct boat //定义结构体 存储算符 m表示船要运走的野人数 c表示要运走的传教士数 {int m;int c; };struct state open[MAX];//定义open数组和boatState数组struct boat boatState[MAX1]; int top=0; //定义open数组的下标 指向最后一个元素 int sum=0; //用来存储解的个数 int j=-1; //用来存储算符的个数 //*********************************************************************************void inist() //初始化算符 {int m;int c; for(m=0;m<=M;m++){for(c=0;c<=C;c++){ if((m <= c || c == 0) && (m+c)<=B && (m || c)){j++;boatState[j].m = m;boatState[j].c = c; }} }}//*******************************************************************************int goal(struct state * p) //判断当前状态是否目标状态 {if(p->m==0&&p->c==0&&p->s==1) return 1;else return 0; }//******************************************************************************void print(struct state * p) //输出解 { printf("第%d个解是:\n",++sum);struct state * pTemp=p;struct state temp[MAX];int i=1;while(pTemp){temp[i].m=pTemp->m;temp[i].c=pTemp->c;temp[i].s=pTemp->s;i++;pTemp=pTemp->pre;}while(--i){printf("[%d,%d,%d]--",temp[i].m,temp[i].c,temp[i].s);

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

人工智能上机实验报告

学号:姓名:所在系:信息学院班级:

实验名称:实验日期2016年12月3日

实验指导教师实验机房A401

------------------------------------------------------------------------------------------------------ 1.实验目的:

(1)在掌握状态空间搜索策略的基础上,理解知识表示的方法。

(2)能够应用知识表示方法,解决实际问题

2. 实验内容:

(1)M-C问题描述

有n个牧师和n个野人准备渡河,但只有一条能容纳c个人的小船,为了防止野人侵犯牧师,要求无论在何处,牧师的人数不得少于野人的人数(除非牧师人数为0),且假定野人与牧师都会划船,试设计一个算法,确定他们能否渡过河去,若能,则给出小船来回次数最少的最佳方案。

3.算法设计(编程思路或流程图或源代码)

#include

#include

#include

#define maxloop 100 /* 最大层数,对于不同的扩展方法自动调整取值*/

#define pristnum 3 /*初始化时设定有3个野人3个牧师,实际可以改动*/

#define slavenum 3

struct SPQ

{ int sr,pr; /* 船运行一个来回后河右岸的野人、牧师的人数*/

int sl,pl; /* 船运行一个来回后河左岸的野人、牧师的人数*/

int ssr,spr; /* 回来(由左向右时)船上的人数*/

int sst,spt; /* 去时(由右向左时)船上的人数*/

int loop; /* 本结点所在的层数*/

struct SPQ *upnode ,*nextnode;/* 本结点的父结点和同层的下一个结点的地址*/

}spq;

int loopnum;/* 记录总的扩展次数*/

int openednum;/* 记录已扩展节点个数*/

int unopenednum;/* 记录待扩展节点个数*/

int resultnum;

struct SPQ *opened;

struct SPQ *oend;

struct SPQ *unopened;

struct SPQ *uend;

struct SPQ *result;

void initiate();

void releasemem();

void showresult();

void addtoopened(struct SPQ *ntx);

int search();

void goon();

int stretch(struct SPQ* ntx);

void recorder();

void addtoopened(struct SPQ *ntx) /*扩展节点*/ {

unopened = unopened -> nextnode; unopenednum--;

if (openednum == 0 )

oend = opened = ntx;

oend -> nextnode = ntx;

oend = ntx;

openednum++;

}

void recorder()

{

int i , loop;

struct SPQ *newnode;

struct SPQ *ntx;

loop = oend -> loop;

ntx = oend;

resultnum = 0;

for( i = 0 ; i <= loop ; i++ )

{

newnode = (struct SPQ*) malloc (sizeof(spq));

if(newnode==NULL)

{

printf("\n内存不够!\n");

exit(0);

}

newnode -> sr = ntx -> sr;

newnode -> pr = ntx -> pr;

newnode -> sl = ntx -> sl;

newnode -> pl = ntx -> pl;

newnode -> sst = ntx -> sst;

newnode -> spt = ntx -> spt; newnode -> ssr = ntx -> ssr; newnode -> spr = ntx -> spr; newnode -> nextnode = NULL;

ntx = ntx -> upnode;

if(i == 0)

result = newnode;

newnode -> nextnode = result; result = newnode;

resultnum++;

}

}

void releasemem()

{

int i;

struct SPQ* nodefree;

for ( i = 1 ; i < openednum ; i++ ) {

nodefree = opened;

opened = opened -> nextnode;

free(nodefree);

}

for ( i = 0 ; i < unopenednum ; i++ ) {

nodefree = unopened;

unopened = unopened -> nextnode; free(nodefree);

}

}

void showresult() /*显示*/

{

int i;

int fsr , fpr ; /* 在右岸上的人数*/ int fsl , fpl ; /* 在左岸上的人数*/ struct SPQ* nodefree;

printf("%d个牧师",result -> pr); printf("%d个野人",result -> sr); printf("%d个牧师",result -> pl); printf("%d个野人",result -> sl); for ( i = 1 ; i < resultnum ; i++ ) {

相关文档
最新文档