数学建模人狼羊菜问题
发布时间:2012-04-22 12:01:56
发布时间:2012-04-22 12:01:56
一,论文题目 人,狼,羊,菜渡河问题
二,摘要
将人狼羊菜依次用一个四维向量表示,对每一分量按二进制法则进行运算,将可行状态与转移状态表示出来,将这种运算方法设计为Matlab语言,进行计算机的计算,最终求得所得结果。
三,问题的重述
一个摆渡人希望用一条小船把一只狼,一只羊和一篮白菜从一条河的左岸渡到右岸去,而船小只能容纳人,狼,羊,菜中的两个,绝不能在无人看守的情况下,留下狼和羊或羊和白菜在一起,求应怎样渡河才能把狼羊白菜都运过去?
四,模型的假设、符号约定和名词解释
我们可以用四维向量来表示状态,其中第一分量表示人,第二分量表示狼,第三分量表示羊,第四分量表示菜;当人或物在此岸时相应分量取1,在对岸时则取0。
根据题意,人不在场时,狼要吃羊,羊要吃菜,因此,人不在场时,不能将狼与羊,羊与菜留在河的任一岸。例如,状态(0,1,1,0)表示人和菜在对岸,而狼和羊在此岸,这时人不在场的情况下狼要吃羊,因此,这个状态是不可行的。
我们通过穷举法将所有可行的状态列举出来,可行的状态有
(1,1,1,1),(1,1,1,0),(1,1,0,1),(1,0,1,1),(1,0,1,0)
(0,1,0,1),(0,1,0,0),(0,0,1,0),(0,0,0,1),(0,0,0,0)
可行状态共有十种。每一次的渡河行为改变现有的状态。
用1 表示过河,0 表示未过河。例如,(1,1,0,0)表示
人带狼过河。状态转移只有四种情况,用如下的向量表示。
(1,0,0,0),(1,1,0,0),(1,0,1,0),(1,0,0,1)
五,模型的建立、模型求解、模型的结果和检验
将可取状态及可取运载分别编成矩阵。共分为五个m文件,一个主文件xduhe.m数,分别为:
1、 duhe(L,B,M,s)函数。
用来实现渡河总思路。思路为:将起始矩阵A分别与可取运载相加(使用二进制法则),判断相加后的矩阵C是否是【0,0,0,0】,如果是,则渡河成功。否则,用fuhe(C,M) 函数判断C是否是可取状态,如果是,则打印并将C与初始矩阵合并成新矩阵,继续调用duhe.m函数。
2、 fuhe(C,M)函数。
判断和矩阵C是否属于矩阵M,如果是,则返回1,否则返回0.
3、 Panduan(S函数。
判断S矩阵中是否有两个相同的状态,即行向量。如果有,则返回0,否则返回1.
4、 print(K,C,s)函数。
打印相应的状态。
通过程序运行结果截图为:
可得两种运送方案
六,模型的评价和改进
从书中所学知识让我们了解到图解法,但对于此问题,涉及到四维向量,显然利用坐标系很难完成,所以我们采用计算机编程来得到求解,具有高效简洁的优势,利用运行结果让我们对问题的解答一目了然,改进方面,希望能尝试运用其他思路。
七,参考文献
1,姜启源、谢金星、叶俊《数学模型》(第三版),北京:高等教育出版社.
八,程序代码
1、 xduhe.m文件
clear;clc;
A=[1,1,1,1];
B=[1,0,1,0;1,1,0,0;1,0,0,1;1,0,0,0];
M=[1,1,1,0;0,0,0,1;1,1,0,1;0,0,1,0;1,0,1,1;0,1,0,0;1,0,1,0;0,1,0,1];
duhe(A,B,M,1);
2、 duhe.m文件
function duhe(L,B,M,s);
[h,l]=size(L);
for k=s:h
for i=1:4
C=mod(L(k,:)+B(i,:),2);
if C==[0,0,0,0]
print(B(i,:),C,s);
fprintf('渡河成功\n\n');
break;
else if fuhe(C,M)==1
print(B(i,:),C,s);
S=[L;C];
if Panduan(S)==1
duhe(S,B,M,s+1);
else
fprintf('此渡河方案不可行\n\n');
end
end
end
end
end
3、 fuhe.m文件
function y=fuhe(C,M)
y=0;
for i=1:8
if(C==M(i,:))
y=1;
break;
end
end
4、 Panduan.m文件
function z=Panduan(S)
z=1;
[m,n]=size(S);
for p=1:m
for q=(p+1):m
if S(p,:)-S(q,:)==[0,0,0,0]
z=0;
break;
end
end
end
5、 print.m文件
function print(K,C,s)
fprintf('第%d次渡河:',s);
if K(1)==1
fprintf('人, ');
end
if K(2)==1
fprintf('狼, ');
end
if K(3)==1
fprintf('羊, ');
end
if K(4)==1
fprintf('菜, ');
end
if C(1)==0
fprintf('从左岸到达右岸\n');
else
fprintf('从右岸回到左岸\n');
end