商人过河实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数学模型实验—实验报告6
学院:工商学院专业:电气二类(计算机)姓名:辛文辉尚磊张亨
学号:___ 2012484019 2012484091 2012484055 ____ 实验时间:__ 3.18 ____ 实验地点:b3
一、实验项目:
Matlab程序设计
安全渡河问题可以看成一个多步决策过程。每一步,即船由此岸驶向彼岸或从彼岸驶回此岸,都要对船上的人员(商人随从各几人)作出决策,在保证安全的前提下(两岸的商人数都不比随从数少),在有限步内使人员全部过河。用状态(变量)表示某一岸的人员状况,决策(变量)表示船上的人员状况,可以找出状态随决策变化的规律。问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到渡河的目的。
此类智力问题经过思考,可以拼凑出一个可行方案。但是,我们现在希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。
二、实验目的和要求
a.了解Matlab程序设计有关基本操作
b.掌握有关程序结构
三、实验内容
允许的状态向量
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10
0 11
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 0
11 1
11 2
11 3
11 4
11 5
11 6
11 7
11 8
11 9
11 10
允许的决策向量:
0 1
0 2
0 3
0 4
0 5
0 6
1 0
1 1
2 0
2 1
2 2
3 0
3 1
3 2
3 3
4 0
4 1
4 2
5 0
5 1
6 0
过河步骤:
第1步:0商5仆过河,0商1仆返回
第2步:5商1仆过河,1商1仆返回
第3步:3商3仆过河,1商1仆返回
第4步:3商3仆过河,1商1仆返回
第5步:3商3仆过河,完成
过河过程中状态变化:
步骤此岸商此岸仆方向彼岸商彼岸仆
1 11 6 ==> -8 -3
11 7 <== -8 -4
2 6 6 ==> -
3 -3
7 7 <== -4 -4
3 4 4 ==> -1 -1
5 5 <== -2 -2
4 2 2 ==> 1 1
3 3 <== 0 0
5 0 0 ==> 3 3
对于经典的3对商仆、小船容量为2人时的问题,运行程序求得结果如下
11对商仆,小船容量为6人时,运行程序求得结果如下:
图 3 11对商仆、小船容量为6时的求解结果
事实上,11对商仆时的状态空间如图:
图 4 12对商仆时的状态空间
显然的船容量必须至少保证状态转移能够沿对角线方向向下移动,问题才会有解。船容量为2时可以使状态转移沿对角线移动,但不能持续向下移动,船容量至少为4才可使状态能够沿对角线向下移动。
下面说明何时需要状态空间沿对角线移动。当商仆对数为6时,状态空间为:
图 5 6对商仆时的状态空间
此时状态中心(3,3)距离边界状态(6,3)的距离为3,船容量至少为4才可避免状态转移沿对角线下行,而船容量为4已经是状态转移沿对角线移动的条件,即当商仆对数大于等于6时,船容量至少为4,问题有解。不难说明,当商仆对数为4或5时,所需的
最小船容量为3。综上,使问题有解的商仆对数与船容量之间的关系如下:
表 1 商仆对数与船容量的关系
商仆对数小船容量
1、2、3 ≥2
4、5 ≥3
≥6 ≥4
从图中可以看出,商仆对数为3,容量为2,3,4,5,6的时候,均可以安全过河。当容量为2时并且有4种方式。
通过计算机运行此c++程序,当题目中给定出任意数量的商人,随从,以及规定出任意船的容量,都可以判断出“商人们能否安全渡河?”以及解决“如果能,那么安全渡河的方案是什么?”的问题。从而使这个模型更具有一定的推广价值。
.附件
n=input('输入商人数目: ');
m=input('输入仆人数目: ');
h=input('输入船的最大容量: ');
m0=0;n0=0;
LS=0; % 允许的状态集合S与个数LS
LD=0; % 允许的决策集合D与个数LD
for i=0:n
for j=0:m
if i>=j&n-i>=m-j|i==n|i==0
LS=LS+1;S(LS,:)=[i j];
end
if i+j>0&i+j<=h&(i>=j|i==0)
LD=LD+1;D(LD,:)=[i j];
end
end
end% 用搜寻法找出符合条件的渡河方案
N=15;
Q1=inf*ones(2*N,2*N);
Q2=inf*ones(2*N,2*N);
t=1;le=1;
q=[m n];f0=0; % 判断循环终止标记
while f0~=1&t k=1; sa=[]; sb=[]; for i0=1:le % 第n次允许的策略集逐次搜索 s0=q(i0,:); if f0==1 break end for i=1:LD % 由s0搜索D后得到允许的状态 s1=s0+(-1)^t*D(i,:); if s1==[m0,n0] sa=[m0,n0]; sb=D(i,:); f0=1; break end for j=2:LS-1 % 搜索对比S后允许状态 if s1==S(j,:) if k==1 sa(k,:)=s1; sb(k,:)=D(i,:); k=k+1; break end if k>1 % 对重复状态删除处理 f1=0; for ii=1:k-1 if s1==sa(ii,:) f1=1; break