ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:37.07KB ,
资源ID:8104351      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8104351.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(商仆过河问题数学建模.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

商仆过河问题数学建模.docx

1、商仆过河问题数学建模商仆过河问题作者:*学院 *班 * * *号2014年12月4日摘要:为了求解3个商人和3个随从的过河问题,用数学分析方法,建立数学模型,并且加以求解,展示动态规划思想的应用步骤。最后利用计算机编程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题的作用。关键词:多步决策 计算机求解 状态转移律 图解法 MATLAB程序一、问题的提出S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?二、问题的关

2、键解决的关键集中在商人和随从的数量上,以及小船的容量上,该问题就是考虑过河步骤的安排和数量上。各个步骤对应的状态及决策的表示法也是关键。三、问题的分析在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。由于船上人数限制,这需要多步决策过程,必须考虑每一步船上的人员。动态规划法正是求解多步决策的有效方法。它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。直到可以直接求出其解的子问题为止。分解成所有子问题按层次关系构成一棵子问题树树根是原问题。原问题的解依赖于子问题树中所有子问题的解。四、 模型假设记第k次过河前A岸的商人数为XK,随从数为YK k=1,2,? XK ,

3、YK=0,1,2,3,将二维向量SK=(XK,YK)定义为状态把满足安全渡河条件下的状态集合称为允许状态集合。记作S。则S=(XK ,YK)|(XK =0,YK =0,1,2,3),(XK =3,YK =0,1,2,3),(XK =YK =1)(XK =YK =2)记第k次过河船上的商人数为UK,随从数为VK将二维向量DK=(UK ,VK)定义为决策由小船的容量可知允许决策集合(记作D)为 D=(UK ,VK)|UK +VK=l,2=(O,1);(O,2);(1,O);(1,1);(2,O)五、模型建立:动态规划法正是求解多步决策的有效方法。它要求把解的问题一层一层地分解成一级一级、规模逐步缩

4、小的子问题。直到可以直接求出其解的子问题为止。分解成所有子问题按层次关系构成一棵子问题树树根是原问题。原问题的解依赖于子问题树中所有子问题的解。用动态规划法分析三名商人的过河问题。可得如下的递归树:K=1A(3,2)B(0,1)A(3,2)B(0.1)K=2A(3,1)B(0,2)(0,1)A(2,2)B(1,1)(0,2)A(3,0)B(0,3)(1,1)(2,0)(3,3)(1,1)(1,0)相同情况K=3(0,2)A(3,1)B(0,2)K=4K=5(0,1)(2,0)A(1,1)B(2,2)K=6A(2,2)B(1,1)K=7=A(0,2)B(3,1)K=8(0,1)(转下页)A(0,

5、3)B(3,0)K=9(0,2)A(0,1)B(3,2)A(1,1)B(2,2)A(0,2)B(3,1)(1,0)(0,1)A(0,0)B(3,3)K=10K=11(注解:当K为奇数时,船在B岸;当K为偶数时,船在A岸。)通过分析该递归树,知道求解关键在于正确地写出基本的状态转移关系式和恰当的边界条件。因为k为奇数时,船是从A岸驶向B岸,k为偶数时。船是由B岸驶回A岸。所以状态SK随决策DK变化的规律是SK+1=SK+(-1)K DK,k=l,2,?,称之为状态转移律,这样,制定过河方案就归结为如下的多步决策问题:每一步,船由A岸驶向B岸或B岸驶回A岸,都要对船上的人员(商人UK,随从VK各几

6、人)作出决策,在保证安全的前提下即两岸的商人数XK都不比随从数YK少,用有限步使人员全部过河用状态(变量)SK表示某一岸的人员状况,决策(变量)DK表示船上的人员状况,可以找出状态SK随决策DK变化的规律这样安全过河问题就转化为:求决策DKD(k=1,2,n),使得状态SKS,按照状态转移律,由初始状态S1=(3,3),经有限步n到达状态SK+1=(O,O)。模型建立:SK+1=SK+(-1)KDK,k=l,2,3,其中DK D=(UK ,VK)|UK +VK=l,2,其中SK (XK ,YK)|(XK=0,YK =1,2,3);(XK =3,YK=0,1,2,3);(XK =YK =1,2)

7、,Sn+1 =(0,0)这就是三个商人的过河问题模型。六、模型求解:穷举法:计算机编程(见附)先建立编程的基本过程,然后考虑模型,再编写程序。然后就可以得出结果了。 开始变量赋值初始化判断是否完全过河选择一种可行方案,进行过河或返回,得到新的状态否判断是不是允许状态集合中的状态,并且还没在已经考虑的状态中是否还有其他状态否结束是是是主程序流程图图解法:状态s=(x,y) 16个格点允许状态 10个点允许决策 移动1或2格; k奇,左下移;k偶,右上移.xy3322110S1sn+1d1d11总共需要11步可以得出经过11步的渡河就能达到安全渡河的目标及满足渡河的次数尽量少的条件。这11步的渡河

8、方案就是上面程序运行结果中船上下面的一列。八、 模型的检验用2名商人和2名随从的过河问题的解决思路,检验3名商人和3名随从的过河问题。九、 模型的拓展和延伸通过三名商人和三名随从的过河问题的解决方案,可以进一步计算四名商人和四名随从的过河问题,通过计算机编程可以设计m名商人和n名随从的过河问题。十、总结这是通过数学分析的方法解决实用问题,经过问题提出、问题假设、问题分析、模型建立、模型求解、模型检验的过程,解决商人过河问题。然后扩展延伸到n个商人的问题。学习数学建模以来,重新认识了学习数学的乐趣,也重新认识了数学,本以为数学是单调的,枯燥的,学习了之后,发现数学是普遍存在我们生活之中的。解决现

9、实中的问题,很多都需要数学。沉浸在数学的世界里,发现学习是有趣的;相比于机械的认识各个组织器官,建立一个数学模型解决问题是十分有趣的。参考文献:(1)傅清祥数据结构与算法王晓东北京:电子工业出版社 1998(2)姜启瑟数学建模(第二版)北京:高等教育出版社,2000(3)运筹学教材编写组运筹学(修订版)北京:清华大学出版社。2001附:商仆过河的C程序及运行截屏:#include using namespace std;struct Node int nMer; int nSer; int length;class Apublic: A(); A(); void Tspt(); /过河的动作

10、void doLeft(int nhead,int ntail,int nlength); private: bool islegal(int nm,int ns); /判断是否满足约束条件,满足为true Node *funTspt(int nm,int ns,bool flag);/添加STEPhead可以向后延伸的节点 bool noRepeat(int nm,int ns);/没有重复返回TRUE void funshow(int a2,int ntail); bool funLeft(Node nd,int b1,int b2,int n); void show(int s,int

11、p2,int &top,int &count,int a); int head; int tail; int n; /商仆的对数 int nB; /船最多的载人数目 Node *STEP;A:A() free(STEP);A:A() coutn; if(n=1) nB=2; cout船最多载人的数目K=nB; else if(n=2) cout船最多载人的数目可以取:; for(int x=n;x=2*n;x+) coutx、; coutendl; coutnB; else if(n=3) cout船最多载人的数目可以取:; for(int x=n-1;x=2*n;x+) coutx、; co

12、utendl; coutnB; else if(n=4) cout船最多载人的数目可以取:; for(int x=n-1;x=2*n;x+) coutx、; coutendl; coutnB; else if(n=5&n=100) cout船最多载人的数目可以取:; for(int x=4;x=2*n;x+) coutx、; coutendl; coutnB; else if(n100) cout本程序仅在S=(0100)以内保证其正确性endl; cout请重新输入商仆的对数S=; goto F; STEP = (Node *)malloc(sizeof(Node)*10000); mems

13、et(STEP,0,sizeof(Node)*10000); head = tail = 0; STEP0.nMer = STEP0.nSer = n;int main() cout问题描述: S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?endl; A a; a.Tspt(); return 0;void A:show(int s,int p2,int &top,int &count,int a) if(top = -1)

14、 return ; /已找到目标状态需,输出数据 if(top = STEPhead.length) cout* +count *endl; funshow(p,top + 1); B: top-; if(top = -1) return ;C: stop-; if(STEP(stop).length != top)/退过了 stop = atop; goto B; if(funLeft(STEP(stop),ptop - 10,ptop - 11,top - 1) = false) goto C; ptop0 = STEP(stop).nMer; ptop1 = STEP(stop).nSe

15、r; show(s,p,top,count,a); return ; /在中间加入节点STEP(stop + 1) if(funLeft(STEP(stop + 1),ptop0,ptop1,top) = true)/符合条件 top+; ptop0 = STEP(stop).nMer; ptop1 = STEP(stop).nSer; show(s,p,top,count,a); return ; else /不符合条件 E: stop + 1-; if(STEP(stop + 1).length = top)/退过了,到了下一层 stop + 1 = atop + 1;D: stop-;

16、if(STEP(stop).length != top)/退过了,到了下一层 for(int i = top; i = STEPhead.length; i+) si = ai; top-; if(top = -1) return ; goto D; if(top = 0) return ; if(funLeft(STEP(stop),ptop - 10,ptop - 11,top - 1) = false) goto D; ptop0 = STEP(stop).nMer; ptop1 = STEP(stop).nSer; show(s,p,top,count,a); return ; if(

17、funLeft(STEP(stop + 1),ptop0,ptop1,top) = false) goto E; top+; ptop0 = STEP(stop).nMer; ptop1 = STEP(stop).nSer; show(s,p,top,count,a); void A:doLeft(int nhead,int ntail,int nlength) int a1000; int a11000; int sp10002; bool flag = false; memset(a,0xff,4000); memset(a1,0xff,4000); memset(sp,0xff,8000

18、); if(STEPhead.length%2 = 0) flag = true; while(STEPhead.length = nlength - 1) funTspt(STEPhead.nMer,STEPhead.nSer,flag); head+; for(int i = 0; i head + 1; i+) a(STEPi.length) = i; a1(STEPi.length) = i; sp00 = sp01 = n; STEPhead.nMer = STEPhead.nSer = 0; int top = 0; int count = 0; show(a1,sp,top,co

19、unt,a); bool A:funLeft(Node nd,int b1,int b2,int n) bool flag = abs(nd.nMer - b1) + abs(nd.nSer - b2) 0; if(flag = false) return false; if(n%2 = 0 & b1 = nd.nMer & b2 = nd.nSer) return true; if(n%2 = 1 & b1 = nd.nMer & b2 = nd.nSer) return true; return false;void A:Tspt() Node *temp = new Node; temp

20、 = NULL; bool flag = false; while(head tail) cout此问题无解!nMer,temp-nSer,temp-length);/temp-nMer表示head delete temp;Node* A:funTspt(int nm,int ns,bool flag)/flag = true 向对岸运输 Node *nd = NULL; int temp = 1; int tM = STEPhead.nMer; /可供运输的商人数 int tS = STEPhead.nSer; /可供运输的仆人数 if(flag = false) /向此岸运输 tM = n

21、 - STEPhead.nMer; tS = n - STEPhead.nSer; temp = -1; for(int i = 0; i tM + 1 & i nB + 1; i+)/i表示运输的商人数 for(int j = 0; j tS + 1 & j length = STEPhead.length + 1; nd-nMer = head; nd-nSer = tail; return nd; tail+; STEPtail.length = STEPhead.length + 1; STEPtail.nMer = p; STEPtail.nSer = q; return nd;bo

22、ol A:noRepeat(int nm,int ns) int j1 = 0; if(STEPhead.length%2 = 0) j1 = 1; for(int i = j1; i tail + 1; i+) if(STEPi.length%2 = j1 & nm = STEPi.nMer & ns = STEPi.nSer) return false; return true;bool A:islegal(int nm,int ns) /商人数少于仆人数或者商人数为0 if(nm = 0) | (nm = n) | (nm = ns) return true; return false;void A:funshow(int a2,int ntail) coutendl; cout 商人数 仆人数endl; for(int i = 0; i ntail; i+) cout第i次 ai0 ai1endl; if(i != ntail - 1 & i%2 = 0) cout (abs(ai + 10 - ai0), abs(ai + 11 - ai1)endl; else if(i != ntail - 1 & i%2 = 1) cout - (abs(ai + 10 - ai0), abs(ai + 11 - ai1)endl; coutendl;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1