数学建模.docx
- 文档编号:26524770
- 上传时间:2023-06-20
- 格式:DOCX
- 页数:28
- 大小:238.92KB
数学建模.docx
《数学建模.docx》由会员分享,可在线阅读,更多相关《数学建模.docx(28页珍藏版)》请在冰豆网上搜索。
数学建模
目录
摘要关键词································2
一、模型的假设································3
二、参数······································3
三、问题分析································3
四、模型的建立及其求解························5
五、模型的检验································9
六、模型的合理性讨论··························10
七、模型的改进方向····························10
八、模型的推广································10
九、参考文献··································10
附录······································11
商仆安全过河问题
摘要
我们知道,有
队商仆过河,一只船最多载多少人,船上和岸上的仆人数不能多于商人,否则商人就会有生命危险。
便使得商人安全渡河问题的提出成为必然。
本文就经典数学建模模型“商人过河们如何能够安全过河问题”,采用多步决策建立了数学模型,求解得到商人们安全过河的方案。
将经典的商人过河问题进行了更为深入更广泛的讨论,在此基础上着重分析了安全渡河的状态空间,建立了满足问题需求的规则,从而得出了要求解问题的方案。
模型主要通过穷举的方法对各种过河的方案进行一一列举,然后根据小船的容量和商人们要安全渡河为前提对各种方案进行层层筛选。
最终,得到商人安全渡河的方案。
此方案适用于不同对数商仆的情况下,求的安全渡河的最合理方法。
最后本文就此问题在,当有
名商人
名随从且小船的容量为
时,将会得到几种解决方案给出了说明。
关键词:
穷举法多步决策图解法商人过河状态空间
状态向量运载向量
一、模型的假设
1.商人和仆人都会划船。
2.天气很好,无大风大浪,船的质量很好,船桨足够很多次的运载商人和仆人。
3.所有人最终都能到达对岸,且安全。
二、参数
表示商人的数量
表示随从的数量
表示船的容量
表示船在此岸和彼岸(K=-1表示船去彼岸,K=1表示船回此岸)
表示船运载动作执行的次数
表示此岸的商人数量
表示此岸随从的数量
表示彼岸的商人数量
表示彼岸的随从数量
表示船上商人的数量
表示船上仆人的数量
三、问题分析
商仆安全渡河问题可以视为一个多步决策过程,多步决策是指决策过程难以一次完成,而是多步优化,最后获取一个全局最优方案的决策方法。
对于每一步,即船由此岸驶向彼岸,或者船由彼岸驶向此岸的决策,不仅会影响到该过程的效果,而且还会影响到下一步的初始状态,从而对整个过程都会有影响。
所以,在每一次过河时,就不能只从这一次过河本身考虑,还要把它看成是整个过河过程中的一个部分。
在对船上的人员做决策时,要保证两岸的商人数不能少于仆人数,用最少的步伐是人员全部过河。
应用状态向量和运载向量,找出状态随运载变化的规律,此问题就转化为状态在允许范围内(即安全渡河条件),确定每一次该如何过河,从而达到渡河的目标。
现在我们都把它们数量化:
即用数学语言来表示。
下面我们将以10对商仆过河,船每次最多可载5人为例进行说明。
1.状态向量的选择
用二维向量(M、N)表示总状态向量。
M代表总商人数,N代表总仆人数。
则:
(M、N)=(10、10)
用二维向量(m、n)和(u、v)分别表示此岸和彼岸的状态向量。
m代表此岸商人数,n代表此岸仆人数,u代表彼岸商人数,v代表彼岸仆人数。
则:
0≤(m、n、u、v)≤10
例:
(10、10)(9、8)(5、4)(7、6)(3、3)等
1.可取状态向量的选择
为满足题目要求,即河的任意岸上仆人数均不能超过商人数。
所以可取的状态向量有:
2.
(0、0)
(1、0)(1、1)
(2、0)(2、1)(2、2)
(3、0)(3、1)(3、2)(3、3)
(4、0)(4、1)(4、2)(4、3)(4、4)
(5、0)(5、1)(5、2)(5、3)(5、4)(5、5)
(6、0)(6、1)(6、2)(6、3)(6、4)(6、5)(6、6)
(7、0)(7、1)(7、2)(7、3)(7、4)(7、5)(7、6)(7、7)
(8、0)(8、1)(8、2)(8、3)(8、4)(8、5)(8、6)(8、7)(8、8)
(9、0)(9、1)(9、2)(9、3)(9、4)(9、5)(9、6)(9、7)(9、8)(9、9)
(10、0)(10、1)(10、2)(10、3)(10、4)(10、5)(10、6)(10、7)(10、8)
(10、9)(10、10)
运载向量的选择
用二维向量(x、y)表示船的运载向量。
其中:
x表示船上商人的数量,y表示船上的仆人数量。
则:
0≤(x、y)≤10
例:
(10、10)(9、8)(5、4)(7、6)(3、3)等
3.可取运载向量的选择
(0、1)(0、2)(0、3)(0、4)(0、5)
(1、0)(1、1)(1、2)(1、3)(1、4)
(2、0)(2、1)(2、2)(2、3)
(3、0)(3、1)(3、2)
(4、0)(4、1)
(5、0)
为满足题目要求,即船每次最多可运载Z人;也就是说船的容量为Z。
而此题中Z=5。
所以可取运载向量有:
4.过河步骤的实现
Ø船从此岸到彼岸
此岸人数减少,彼岸人数增加,总人数不变。
所以:
(u、v)=(M、N)-[(m、n)-(x、y)]
Ø船从彼岸到此岸
此岸人数增加,彼岸人数减少,总人数不变。
所以:
(u、v)=(M、N)-[(m、n)+(x、y)]
Ø船的来去数学化
以K表示船从此岸到彼岸或者是船从彼岸到此岸,当K=-1时船从此岸到达彼岸,当K=1时船从彼岸返回此岸。
则有:
(u、v)=(M、N)-[(m、n)+K(x、y)]
6.过河目的的实现
过河的目的是指在满足各种限制条件的情况下,最终能够使10对商仆快速而有效地过河。
为了达到此目的,我们希望每完成一次往复运载动作后此岸的人数会减少,彼岸的人数会增加。
要使所有人都过河,船的最后一次运载一定是从此岸到彼岸。
所谓的往复一次运载就是说,船从此岸到彼岸在从彼岸返回此岸的过程。
以k表示船执行过河的动作次数,则有总的船执行过河的动作次数为2k+1,而为了达到过河目的,必须使:
并且
四、模型的建立及其求解
1.模型的建立
我们建立了一个商仆过河问题的向量关系模型,此模型保证了河的两岸仆人数不会多于商人数;过河动作不会出现死循环现象。
即商仆最终可以在即安全又快速的情况下完成过河目的。
模型建立如下:
✧符号介绍
:
表示总的状态向量,即:
=(M、N)=(10、10)
:
表示第k次执行运载动作时此岸的可取状态向量,即:
=(m、n)
:
表示第k次执行运载动作时彼岸的可取状态向量,即:
=(u、v)
:
表示第k次执行运载动作时的可取运载限量,即:
=(x、y)
✧问题描述
在满足条件:
=
-[
+
]和
≥
并且
≤
情况下:
1)求解满足要求的情况下最终使
=
,
=0。
2)求解最优的过河步骤,即k的最优值。
初始条件:
=(M、N)=(10、10)
=
=0
=0
2.模型的解
v解法一:
算法
根据过河的要求以及过河前后,河岸两边人数的变化关系建立以下过河的算法:
此算法原理采用多步决策过程,多步决策是指决策过程难以一次完成,而是多步优化,最后获取一个全局最优方案的决策方法。
多步决策每一步的完成不仅与前一步的结果有关,同时还影响着下一步的决策。
此算法先进行初值确定,然后在进行计算,接下来判断结果选择正确的结果,最后整理结果等待下一次计算。
当
时:
注:
√:
该向量是此刻的可取状态向量
×:
该向量不是此刻的可取状态向量
⊙:
此过河方式满足题目各种要求
当
时:
注:
√:
该向量是此刻的可取状态向量
×:
该向量不是此刻的可取状态向量
⊙:
此过河方式满足题目各种要求
以上是第一次往复运载执行的过程,由于每一步的分支太多此处不再一一介绍。
具体计算结果参考本文【附件:
1】商仆过河程序运行结果。
v解法二:
图解法
作图规则:
让‘●’表示可取状态向量。
1 当船从此岸到彼岸时让‘●’向下或向左移动1~5格;即当k=奇数时‘●’向下或向左移动1~5格。
2 当船从彼岸到此岸时让‘●’向上或向右移动1~5格;即当k=奇数时‘●’向上或向右移动1~5格。
vn起始点
010●
19●●
28●●●
37●●●●
46●●●●●
55●●●●●●
64●●●●●●●
73●●●●●●●●
82●●●●●●●●●
91●●●●●●●●●●
100●●●●●●●●●●●
012345678910m
终点109876543210u
注:
只能在各‘●’点之间移动
例:
当k=1时,从起始点向下或向左移动1~5格。
当k=2时,从k=1执行完后的点向上或向右移动1~5格。
去掉死循环的点,就是第二步的结果。
五、模型的检验
我们在网上下载并调试了一段关于商人过河的程序,对模型提出的解决方案做了合理性检验,最后得出了正确的结论。
程序语言见【附件:
1】
演示结论见【附件:
2】
通过检验得到的结论与算法计算的结论一致,可以说明该模型的建立和算法实现是符合实际要求的
六、模型的合理性讨论
多步决策不会出现遗漏可能的过河方式,可以将其全部得出来且看起来直观易懂。
模型的缺点也很明显,就是解决是复杂繁琐。
七、模型的改进方向
本模型只能解决过河的人少时的过河方案,如果人多的话,这种方法显然不适合。
过河人较多时,可通过编程较容易实现,本例所采用的程序语言正好可以解决模型求解带来的缺点,弥补了多步决策问题的繁琐缺陷。
八、模型的推广
该模型还可以可以扩展为
名商人带
名随从过河的问题。
同时可以进一步通过程序实现当商仆人数给定时,自动确定船的容量为多少时可以实现过河目的,以及相应的可取运载向量。
九、参考文献
【1】:
《数学建模方法与范例》寿纪麟主编西安交通大学出版社
【2】:
《C++程序设计学习指导与习题解答》johnR.Hubbard著金名等译清华大学出版社
【3】:
数学建模过河问题程序
附录
附件:
1
//约束条件:
岸上仆人不能多于商人数
#include
usingnamespacestd;
structNode
{intnMer;
intnSer;
intlength;
};
classA
{
public:
A();
~A();
voidTspt();//过河的动作
voiddoLeft(intnhead,intntail,intnlength);
private:
boolislegal(intnm,intns);//判断是否满足约束条件,满足为true
Node*funTspt(intnm,intns,boolflag);//添加STEP[head]可以向后延伸的节点
boolnoRepeat(intnm,intns);//没有重复返回TRUE
voidfunshow(inta[][2],intntail);
boolfunLeft(Nodend,intb1,intb2,intn);
voidshow(ints[],intp[][2],int&top,int&count,inta[]);
inthead;
inttail;
intn;//商仆的对数
intnB;//船最多的载人数目
Node*STEP;
};
A:
:
~A()
{
free(STEP);
}
A:
:
A()
{
cout<<"请输入商仆的对数S=";
F:
cin>>n;
if(n==1)
{
nB=2;
cout<<"船最多载人的数目K="< } elseif(n==2) { cout<<"船最多载人的数目可以取: "; for(intx=n;x<=2*n;x++) { cout< } cout< cout<<"请输入船最多载人的数目K="; cin>>nB; } elseif(n==3) { cout<<"船最多载人的数目可以取: "; for(intx=n-1;x<=2*n;x++) { cout< } cout< cout<<"请输入船最多载人的数目K="; cin>>nB; } elseif(n==4) { cout<<"船最多载人的数目可以取: "; for(intx=n-1;x<=2*n;x++) { cout< } cout< cout<<"请输入船最多载人的数目K="; cin>>nB; } elseif(n>=5&&n<=100) { cout<<"船最多载人的数目可以取: "; for(intx=4;x<=2*n;x++) { cout< } cout< cout<<"请输入船最多载人的数目K="; cin>>nB; } elseif(n<1||n>100) { cout<<"本程序仅在S=(0…100)以内保证其正确性"< cout<<"请重新输入商仆的对数S="; gotoF; } STEP=(Node*)malloc(sizeof(Node)*10000); memset(STEP,0,sizeof(Node)*10000); head=tail=0; STEP[0].nMer=STEP[0].nSer=n; } intmain() { cout<<"此程序用于数学建模课程作业——商仆过河问题的解决! ! ! ! ! ! "< cout<<"问题描述: S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。 商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。 但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全? "< Aa; a.Tspt(); return0; } voidA: : show(ints[],intp[][2],int&top,int&count,inta[]) { if(top==-1) return; //已找到目标状态需,输出数据 if(top==STEP[head].length) { cout<<"***********"<<++count<<"***********"< funshow(p,top+1); B: top--; if(top==-1) return; C: s[top]--; if(STEP[(s[top])].length! =top)//退过了 { s[top]=a[top]; gotoB; } if(funLeft(STEP[(s[top])],p[top-1][0],p[top-1][1],top-1)==false) gotoC; p[top][0]=STEP[(s[top])].nMer; p[top][1]=STEP[(s[top])].nSer; show(s,p,top,count,a); return; } //在中间加入节点STEP[(s[top+1])] if(funLeft(STEP[(s[top+1])],p[top][0],p[top][1],top)==true)//符合条件 { top++; p[top][0]=STEP[(s[top])].nMer; p[top][1]=STEP[(s[top])].nSer; show(s,p,top,count,a); return; } else//不符合条件 { E: s[top+1]--; if(STEP[(s[top+1])].length==top)//退过了,到了下一层 { s[top+1]=a[top+1]; D: s[top]--; if(STEP[(s[top])].length! =top)//退过了,到了下一层 { for(inti=top;i<=STEP[head].length;i++) s[i]=a[i]; top--; if(top==-1) return; gotoD; } if(top==0) return; if(funLeft(STEP[(s[top])],p[top-1][0],p[top-1][1],top-1)==false) gotoD; p[top][0]=STEP[(s[top])].nMer; p[top][1]=STEP[(s[top])].nSer; show(s,p,top,count,a); return; } if(funLeft(STEP[(s[top+1])],p[top][0],p[top][1],top)==false) gotoE; top++; p[top][0]=STEP[(s[top])].nMer; p[top][1]=STEP[(s[top])].nSer; show(s,p,top,count,a); } } voidA: : doLeft(intnhead,intntail,intnlength) { inta[1000]; inta1[1000]; intsp[1000][2]; boolflag=false; memset(a,0xff,4000); memset(a1,0xff,4000); memset(sp,0xff,8000); if(STEP[head].length%2==0) flag=true; while(STEP[head].length==nlength-1) { funTspt(STEP[head].nMer,STEP[head].nSer,flag); head++; } for(inti=0;i { a[(STEP[i].length)]=i; a1[(STEP[i].length)]=i; } sp[0][0]=sp[0][1]=n; STEP[head].nMer=STEP[head].nSer=0; inttop=0; intcount=0; show(a1,sp,top,count,a); } boolA: : funLeft(Nodend,intb1,intb2,intn) { boolflag=abs(nd.nMer-b1)+abs(nd.nSer-b2) &&abs(nd.nMer-b1)+abs(nd.nSer-b2)>0; if(flag==false) returnfalse; if(n%2==0&&b1>=nd.nMer&&b2>=nd.nSer) returntrue; if(n%2==1&&b1<=nd.nMer&&b2<=nd.nSer) returntrue; returnfalse; } voidA: : Tspt() { Node*temp=newNode; temp=NULL; boolflag=false; while(head<=tail) { if(STEP[head].length%2==0) flag=true; else flag=false; temp=funTspt(STEP[head].nMer,STEP[head].nSer,flag); if(NULL! =temp) break; head++; } if(head>tail) { cout<<"此问题无解! "< exit (1); } doLeft(temp->nMer,temp->nSer,temp->length);//temp->nMer表示head deletetemp; } Node*A: : funTspt(intnm,intns,boolflag) {//flag==true向对岸运输 Node*nd=NULL; inttemp=1; inttM=STEP[head].nMer;//可供运输的商人数 inttS=STEP[head].nSer;//可供运输的仆人数 if(flag==false)//向此岸运输 { tM=n-STEP[head].nMer; tS=n-STEP[head].nSer; temp=-1; } for(inti=0;i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数学 建模
![提示](https://static.bdocx.com/images/bang_tan.gif)