商人过河的数学模型及编程解决
数学建模:研究商人过河问题
数学建模实验一报告实验题目:研究商人过河问题一、实验目的:编写一个程序(可以是C,C++或Mathlab )实现商人安全过河问题。
二、实验环境:Turbo c 2.0、Microsoft Visual C++ 6.0、Matlab 6.0以上 三、实验要求:要求该程序不仅能找出一组安全过河的可行方案,还可以得到所有的安全过河可行方案。
并且该程序具有一定的可扩展性,即不仅可以实现3个商人,3个随从的过河问题。
还应能实现 n 个商人,n 个随从的过河问题以及n 个不同对象且每个对象有m 个元素问题(说明:对于3个商人,3个随从问题分别对应于n=2,m=3)的过河问题。
从而给出课后习题5(n=4,m=1)的全部安全过河方案。
四、实验步骤:第一步:问题分析。
这是一个多步决策过程,涉及到每一次船上的人员以及要考虑此岸和彼岸上剩余的商人数和随从数,在安全的条件下(两岸的随从数不比商人多),经有限步使全体人员过河。
第二步:分析模型的构成。
记第k 次渡河前此岸的商人数为k x ,随从数为k y ,2,1=k ,n y x k k 2,1,=,(具有可扩展性),将)(k k y x ,定义为状态,状态集合成为允许状态集合(S )。
S={2,1;3,2,1,0,3;3,2,1,0,0|,======y x y x y x y x )(}记第k 次渡船的商人数为k u ,随从数为k v ,决策为),(k k v u ,安全渡河条件下,决策的集合为允许决策集合。
允许决策集合记作D ,所以D={2,1,0,,21|,=<+<v u v u v u )(|1<u+v<2,u,v=0,1,2},因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船由彼岸驶向此岸,所以状态k s 随决策k d 变化的规律是k k k k d s s )1(1-+=-,此式为状态转移律。
制定安全渡河方案归结为如下的多步决策模型:求决策)2,1(n k D d k =∈,使状态S s k ∈按照转移律,由初始状态)3,3(1=s 经有限n 步到达)0,0(1=+n s第三步:模型求解。
商人们怎样安全过河-(附MATLAB程序完整)
商人们怎样安全过河随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.但是乘船渡河的方案由商人决定.商人们怎样才能安全过河?问题分析:决策~ 每一步(此岸到彼岸或彼岸到此岸)船上的人员要求~在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河. 建立模型xk~第k次渡河前此岸的商人数 xk, yk=0,1,2,3;yk~第k次渡河前此岸的随从数 k=1,2,|....sk=(xk , yk)~过程的状态 S ~ 允许状态集合S={(x , y) x=0, y=0,1,2,3; x=3, y=0,1,2,3; x=y=1,2}uk~第k次渡船上的商人数 uk, vk=0,1,2;vk~第k次渡船上的随从数 k=1,2,.....dk=(uk , vk)~决策 D={(u , v) u+v=1, 2} ~允许决策集合~状态转移律多步决策问题求dk D(k=1,2, n), 使sk S, 并按转移律由s1=(3,3)到达 sn+1=(0,0).模型求解穷举法~ 编程上机S={(x , y) x=0, y=0,1,2,3;x=3, y=0,1,2,3;x=y=1,2}图解法状态s=(x,y) ~ 16个格点允许状态~ 10个点允许决策 ~ 移动1或2格; k奇,左下移; k偶,右上移.d1,.......,d11给出安全渡河方案评注和思考规格化方法,易于推广考虑4名商人各带一随从的情况程序%%%%%%%%%%%%%%%% 开始 %%%%%%%%%%%%%%%%%%%%%%function jueche=guoheclear allclc%%%%%%%%%%程序开始需要知道商人和仆人数;%%%%%%%%%%%%%shangren=input('输入商人数目: ');puren=input('输入仆人数目: ');rongliang=input('输入船的最大容量: ');if puren>shangrenshangren=input('输入商人数目:');puren=input('输入仆人数目:');rongliang=input('输入船的最大容量:');end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决策生成jc=1; %决策向量放在矩阵d中,jc为插入新元素的行标初始为1;for i=0:rongliangfor j=0:rongliangif (i+j<=rongliang)&(i+j>0) % 满足条D={(u,v)|1<=u+v<=rongliang,u,v=0,1,2}d(jc,1:3)=[i,j ,1]; %生成一个决策向量立刻扩充为三维;d(jc+1,1:3)=[-i,-j,-1]; % 同时生成他的负向量;jc=jc+2; % 由于生成两个决策向量,则jc要向下移动两个;endendj=0;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数组生成kx=1; % 状态向量放在A矩阵中,生成方法同矩阵生成;for i=shangren:-1:0for j=puren:-1:0if ((i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))% (i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))为可以存在的状态的约束条件 A(kx,1:3)=[i,j,1]; %生成状态数组集合D `A(kx+1,1:3)=[i,j,0];kx=kx+2;endj=puren;end;%%%%%%%%%%%%%%% 将状态向量生成抽象矩阵%%%%%%%%%%%%%%%%%%%k=(1/2)*size(A,1);CX=zeros(2*k,2*k);a=size(d,1);for i=1:2*kfor j=1:ac=A(i,:)+d(j,:) ;x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3))) ; v(i,x)=1; %x为空不会改变v值endend%%%%%%%%%%%%%%%%%%%%%%dijstra算法%%%%%%%%%%%%%%%%%%%%%%%%%%x=1; y=size(A,1);m=size(v,1);T=zeros(m,1);T=T.^-1;lmd=T;P=T;S=zeros(m,1);S(x)=1;P(x)=0; lmd(x)=0;k=x;while(1)a=find(S==0);aa=find(S==1);if size(aa,1)==mbreak;endfor j=1:size(a,1)pp=a(j,1);if v(k,pp)~=0if T(pp)>(P(k)+v(k,pp))T(pp)=(P(k)+v(k,pp));lmd(pp)=k;endendendmi=min(T(a));if mi==infbreak;d=find(T==mi);d=d(1);P(d)=mi;T(d)=inf;k=d;S(d)=1;endendif lmd(y)==infjueche='can not reach(不能过河)';return;endjueche(1)=y;g=2; h=y;while(1)if h==xbreak;endjueche(g)=lmd(h);g=g+1;h=lmd(h);endjueche=A(jueche,:);jueche(:,3)=[]; %%%%%%%%%%%%%%%%%% 程序完 %%%%%%%%%%%%%%%%%%欢迎您的下载,资料仅供参考!致力为企业和个人提供合同协议,策划案计划书,学习资料等等打造全网一站式需求。
11对商仆过河问题数学建模.
数学建模论文商仆过河问题摘要本文针对商人安全渡河的问题,采用多步决策的过程建立数学模型,求解得到了在随从没有杀人越货的情况下的渡河方案。
对于本题而言,在11名商人、11名随从、船的最大容量为6人的情况下,首先定义了渡河前此岸的状态,并设安全渡河条件下的状态集定义为允许状态集合,接着得到渡河方案的允许决策集合,然后得到状态随渡河方案变化的规律,利用matlab 7.0,win 7软件,编译运行程序得到了一种商人安全渡河的方案,并输出了允许的状态向量和允许的决策向量。
但是,本文不仅仅是为了拼凑出一个可行方案,而是希望能找到求解这类问题的规律性,并建立数学模型,用以解决更为广泛的问题。
一 .问题的提出当今社会每个人都想当王者,谁都想成为富翁,所以就在这个问题中仆人们也想成为商人。
仆人们密约,在河的任何一边,只要仆人的数量超过商人的数量,仆人就会联合起来将商人杀死并抢夺其财物,十一名商人各带一个随从乘船渡河,一只小船只能容纳六人,由他们自己划行。
在河的任意一岸,一旦随从的人数比商人多,商人就有危险.但是如何乘船渡河的大权掌握在商人们手中。
商人们怎样才能安全渡河呢?同时,推广到M名商人带M名随从又如何?二. 模型假设3 模型假设(1)每个商人和随从都会划船;(2)只有一条船,且每条船上最多只能乘坐六个人;(3)所有商人与随从之间没有矛盾,不会出现有人不愿意同坐一条船的现象;(4)船在渡河的过程中不受外界环境的影响。
三.问题符号说明3符号说明A初始状态下,商人和随从所在的一岸;B初始状态下,商人和随从欲到达的一岸;S 商仆对数K 船最多载人的数目四 .问题分析安全渡河问题可以看成一个多步决策过程。
每一步,即船由此岸驶向彼岸或从彼岸驶回此岸,都要对船上的人员(商人随从各几人)作出决策,在保证安全的前提下(两岸的商人数都不比随从数少),在有限步内使人员全部过河。
用状态(变量)表示某一岸的人员状况,决策(变量)表示船上的人员状况,可以找出状态随决策变化的规律。
数学建模 商人过河
数学建模课程作业论文题目:对商人过河问题的研究指导教师:黄光辉小组成员:黄志宇(20156260)车辆工程04班牛凯春(20151927)电气工程05班文逸楚(20150382)工商管理02班一、问题重述3名商人带3名随从乘一条小船过河,小船每次只能承载至多两人。
随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。
乘船渡河的方案由商人决定,商人们如何才能安全渡河呢?二、问题分析本题针对商人们能否安全过河问题,需要选择一种合理的过河方案。
对该问题可视为一个多步决策模型,通过对每一次过河的方案的筛选优化,最终得到商人们全部安全过到河对岸的最优决策方案。
对于每一次的过河过程都看成一个随机决策状态量,商人们能够安全到达彼岸或此岸我们可以看成目标决策允许的状态量,通过对允许的状态量的层层筛选,从而得到过河的目标。
三、模型假设1.过河途中不会出现不可抗力的自然因素。
2.当随从人数大于商人数时,随从们不会改变杀人的计划。
3.船的质量很好,在多次满载的情况下也能正常运作。
4.随从会听从商人的调度,所有人都到达河对岸。
四、符号说明第k次渡河前此岸的商人数第k次渡河前此岸的随从数过程的状态向量允许状态集合第k次渡船上的商人数第k次渡船上的随从数决策向量允许决策集合x y 3322110s 1s n +1d 1d 11五、模型建立本题为多步决策模型,每一次过河都是状态量的转移过程。
用二维向量表示过程的状态,其中分别表示对应时刻此岸的商人,仆人数以及船的行进方向,其中则允许状态集合:=又将二维向量定义为决策,则允许的决策合集为:因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船从彼岸驶向此岸,所以状态随决策的变化规律是该式称为状态转移律。
求决策,使,并按照转移律,由经过有限步n 到达状态六、模型求解本模型使用MATLAB 软件编程,通过穷举法获得决策方案如下(完整matlab 程序详见附录):初始状态:可用图片表示为:X0=33状态为:S =3132303111220203010200决策为:D =0201020120112001020102七、模型推广该商人和随从过河模型可以完美解决此类商人过河的决策问题,并且该模型还可推广至解决m个商人和n个随从过河,以及小船的最大载重人数改变时的问题,只需适当地改变相关的语句即可轻松实现模型的转换。
4名商人带4名随从安全过河
4名商人带4名随从安全过河一.问题提出:4名商人带4名随从乘一条小船过河,小船每次自能承载至多两人。
随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.乘船渡河的方案由商人决定,商人们如何才能安全渡河呢?二.模型假设:商人和随从都会划船。
三.问题分析:商随过河问题可以视为一个多步决策过程,通过多次优化,最后获取一个全局最优的决策方案。
对于每一步,即船由此岸驶向彼岸或由彼岸驶向此岸,都要对船上的人员作出决策,在保证两岸的商人数不少于随从数的前提下,在有限步内使全部人员过河。
用状态变量表示某一岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到安全渡河的目标。
四.模型构成:xk~第k次渡河前此岸的商人数,yk~第k次渡河前此岸的随从数xk, yk=0,1,2,3,4; k=1,2,……Sk=(xk, yk)~过程的状态,S~允许状态集合,S={(x,y)| x=0, y=0,1,2,3,4; x=4 ,y=0,1,2,3,4; x=y=1,2,3} uk~第k次渡船上的商人数vk~第k次渡船上的随从数dk=(uk, vk)~决策,D={(u , v)| 1=<u+v=<2,uk, vk=0,1,2} ~允许决策集合 k=1,2,……因为k为奇数时船从此岸驶向彼岸,k为偶数时船从彼岸驶向此岸,所以状态Sk随决策dk的变化规律是Sk1=Sk+(-1)k dk~状态转移律求dk∈D(k=1,2, …n), 使Sk∈S, 并按转移律由S1=(4,4)到达状态Sn1=(0,0)。
五.模型求解:1.图解法:对于人数不多的情况,可以利用图解法来求解。
在xoy平面坐标系上画出如图所示的方格,方格点表示状态s=(x,y),允许状态集合S是圆点标出的13个格子点,允许决策dk是沿方格线移动1格或2格,k为奇数时向左、下方移动,k为偶数时向右、上方移动。
数学建模:研究商人过河问题之欧阳道创编
数学建模实验一报告实验题目:研究商人过河问题一、实验目的:编写一个程序(可以是C,C++或Mathlab)实现商人安全过河问题。
二、实验环境:Turbo c 2.0、Microsoft Visual C++ 6.0、Matlab 6.0以上三、实验要求:要求该程序不仅能找出一组安全过河的可行方案,还可以得到所有的安全过河可行方案。
并且该程序具有一定的可扩展性,即不仅可以实现3个商人,3个随从的过河问题。
还应能实现n个商人,n个随从的过河问题以及n个不同对象且每个对象有m个元素问题(说明:对于3个商人,3个随从问题分别对应于n=2,m=3)的过河问题。
从而给出课后习题5(n=4,m=1)的全部安全过河方案。
四、实验步骤:第一步:问题分析。
这是一个多步决策过程,涉及到每一次船上的人员以及要考虑此岸和彼岸上剩余的商人数和随从数,在安全的条件下(两岸的随从数不比商人多),经有限步使全体人员过河。
第二步:分析模型的构成。
记第k 次渡河前此岸的商人数为k x ,随从数为k y , 2,1=k ,n y x k k 2,1,=,(具有可扩展性),将)(k k y x ,定义为状态,状态集合成为允许状态集合(S )。
S={2,1;3,2,1,0,3;3,2,1,0,0|,======y x y x y x y x )(}记第k 次渡船的商人数为k u ,随从数为k v ,决策为),(k k v u ,安全渡河条件下,决策的集合为允许决策集合。
允许决策集合记作D ,所以D={2,1,0,,21|,=<+<v u v u v u )(|1<u+v<2,u,v=0,1,2},因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船由彼岸驶向此岸,所以状态k s 随决策k d 变化的规律是k k k k d s s )1(1-+=-,此式为状态转移律。
制定安全渡河方案归结为如下的多步决策模型:求决策)2,1(n k D d k =∈,使状态S s k ∈按照转移律,由初始状态)3,3(1=s 经有限n 步到达)0,0(1=+n s第三步:模型求解。
数学建模作业(商人过河问题)
数学建模作业(四)——商人过河问题一.问题描述有四名商人各带一名仆人过河,但船最多能载二人,商人已获得仆人的阴谋:在河的任一岸,只要仆人数超过商人数,仆人会将商人杀死并窃取财物且安排如何乘船的权力掌握在商人手中。
试为商人制定一个安全过河的方案。
二.解决方案用递归的源程序如下:开始时商人,强盗所在的河的这边设为0状态,另一边设为1状态(也就是船开始时的一边设为0,当船驶到对岸是设为1状态,在这两个状态时,都必须符合条件)#include <stdlib.h>struct node /*建立一个类似栈的数据结构并且可以浏览每一个数据点*/ {int x;int y;int state;struct node *next;};typedef struct node state;typedef state *link;link PPointer1=NULL;link PPointer2=NULL;int a1,b1;int a2,b2;/*栈中每个数据都分为0,1状态*/void Push(int a,int b,int n){link newnode;newnode=(link)malloc(sizeof(state));newnode-> x=a;newnode-> y=b;newnode-> state=n;newnode-> next=NULL;if(PPointer1==NULL){PPointer1=newnode;PPointer2=newnode;}else{PPointer2-> next=newnode;PPointer2=newnode;}}void Pop()/*弹栈*/{link pointer;if(PPointer1==PPointer2){free(PPointer1);PPointer1=NULL;PPointer2=NULL;}pointer=PPointer1;while(pointer-> next!=PPointer2)pointer=pointer-> next;free(PPointer2);PPointer2=pointer;PPointer2-> next=NULL;}int history(int a,int b,int n) /*比较输入的数据和栈中是否有重复的*/ {link pointer;if(PPointer1==NULL)return 1;else{pointer=PPointer1;while(pointer!=NULL){if(pointer-> x==a&&pointer-> y==b&&pointer-> state==n)return 0;pointer=pointer-> next;}return 1;}}int judge(int a,int b,int c,int d,int n)/*判断这个状态是否可行,其中使用了history函数*/{if(history(a,b,n)==0) return 0;if(a> =0&&b> =0&&a <=3&&b <=3&&c> =0&&d> =0&&c <=3&&d <=3&&a+c==3&&b+d==3){switch(n){case 1:{if(a==3){Push(a,b,n);return 1;}else if(a==0){Push(a,b,n);return 1;}else if(a==b){Push(a,b,n);return 1;}else return 0;}case 0:{if(a==3){Push(a,b,n);return 1;}else if(a==0){Push(a,b,n);return 1;}else if(a> =b){Push(a,b,n);return 1;}else return 0;}}}else return 0;}int Duhe(int a,int b,int n)/*递归法解决商人渡河问题,如果这一个状态符合*/ {/*则判断下一个状态,直至问题解决*/ if(a==0&&b==0) return 1;if(n==0)/*判断0状态时,商匪状态是否符合要求*/{if(judge(a-1,b-1,4-a,4-b,1)){if(Duhe(a-1,b-1,1)==1)return 1;}if(judge(a,b-2,3-a,5-b,1)){if(Duhe(a,b-2,1)==1)return 1;}if(judge(a-2,b,5-a,3-b,1)){if(Duhe(a-2,b,1)==1)return 1;if(judge(a-1,b,4-a,3-b,1)){if(Duhe(a-1,b,1)==1)return 1;}if(judge(a,b-1,3-a,4-b,1)){if(Duhe(a,b-1,1)==1)return 1;}else{Pop(0);return 0;}}if(n==1)/*判断0状态时,商匪状态是否符合要求*/{if(judge(a+1,b+1,2-a,2-b,0)){if(Duhe(a+1,b+1,0)==1)return 1;}if(judge(a,b+2,3-a,1-b,0)){if(Duhe(a,b+2,0)==1)return 1;}if(judge(a+2,b,1-a,3-b,0)){if(Duhe(a+2,b,0)==1)return 1;}if(judge(a+1,b,2-a,3-b,0)){if(Duhe(a+1,b,0)==1)return 1;}if(judge(a,b+1,3-a,2-b,0))if(Duhe(a,b+1,0)==1)return 1;}else{Pop(1);return 0;}}return 0;}main(){link pointer;Push(3,3,0);Duhe(3,3,0);pointer=PPointer1;while(pointer!=NULL){printf( "%d,%d---%d\n ",pointer-> x,pointer-> y,pointer-> state);pointer=pointer-> next;}getch();}。
商人过河
s=[3,3];m=[0,0];d=zeros(1,2);k=1;l=0; d=3*ones(1,2); while any(s~=0) k=k+1 %渡河 d1=[0,2;1,1;2,0]'; %每种渡河的方案 for i=d1 s1=s; m1=m; s1=s1-i‘; m1=m1+i'; if all(s1==0) l=l+1; d=[d;i']; s=s1; m=m1; else if all(s1>=0) & all(m1>=0) if (s1(1)==0 | s1(1)>=s1(2)) & (m1(1)==0 | m1(1)>=m1(2)) & any(i'~=d(end,:)) %back d2=[0 1;1 0;1 1]'; for j=d2 s2=s1; m2=m1; s2=s2+j‘; m2=m2-j'; if all(s2>=0) & all(m2>=0) if (s2(1)==0 | s2(1)>=s2(2)) & (m2(1)==0 | m2(1)>=m2(2)) l=l+1; d=[d;i']; d=[d;j']; m=m2; s=s2; l=l+1; break end; end; end break end; end; end; end;end d(2:end,:)
答案
商人过河问题
• 三名商人个带一个随从乘船渡河,一只小船 支能容纳二人,由他们自己划行,随从们密约, 在河的任一岸,一旦随从的人数比商人多,就 杀人越货.但是如何乘船渡河的大权掌握在 商人们手中,那么商人们应该怎样才能安全 渡河呢? • 对于这类智力问题可以通过逻辑思维判断 得出解决方案.也可以通过计算机枚举种种 可能,得到合理的解.(考虑过 表示出发岸边的人数; %m--表示河对岸的人数; %d--表示过河的每种决策 clear all s=[3,3];m=[0,0];
数学建模 商人过河
数学建模商人过河(hjh)
问题
随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货.
乘船渡河的方案由商人决定.商人们怎样才能安全过河?
分析问题
(1),数据及其关系?(2)如何存储?(3)过程中数据上的操作?
(4)操作过程中需借助什么结构实现?
解答
(1)数据:河两岸的商人数x∈(0,3)和随从人数y∈(0,3)
关系:线性关系
(2)存储:用二维数组来实现。
(3)操作:前进(过河)、后退(返回)
(4)操作过程中需借助栈结构实现
具体分析
此岸商人数与随从人数为C【x】【y】,彼岸商人数与随从人数为B【3-x】【3-y】,C与B数组中x必须大于等于y。
C与B数组中,各个数组中每相邻两个二维数组|x+y|之差不得超过2。
其中过河途中船上人数用数组A表示A【x1】【y1】,返回途中船上人数A【x2】【y2】。
x1,x2,y1,y2=0,1,2。
x1+y1=1或2;y2+x2=1或2。
从此岸来考察,要从最开始的C【3】【3】变到C【0】【0】。
1,C【3】【3】→C【3】【1】,C【3】【1】→C【3】【2】;
2,C【3】【2】→C【3】【0】,C【3】【0】→C【3】【1】;3,C【3】【1】→C【1】【1】,C【1】【1】→C【2】【2】;4,C【2】【2】→C【0】【2】,C【0】【2】→C【0】【3】;5,C【0】【3】→C【0】【1】,C【0】【1】→C【0】【2】;6,C【0】【2】→C【0】【0】。
操作过程中需借助栈结构实现,具体如下图所示:
此岸人数已经全部转移到彼岸,任务圆满完成,商人们安全过河。
数学模型实验商人过河
《数学模型实验》实验报告姓名:王佳蕾学院:数学与信息科学学院地点:主楼402学号:20151001055 专业:数学类时间:2017年4 月16日一、实验名称:商人和仆人安全渡河问题的matlab实现二、实验目的:1.熟悉matlab基础知识,初步了解matlab程序设计;2.研究多步决策过程的程序设计方法;3.(允许)状态集合、(允许)决策集合以及状态转移公式的matlab表示;三、实验任务:只有一艘船,三个商人三个仆人过河,每一次船仅且能坐1-2个人,而且任何一边河岸上仆人比商人多的时候,仆人会杀人越货。
怎么在保证商人安全的情况下,六个人都到河对岸去,建模并matlab实现。
要求:代码运行流畅,结果正确,为关键语句加详细注释。
四、实验步骤:1.模型构成2.求决策3.设计程序4.得出结论(最佳解决方案)五、实验内容:(一)构造模型并求决策设第k次渡河前此岸的商人数为xk,随从数为yk,k=1,2,...,xk,yk=0,1,2,3.将二维向量sk=(xk,yk)定义为状态,安全渡河条件下的状态集合称为允许状态集合,记作S,S 对此岸和彼岸都是安全的。
S={(x,y)|x=0,y=0,1,2,3;x=3,y=0,1,2,3;x=y=1,2}设第k次渡船上的商人数为uk,随从数vk,将二维变量dk=(uk,vk)定义为决策,允许决策集合记为D,由小船的容量可知,D={(u,v)|1<=u+v<=2,u,v=0,1,2}k为奇数时,船从此岸驶向彼岸,k为偶数时,船从彼岸驶向此岸,状态sk随决策变量dk的变化规律为sk+1=sk+(-1)^k*dk(状态转移律)这样制定安全渡河方案归结为如下的多步决策模型:求决策dk∈D(k=1,2,...,n),使状态sk∈S,按照转移律,由初始状态s1=(3,3)经有限步n到达状态sn+1=(0,0)。
(二)程序设计(三)运行结果、六、 结论体会:安全渡河问题可以看成一个多步决策过程。
【数学模型】商人们怎样过河?
问题引出问题:三名商人各带一个随从过河,一只小船只能容纳两个人,随从们约定,只要在河的任何一岸,一旦随从人数多于商人人数就杀人越货,但是商人们知道了他们的约定,并且如何过河的大权掌握在商人们手中,商人们该采取怎样的策略才能安全过河呢?这次的问题是一个很经常遇到的过河问题,其实对于该类问题,我们经过逻辑思考就可以得到答案。
但是通过数学模型的建立,我们可以得到一个通用的解答,并且通过计算机的计算我们可以大大扩大问题的规模。
问题分析因为这个问题已经理想化了,所以我们无需对模型进行假设,该问题可以看作一个多步决策问题。
每一步,船由此岸划到彼岸或者由彼岸划回此岸,都要对船上的人员进行决策(此次渡河船上可以有几名商人和几名随从),在保证安全(两岸的随从都不比商人多)的前提下,在有限次的决策中使得所有人都到对岸去。
因此,我们要做的就是要确定每一步的决策,达到渡河的目标。
建立模型记第k 次过河前此岸的商人数为x k , 随从数为y k, k = 1, 2, 3…, x k ,yk = 0, 1, 2, 3定义状态:将二维向量s k = ( x k , y k ) 定义为状态将安全渡河状态下的状态集合定义为允许状态集合,记为S = {(x,y) | x=0,y=0,1,2,3; x=y=1; x=y=2; x=3,y=0,1,2,3}记第k 次渡河船上的商人数为u k,随从数为v k定义决策:将二维向量d k = (u k , v k) 定义为决策允许决策集合记作D = {(u,v) | 1 ≤ u+v ≤ 2, u,v = 0,1,2}因为小船容量为2,所以船上人员不能超过2,而且至少要有一个人划船,由此得到上式。
由我们定义的状态s k和决策d k,我们可以发现它们之间是存在联系的:•k 为奇数是表示船由此岸划向彼岸,k 为偶数时表示船由彼岸划回此岸••状态s k是随着决策d k变化的,规律为:•s k+1 = s k + (-1)k d k我们把上式称为状态转移律,因此渡河方案可以抽象为如下的多步决策模型:求决策d k∈D(k = 1,2,…,n) , 使状态s k∈S 按照转移率,初始状态s1 = (3,3) 经有限步n 到达状态s n+1= (0,0)到这里,整个数学模型就已经非常清晰了,接下来要做的就是求解模型得出结果。
商人们怎样安全过河-(附MATLAB程序完整)培训讲学
商人们怎样安全过河建立模型xk~第k次渡河前此岸的商人数yk~第k次渡河前此岸的随从数sk=(xk , yk)~过程的状态S={(x , y) x=0, y=0,1,2,3; x=3, y=0,1,2,3; x=y=1,2} uk~第k次渡船上的商人数vk~第k次渡船上的随从数dk=(uk , vk)~ 决策多步决策问题求dk到达sn+仁(0,0).模型求解穷举法~ 编程上机S={(x , y) x=0, y=0,1,2,3;x=3, y=0,1,2,3; x=y=1,2}图解法状态s=(x,y) ~ 16个格点允许状态~ 10个“专点允许决策~移动1或2格;k奇,左下移;k偶右上移.d1,•……,d11给出安全渡河方案xk, yk=0,1,2,3;k=1,2,|....S~允许状态集合uk, vk=0,1,2;k=1,2,..…u+v=1,2} ~允许决策集合~状态转移律n),使sk S,并按转移律由s仁(3,3)要求~在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河D={(u , v)D(k=1,2,评注和思考规格化方法 ,易于推广考虑 4 名商人各带一随从的情况 程序%%%%%%%%%%%%%%%% 开始 %%%%%%%%%%%%%%%%%%%%%% function jueche=guohe clear all clc%%%%%%%%%% 程序开始需要知道商人和仆人数; %%%%%%%%%%%%% shangren=input(' 输入商人数目 : '); puren=input(' 输入仆人数目 : ');rongliang=input(' 输入船的最大容量 : ');if puren>shangren shangren=input(' 输入商人数目 :'); puren=input(' 输入仆人数目 :'); rongliang=input(' 输入船的最大容量 :');end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决 策 生成jc=1; %决策向量放在矩阵 fori=0:rongliangfor j=0:rongliangif (i+j<=rongliang)&(i+j>0)d(jc,1:3)=[i,j ,1];d(jc+1,1:3)=[-i,-j,-1];jc=jc+2;endendj=0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数 组生成kx=1; % 状态向量放在 A 矩阵中,生成方法同矩阵生成;for i=shangren:-1:0for j=puren:-1:0if ((i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren))% (i>=j)&((shangren-i)>=(puren-j)))|((i==0)|(i==shangren)) 为可以存在的状态的约束条件A(kx,1:3)=[i,j,1];%生成状态数组集合 D 'A(kx+1,1:3)=[i,j,0];kx=kx+2;endend 中, jc 为插入新元素的行标初始为 1; % 满足条 D={(u,v)|1<=u+v<=rongliang,u,v=0,1,2} %生成一个决策向量立刻扩充为三维; % 同时生成他的负向量; 由于生成两个决策向量,则 jc。
商人过河问题数学建模
功课1.2:商人过河一、问题重述问题一:4个商人带着4个侍从过河,过河的对象只有一艘划子,只能同时载两小我过河,包含荡舟的人.侍从们密约, 在河的任一岸, 一旦侍从的人数比商人多, 就杀人越货.乘船渡河的筹划由商人决议.商人们如何才干安然过河?问题二:假如划子可以容3人,请问最多可以有几名商人各带一名侍从安然过河.二.问题剖析问题可以看做一个多步决议计划进程.每一步由此岸到此岸或此岸到此岸船上的人员在安然的前提下(两岸的侍从数不比商人多),经有限步使全部人员过河.用状况变量暗示某一岸的人员状况,决议计划变量暗示船上的人员情形,可以找出状况随决议计划变更的纪律.问题就转换为在状况的许可变更规模内(即安然渡河前提),肯定每一步的决议计划,达到安然渡河的目的.三.问题假设1. 过河途中不会消失不成抗力的天然身分.2. 当侍从人数大于商人数时,侍从们不会转变杀人的筹划.3.船的质量很好,在多次满载的情形下也能正常运作.4. 侍从会服从商人的调剂.四.模子组成x(k)~第k 次渡河前此岸的商人数 x(k),y(k)=0,1,2,3,4; y(k)~第k 次渡河前此岸的侍从数 k=1,2,…..s(k)=[ x(k), y(k)]~进程的状况 S~许可状况聚集 S={(x,y)|x=0,y=0,1,2,3,4; x=4,y=0,1,2,3,4;x=y=1,2,3} u(k)~第k 次渡船上的商人数 u(k), v(k)=0,1,2; v(k)~ 第k 次渡船上的侍从数 k=1,2…..d(k)=( u(k), v(k))~进程的决议计划 D~许可决议计划聚集D={u,v|u+v=1,2,u,v=0,1,2}状况因决议计划而转变s(k+1)=s(k)+(-1)^k*d(k)~状况转移律 求d(k)ÎD(k=1,2,….n),使s(k)ÎS 并按转移律s(k+1)=s(k)+(-1)^k*d(k)由(4,4)到达(0,0)数学模子: k+1k S =S +k k D (-1)(1)'4k k x x += (2)'4k k y y +=(3)k.k x y ≥ (4)''k k x y ≥(5)模子剖析:由(2)(3)(5)可得化简得分解(4)可得k k x y =和 {}(,)|0,0,1,2,3,4k k k k k S x y x y ===(6)还要斟酌{}'(',')|'0,'0,1,2,3,4k k k k k S x y x y === (7)把(2)(3)带入(7)可得化简得{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8)分解(6)(7)(8)式可得知足前提的情形知足下式{}(,)|0,4,0,1,2,3,4;k k k k k k k S x y x y x y ====(9) 所以我们知道知足前提的点如上图所示:点移动由{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8)到达{}(,)|0,0,1,2,3,4k k k k k S x y x y ===(6)时,可以以为完成渡河.因为移动的格数小于等于2,只有中间点(2,2)到(6)点和(8)点的距离为2,所以中间点(2,2)成为渡河的症结点.当我们移动到(2,2)点时,就无法进行下去.故4个商人,4个侍从,船容量为2人时,无法安然渡河. 对于问题二,我们可以树立模子为:k+1k S =S +k k D (-1)(10)'k k x x M+= (11) 'k k y y M += (12)k.k x y ≥(13)''k k x y ≥ (14) u(k), v(k)=0,1,2,3; (15)经由过程相似于问题一的步调可以知道:坐标上的症结点是(3,3),最多可以五名商人带五名侍从曩昔.须要肯定五名商人带五名侍从的筹划可行再肯定六名商人带六名侍从的筹划不成行1.五名商人带五名侍从的情形:(1)起首不成能有三名商人先过河,两名商人一名侍从过河,一名商人两名侍从过河(2)三个侍从先过河(5,2),回来一个侍从(5,3),曩昔两个侍从(5,1)回来一个侍从(5,2),再曩昔三个商人(2,2),回来一个商人一个侍从(3,3),再曩昔三个商人(0,3),回来一个侍从(0,4),曩昔三个侍从(0,1),回来一个侍从(0,2)再曩昔两个侍从(0,0)综上可知:五名商人带五名侍从,划子可以载三小我可以过河 2.六名商人带六名侍从的情形:(1)起首不成能有三名商人先过河,两名商人一名侍从过河,一名商人两名侍从过河(2)三个侍从先过河(6,3),回来一个侍从(6,4),曩昔两个侍从(6,2)回来一个侍从(6,3),曩昔三个商人(3,3),此时两岸都是(3,3),由坐标法剖析知,这是最接近终点的临界点,但是假如回来的时刻必定是回来一个商人和一个侍从,假如这一步可行,后面就进行不去综上所述,六个商人带六个侍从,划子载三小我的情形下不克不及渡河联合 1.2知,当划子最多载三小我的时刻,最多五名商人各带一个侍从可以过河.五、模子的磨练与评价由少数人的过河问题推广到了更多半人的过河问题,使得问题变得清楚明了有纪律.六、参考文献[1]章胤,2014年燕山大学全国大学生数学建模比赛培训ppt,2014年4月17日。
商人过河问题数学建模c语言
商人过河问题数学建模c语言商人过河问题是一个经典的数学建模问题,通过建立数学模型,我们可以更深入地理解问题的本质,并找到最优的解决方案。
本文将通过C语言来实现这个问题的数学建模。
一、问题描述假设有n个商人要过河,每艘船只能承载一定数量的货物,而过河需要消耗一定的时间。
为了在最短的时间内完成过河任务,我们需要考虑商人的数量、船只的承载量以及过河的时间等因素,建立相应的数学模型。
二、数学建模1. 变量定义我们需要定义一些变量来描述过河过程中的各种因素,如商人的数量、船只的数量、船只的承载量、过河的时间等。
2. 算法设计算法的核心思想是利用贪心策略,尽可能多地利用船只,以减少过河的时间。
具体步骤如下:(1) 分配船只:根据船只的承载量,将商人分配到不同的船只上;(2) 计算过河时间:根据当前船只的位置和目标河岸的位置,计算每艘船只的过河时间;(3) 更新船只位置:根据过河时间,更新每艘船只的位置;(4) 重复以上步骤,直到所有商人过河。
3. C语言实现以下是一个简单的C语言程序,实现了上述算法:```c#include <stdio.h>#include <stdlib.h>int main() {int n, m, t, i, j, k;scanf("%d%d", &n, &m); // 输入商人数量和船只数量int cargo[n], time[n]; // 定义变量数组,用于存储商人和船只的信息scanf("%d%d", &cargo[0], &time[0]); // 输入第一个商人和他的过河时间for (i = 1; i < n; i++) { // 输入剩余商人和他们的过河时间scanf("%d%d", &cargo[i], &time[i]);}int boat[m]; // 定义船只数组,用于存储船只的承载量和位置信息for (j = 0; j < m; j++) { // 输入船只的承载量和位置信息scanf("%d", &boat[j]);}for (k = 0; k < n; k++) { // 模拟过河过程for (j = 0; j < m; j++) { // 遍历所有船只if (boat[j] >= cargo[k]) { // 如果船只承载量足够承载当前商人time[k] += time[k] / boat[j]; // 根据过河时间和船只速度计算剩余时间boat[j] += cargo[k]; // 将商人转移到指定位置的船只上break; // 如果找到了足够承载商人的船只,跳出当前循环继续下一轮操作}}}printf("%d\n", time[n - 1]); // 输出最后一个商人的过河时间return 0;}```三、总结通过上述C语言程序,我们可以实现商人过河问题的数学建模。
商人渡河数学模型
商人渡河数学模型
1、商人渡河数学模型
商人渡河是一类有趣的动态规划问题,其本质是一类路径规划问题,用数学模型可以描述为:
假设有n种物品,体积大小分别为W1,W2,……,Wn,以及一艘能承重V的船,每次船只能装载一些物品,要求在尽可能少的船次内,将物品搬运到对岸。
令Xij表示第i次船运载物品的状态,其中0≤Xij≤1,Xij=1表示船上装有第j个物品,Xij=0表示船上没有第j个物品,那么商人渡河问题就可以用下面的数学模型表示:
目标函数:
(1) Min Z=X11+X12+ (Xi)
约束条件:
(2) W1X11+W2X12+……+WnXin≤V
(3) X11+X12+……+Xin=1
(4) 0≤Xij≤1
其中,约束条件(2)表示第i次船运的负载不超过容量V,约束条件(3)表示每次船运必须装一些物品,约束条件(4)表示每次船运的物品的数量限制在0与1之间。
商人过河问题
商人过河一、问题重述和分析随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货。
现有4名商人各带一个随从一起渡河一只船只能容纳两个人,但如何乘船渡河的大权掌握在商人的手里,商人怎样安排才能在有限步内安全渡河?二、模型假设1、在商人人数多于随从时乘船渡河的大权掌握在商人的手里;2、商人和随从都会划船;三.符号说明x表示商人人数;y表示随从人数;z表示划船到河的此岸与彼岸。
四、模型的建立与求解本题为多步决策模型,每一次过河都是状态量的转移过程。
此岸四个商人用x=0、1、2、3、4表示,此岸四个随从用y=0、1、2、3、4表示,z=0时表示划船到河的此岸时,z=1时表示划船到河的彼岸时,用有序数对(x,y,z)表示每次转移的状态量。
解决此问题就是状态量(4,4,0)转移至(0,0,1),以下就是状态量转移的全部情况(其中“!”表示不能再转移下去或与前面步骤重复):(4,4,0)→(3,3,1)↓↓(4,2,1)→(4,3,0)→(4,1,1)→(4,2,0)→(4,0,1)→(4,1,0)→!↓(2,2,1)↓!由以上关系可知,一只船只能容纳两个人的情况下,四名商人各带一个随从无法过河。
此外,如果船的容量增加到3人,那么商人就能以几种方式安全过河,以下是其中一种方案:(4,4,0)→(4,2,1)→(4,3,0)→(4,1,1,)→(4,2,0)→(2,2,1)↓(0,1,1)←(0,3,0)←(0,2,1)←(0,4,0)←(0,3,1)←(3,3,0)↓(0,2,0)→(0,0,1)五、模型推广通过以上模型的建立,若商人和随从人数增加或小船容量加大,考虑n名商人各带一随从的情况。
数学建模—商人们怎样安全过河
乙至甲
8:09
8:19
8:00 x 8:10
8:20
8:30
X-8:00=0:09 x=8:09
甲至乙
5 一男孩和一女孩分别在离家 2 km 和 1 km 且方 向相反的两所学校上学,每天同时放学后分别 以4 km/h和 2 km/h 的速度步行回家。一小狗以 6 km/h的速度由男孩处奔向女孩,又从女孩处 奔向男孩,如此往返直至回到家中。问小狗奔 波了多少路程?
•一般思维:
36 18 10 4 2 1 18 9 5 2 11 36 2 2 2 22
•逆向思维:
每场比赛淘汰一名失败球队,只有一名冠军,即 就是淘汰了36名球队,因此比赛进行了36场。
3 某人家住T市在他乡工作,每天下班后乘火车于 6时抵达T市车站,它的妻子驾车准时到车站接他 回家。一日他提前下班搭早一班火车于5时半抵达 T市车站,随即步行回家,它的妻子像往常一样驾 车前来,在半路上遇到他接回家时,发现比往常 提前了10分钟。问他步行了多长时间?
河 小船(至多2人)
但是乘船渡河的方案由商人决定.
商人们怎样才能安全过河?
问题分析
多步决策过程
3名商人 3名随从
决策~ 每一步(此岸到彼岸或彼岸到此岸)船上的人员
要求~在安全的前提下(两岸的随从数不比商人多),经有限 步使全体人员过河.
模型构成
xk~第k次渡河前此岸的商人数 yk~第k次渡河前此岸的随从数 sk=(xk , yk)~过程的状态
y
状态s=(x,y) ~ 16个格点
3
允许状态 ~ 10个 点
允许决策 ~ 移动1或2格;
2
s1
d1
k奇,左下移; k偶,右上移.
d1,
(完整word版)商人过河问题数学建模
作业1、2:商人过河一、问题重述问题一:4个商人带着4个随从过河,过河的工具只有一艘小船,只能同时载两个人过河,包括划船的人。
随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货。
乘船渡河的方案由商人决定。
商人们怎样才能安全过河?问题二:假如小船可以容3人,请问最多可以有几名商人各带一名随从安全过河。
二、问题分析问题可以看做一个多步决策过程。
每一步由此岸到彼岸或彼岸到此岸船上的人员在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。
用状态变量表示某一岸的人员状况,决策变量表示船上的人员情况,可以找出状态随决策变化的规律。
问题就转换为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到安全渡河的目标。
三.问题假设1. 过河途中不会出现不可抗力的自然因素。
2. 当随从人数大于商人数时,随从们不会改变杀人的计划。
3.船的质量很好,在多次满载的情况下也能正常运作。
4. 随从会听从商人的调度。
四、模型构成x(k)~第k次渡河前此岸的商人数x(k),y(k)=0,1,2,3,4;y(k)~第k次渡河前此岸的随从数k=1,2,…..s(k)=[ x(k), y(k)]~过程的状态S~允许状态集合S={(x,y) x=0,y=0,1,2,3,4; x=4,y=0,1,2,3,4;x=y=1,2,3}u(k)~第k次渡船上的商人数u(k), v(k)=0,1,2;v(k)~ 第k次渡船上的随从数k=1,2…..d(k)=( u(k), v(k))~过程的决策 D~允许决策集合D={u,v |u+v=1,2,u,v=0,1,2}状态因决策而改变s(k+1)=s(k)+(-1)^k*d(k)~状态转移律求d(k) ∈D(k=1,2,….n),使s(k)∈S 并按转移律s(k+1)=s(k)+(-1)^k*d(k)由(4,4)到达(0,0)数学模型:k+1k S =S +k k D (-1) (1)'4k k x x += (2)'4k k y y += (3)k.k x y ≥ (4)''k k x y ≥ (5)模型分析:由(2)(3)(5)可得44kk x y -≥- 化简得k k x y ≤综合(4)可得k k x y = 和 {}(,)|0,0,1,2,3,4k k k k k S x y x y === (6)还要考虑 {}'(',')|'0,'0,1,2,3,4kk k k k S x y x y === (7) 把(2)(3)带入(7)可得{}(4,4)|40,40,1,2,3,4k k k k k S x y x y =---=-=化简得{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8) 综合(6)(7)(8)式可得满足条件的情况满足下式{}(,)|0,4,0,1,2,3,4;k k k k k k k S x y x y x y ==== (9)所以我们知道满足条件的点如上图所示:点移动由{}(,)|4,0,1,2,3,4k k k k k S x y x y === (8) 到达{}(,)|0,0,1,2,3,4k k k k k S x y x y === (6)时,可以认为完成渡河。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要:M对商仆过河,一只船最多载N人,船上和岸上的仆人数都不能多于商人数,否则商人有危险。
安排合理的渡河方案,保证商人能安全渡河。
(可利用向量,矩阵,图解等方法)一.问题提出:有M对商仆乘船过河,一只船最多载N人,由商人和仆人自己划船渡河,在河的任意一岸,一旦仆人数多于商人数,仆人就可将商人杀死,谋取利益,但是乘船渡河的主动权掌握在商人们手中,商人们如何安排渡河方案,才能安全渡河?二.假设:商人和仆人都会划船,天气很好,无大风大浪,船的质量很好,船桨足够很多次的运载商人和仆人。
三.参数:1.设(x,y)是状态向量,表示任一岸的商人和仆人数,并且x,y分别要大于等于0,小于等于M。
2.设(m,n)是运载向量,表示运载的商人数和仆人数,0<=m<=N,0<=n<=N,0<=m+n<=N。
3.设用s表示所有的可取状态向量的集合。
4.设用d表示所有运载向量的集合。
5.设用表示从此岸到彼岸,作减;用表示从彼岸到此岸,作加。
Sk:表示第k步可取状态向量(sk属于s);dk:表示第k步可取转移向量(dk属于d);四.问题分析:商仆安全渡河问题可以视为一个多步决策过程,多步决策是指决策过程难以一次完成,而是多步优化,最后获取一个全局最优方案的决策方法。
对于每一步,即船由此岸驶向彼岸,或者船由彼岸驶向此岸的决策,不仅会影响到该过程的效果,而且还会影响到下一步的初始状态,从而对整个过程都会有影响。
所以,在每一次过河时,就不能只从这一次过河本身考虑,还要把它看成是整个过河过程中的一个部分。
在对船上的人员做决策时,要保证两岸的商人数不能少于仆人数,用最少的步伐是人员全部过河。
应用状态向量和运载向量,找出状态随运载变化的规律,此问题就转化为状态在允许范围内(即安全渡河条件),确定每一次该如何过河,从而达到渡河的目标。
现在我们都把它们数量化:即用数学语言来表示。
我们以3名商人为例设第k次渡河前此岸的商人数为x k,随从数为y k,k=1,2,…,x k,y k =0,1,2,3,将二维向量S k =(x k,y k)定义为状态。
安全渡河条件下的状态集合称为允许状态集合,记为S,则允许状态集合为:S={(x,y)| x = 0或3,y = 0,1,2,3,x = y = 1,2} (1)又设第k次渡船上的商人数为u k,随从数为v k,将二维向量d k=(u k+ v k)定义为决策。
则允许决策集合为:D={(u,v)| u + v = 1,2} (2)因为k为奇数时船从此岸驶向彼岸,k为偶数时船由彼岸驶向此岸,所以状态S k随着决策d k变化的规律即状态转移规律是:S k+1 = S k +(- 1)k d k(3)这样,制定安全渡河方案归结为如下的多步决策问题:求决策d k ∈ D(k = 1,2,…,n),使状态S k ∈ S按照规律(3),由初始状态S1=(3,3)经有限步(设为n)到达状态S n+1=(0,0)。
模型的解答下面通过程序给出这个多步决策问题的一个解,a[1]={0,0};a[2]={0,1};a[3]={0,2};a[4]={0,3};a[5]={3,0};a[6]={3,1};a[7]={3,2};a[8]={3,3};a[9]={1,1};a[10]={2,2};(*以上给出10个允许的状态*)d[1]={0,2};d[2]={2,0};d[3]={1,1};d[4]={0,1};d[5]={1,0};(*以上表示给出5个允许的决策*)i=1;j=1;k=1;s[0]=s[1]={3,3};Print[″此岸————船上————对岸″];Do[Do[s[i+1]=s[i]+(-1)^i d[j];t=0;Do[If[s[i+1]= =a[k],t=1],{k,1,10}];If[t= =0,Continue[ ]];(*以上是保证状态属于允许的状态*)l=Mod[i+1,2];m=l;u=0;If[i+1> =3,Do[If[s[i+1]= =s[m],u=1,Break[ ]],{m,l,i -1,2}]];If[u= =0,c[i+1]=d[j];Break[ ]],{j,1,5}];If[t= =0,Print[No,Result];Break[ ]];b[i+1]={3,3}-s[i+1];Print[s[i],″- - - -″,c[i+1],″- - - -″,b[i+1]];If[s[i+1]= ={0,0},Break[ ]],{i,1,12}]程序运行结果如下:此岸——————船上——————对岸{3,3}——————{0,2}——————{0,2} {3,1}——————{0,1}——————{0,1} {3,2}——————{0,2}——————{0,3} {3,0}——————{0,1}——————{0,2} {3,1}——————{2,0}——————{2,2} {1,1}——————{1,1}——————{1,1} {2,2}——————{2,0}——————{3,1} {0,2}——————{0,1}——————{3,0} {0,3}——————{0,2}——————{3,2} {0,1}——————{0,1}——————{3,1} {0,2}——————{0,2}——————{3,3} 可以得出经过11步的渡河就能达到安全渡河的目标及满足渡河的次数尽量少的条件。
这11步的渡河方案就是上面程序运行结果中船上下面的一列。
渡河的整个过程如下所示:去2随从回1随从(3商人3随从)—————→(3商人1随从)—————→去2随从回1随从(3商人2随从)—————→(3商人0随从)—————→去2商人回1商人1随从(3商人1随从)—————→(1商人1随从)—————→去2商人回1随从(2商人2随从)—————→(0商人2随从)—————→去2随从回1随从(0商人3随从)—————→(0商人1随从)—————→去2随从(0商人2随从)—————→(渡河成功)一.程序实现#include "stdio.h"#include "string.h"#include <memory>#include <stdlib.h>#include<iostream>using namespace std;#include "conio.h"FILE *fp;/*设立文件指针,以便将它用于其他函数中*/ struct a{long m,s;struct a *next;};/*数组类型a:记录各种情况下船上的商人和仆人数,m:代表商人数s:代表仆人数*/struct a *jj,head;/*head为头指针的链表单元(船上的人数的各种情况的链表)*/int n,total=0,js=0;/*total表示船上各种情况总数*/ struct aim {long m1,s1,m2,s2;int n;struct aim *back,*next;};/*用于建立双向的指针链表,记入符合的情况,m1,s1表示要过岸的商人数和仆人数;m2,s2表示过岸了的商人数和仆人数,n表示来回的次数*/int k1,k2;void freeit(struct aim *p){struct aim *p1=p; p1=p->back;free(p);if(p1!=NULL)p1->next=NULL;return;}/*释放该单元格,并将其上的单元格的next指针还原*/int determ(struct aim *p){ struct aim *p1=p;if(p->s1>k2)return -1;/*仆人数不能超过总仆人数*/if(p->m1>k1)return -1;/*商人数不能超过总商人数*/if(p->s2>k2)return -1;/*对岸,同上*/if(p->m2>k1)return -1;/*对岸,同上*/if(p->s1<0)return -1;/*仆人数不能为负*/if(p->s2<0)return -1;/*商人数不能为负*/if(p->m1<0)return -1;/*对岸,同上*/if(p->m2<0)return -1;/*对岸,同上*/if(p->m1!=0)if(p->s1>p->m1)return -1;if(p->m2!=0)if(p->s2>p->m2)return -1;/*两岸商人数均不能小于仆人数*/while(p1!=NULL){p1=p1->back;if(p1!=NULL)if(p1->n%2==p->n%2)if(p1->s1==p->s1)if(p1->s2==p->s2)if(p1->m1==p->m1)if(p1->m2==p->m2)return -1;}/*用于解决重复,算法思想:即将每次算出的链表单元与以前的相比较,若重复,则表示出现循环*/ if(p->s1==0&&p->m1==0)if(p->n%2==0)return 1;else return -1;/*显然如果达到条件就说明ok了*/return 0;}/*判断函数*/int sign(int n){if(n%2==0)return -1;return 1;}/*符号函数*/void copyit(struct aim *p3,struct aim *p){p3->s1=p->s1;p3->s2=p->s2;p3->m1=p->m1;p3->m2=p->m2;p3->n=p->n+1;p3->back=p;p3->next=NULL;p->next=p3;}/*复制内容函数,将p中的内容写入p3所指向的链表单元中*/void print(struct aim *p3){struct aim *p=p3;js++;while(p->back){p=p->back;}printf("\n第%d种方法:\n",js);fprintf(fp,"\n第%d种方法:\n",js);int count=0;while(p){ printf("%ld,%ld——》%ld,%ld\t",p->m1,p->s1,p->m2,p->s2);fprintf(fp,"%ld,%ld——》%ld,%ld\t",p->m1,p->s1,p->m2,p->s2);p=p->next;count++;}cout<<"一共有"<<count<<"步完成"<<endl;}/*打印函数,将p3所指的内容打印出来*/void trans(struct aim *p){struct aim *p3;/*p3为申请的结构体指针*/struct a *fla;int i,j,f;fla=&head;p3=(struct aim *)malloc(sizeof(struct aim)); f=sign(p->n);for(i=0;i<total;i++){fla=fla->next;copyit(p3,p);p3->s1-=fla->m*f;p3->m1-=fla->s*f;p3->s2+=fla->m*f;p3->m2+=fla->s*f;/*运算过程,即过河过程*/j=determ(p3);/*判断,j记录判断结果*/if(j==-1){if(i<total-1){continue;}else{freeit(p3);break;}}int count1=0;if(j==1){if(i<total-1){print(p3);count1++;continue;}else{print(p3);count1++;freeit(p3);break;}//cout<<count1<<endl;printf("%d",count1);printf("\n");}if(j==0)trans(p3);}return;}/*转移函数,即将人转移过河*//*n=0*/void main(){struct aim *p,*p1;int j,a,e,f;struct a *flag;/*flag是用与记录头指针*/ FILE*fpt;if((fpt=fopen("c:result.dat","w+"))==0){ printf("can′t creat it\n");exit(0);}fp=fpt;system("cls");printf("问题描述:三个商人各带一个随从乘船过河,一只小船只能容纳X人,由他们自己划船。