商人过河Matlab程序2

合集下载

数学建模 商人过河

数学建模 商人过河

数学建模课程作业论文题目:对商人过河问题的研究指导教师:黄光辉小组成员:黄志宇(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个随从过河,以及小船的最大载重人数改变时的问题,只需适当地改变相关的语句即可轻松实现模型的转换。

数学建模:研究商人过河问题

数学建模:研究商人过河问题

数学建模试验一陈述 【1 】试验标题:研讨商人过河问题一.试验目标:编写一个程序(可所以C,C++或Mathlab )实现商人安然过河问题.二.试验情形:Turbo c 2.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第三步:模子求解.#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中的内容写入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++){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);freeit(p3);break;}//cout<<cout1<<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人,由他们本身荡舟.三个商人窃听到侍从们谋害,在河的随意率性一岸上,只要侍从的人数比上人多,就杀失落商人.但是若何乘船渡河的决议计划权在商人手里,商人们若何安插渡河筹划确保自身安然?\n");printf("\n");p=(struct aim *)malloc(sizeof(struct aim));p->back=NULL;p->next=NULL;p->s2=0;p->m2=0;p->n=1;/*设立初始头指针*/printf("please input the total of people on the board\n");fprintf(fp,"\n请输入船上的人数\n");scanf("%d",&n);fprintf(fp,"\n%d\n",n);flag=&head;for(e=0;e<=n;e++)for(f=0;f<=n;f++)if(e+f>0&&e+f<=n){ total++;jj=(struct a*)malloc(sizeof(struct a));jj->m=e;jj->s=f;flag->next=jj;jj->next=NULL;flag=jj;}/*********************************/printf("please input the total of merchant and salvent as follow: mechant,salvent;\n"); fprintf(fp,"\nplease input the total of merchant and salvent as follow: mechant,salvent;\n"); scanf("%ld,%ld",&p->m1,&p->s1);fprintf(fp,"\n%ld,%ld\n",p->m1,p->s1);/**********************************/k1=p->m1;k2=p->s1;trans(p);fclose(fpt);getch();}第一步:三个商人,三个侍从的模子求解答案为:运行后的成果为:第1 种筹划:(3,3) 到(0,0).(3,1) 到(0,2).(3,2) 到(0,1).(3,0) 到(0,3).(3,1) 到(0,2).(1,1) 到(2,2).(2,2) 到 (1,1).(0,2) 到 (3,1).(0,3) 到 (3,0).(0,1) 到 (3,2).(0,2) 到 (3,1).(0,0) 到 (3,3)第2 种筹划:(3,3) 到(0,0).(3,1) 到(0,2).(3,2) 到(0,1).(3,0) 到(0,3).(3,1) 到(0,2).(1,1) 到(2,2).(2,2) 到 (1,1).(0,2) 到 (3,1).(0,3) 到 (3,0).(0,1) 到 (3,2).(1,1) 到 (2,2).(0,0) 到 (3,3)第3 种筹划:(3,3) 到(0,0).(2,2) 到(1,1).(3,2) 到(0,1).(3,0) 到(0,3).(3,1) 到(0,2).(1,1) 到(2,2).(2,2) 到 (1,1).(0,2) 到 (3,1).(0,3) 到 (3,0).(0,1) 到 (3,2)(.0,2) 到 (3,1).(0,0) 到 (3,3)第4 种筹划:(3,3) 到(0,0).(2,2) 到(1,1).(3,2) 到(0,1).(3,0) 到(0,3).(3,1) 到(0,2).(1,1) 到(2,2).(2,2) 到 (1,1).(0,2) 到 (3,1).(0,3) 到 (3,0).(0,1) 到 (3,2).(1,1) 到 (2,2)(0,0) 到 (3,3)第二步:四个商人三个侍从,其成果为:第1种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第2种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第3种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第4种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第5种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第6种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第7种办法:4,3::0,0 3,2::1,1 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第8种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第9种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第10种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第11种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第12种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第13种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第14种办法:4,3::0,0 3,2::1,1 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第15种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第16种办法:2,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第17种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第18种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第19种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第20种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第21种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第22种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,10,3::4,0 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第23种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 2,1::2,2 1,0::3,3 1,1::3,20,0::4,3 一共有16步完成第24种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第25种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第26种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第27种办法:4,3::0,0 3,2::1,1 3,3::1,0 2,2::2,1 4,2::0,14,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,1::4,2 0,2::4,10,0::4,3 一共有16步完成第28种办法:4,0::0,3 4,1::0,2 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第29种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第30种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 2,1::2,2 1,0::3,3 1,1::3,20,0::4,3 一共有16步完成第31种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 0,2::4,10,3::4,0 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第32种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 1,1::3,2 0,0::4,3 一共有14步完成第33种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第34种办法:2,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,1::4,2 0,2::4,10,0::4,3 一共有16步完成第35种办法:4,3::0,0 4,1::0,2 4,2::0,1 3,2::1,1 3,3::1,02,2::2,1 3,2::1,1 2,1::2,2 2,2::2,1 1,1::3,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第36种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第37种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第38种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第39种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第40种办法:2,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第41种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第42种办法:4,3::0,0 4,1::0,2 4,2::0,1 2,2::2,1 3,2::1,12,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成第43种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,21,1::3,2 0,0::4,3 一共有12步完成第44种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,22,1::2,2 1,0::3,3 1,1::3,2 0,0::4,3 一共有14步完成第45种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 0,2::4,1 0,3::4,0 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第46种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,21,1::3,2 0,0::4,3 一共有12步完成第47种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 0,1::4,20,2::4,1 0,0::4,3 一共有12步完成第48种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,1::4,2 0,2::4,1 0,0::4,3 一共有14步完成第49种办法:4,3::0,0 4,1::0,2 4,2::0,1 4,0::0,3 4,1::0,22,1::2,2 2,2::2,1 1,1::3,2 2,1::2,2 1,0::3,31,1::3,2 0,0::4,3 一共有12步完成。

商人过河

商人过河

数学建模题目:商人安全过河问题学院:数理与信息工程学院专业:数学与应用数学组员:指导老师:评分:摘要本文通过MATLAB编程来解决商人安全过河问题。

运用编程来计算分析,动态规划思想的应用步骤。

最后利用计算机编程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题。

针对此问题,为了求解3个商人和3个随从的过河问题,用数学分析方法,建立多步决策数学模型,并且加以求解。

首先通过图解法求解3个商人和3个随从的过河问题,引进状态、允许状态集合、状态转移等,通过多步决策将初始状态到最终状态来解决问题。

总之,问题转化为多步决策模型通过计算机、图解法解决了问题过河需要经过11此来回。

关键词:多步决策;计算机求解;状态转移律;图解法;MATLAB程序1 问题重述三名商人各带一个随从过河,一只小船只能容纳两个人,随从们约定,只要在河的任何一岸,一旦随从人数多于商人人数就杀人越货,但是商人们知道了他们的约定,并且如何过河的大权掌握在商人们手中,商人们该采取怎样的策略才能安全过河呢?S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。

商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。

但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?2 模型假设1.假设记第k次过河前A岸的商人数为X K,随从数为Y K,k=1,2,⋯ X K,Y K=0,1,2,3,将二维向量S K=(X K,Y K)定义为状态.把满足安全渡河条件下的状态集合称为允许状态集合。

记作S。

则S={(X K,Y K)|(X K=0,Y K=0,1,2,3),(X K=3,Y K=0,1,2,3),(X K=Y K=1)(X K =Y K=2)}2.假设记第k次过河船上的商人数为U K,随从数为V K将二维向量D K=(U K ,V K)定义为决策。

由小船的容量可知允许决策集合(记作D)为D={(U K ,V K)|U K+V K=1,2}={(0,1);(0,2);(1,0);(1,1);(2,0)}3 模型的建立与求解3.1 问题一3.1.1 问题分解在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。

数学模型实验商人过河

数学模型实验商人过河

《数学模型实验》实验报告姓名:王佳蕾学院:数学与信息科学学院地点:主楼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)。

(二)程序设计(三)运行结果、六、 结论体会:安全渡河问题可以看成一个多步决策过程。

商人过河问题matlab程序

商人过河问题matlab程序

商人过河functionjueche=guohe%程序开始需要知道商人和仆人数;n=input(’输入商人数目:’);nn=input('输入仆人数目:’);nnn=input('输入船的最大容量:');ifnn>nn=input(''输入商人数目:');nn=input('输入仆人数目:');nnn=input(’输入船的最大容量:');end%决策生成jc=1;%决策向量放在矩阵d中,jc为插入新元素的行标初始为1;for i=0:nnnfor j=0:nnnif(i+j<=nnn)&(i+j〉0)%满足条D={(u,v)|1〈=u+v<=nnn,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=n:-1:0for j=nn:-1:0if((i>=j)&((n—i)>=(nn-j)))|((i==0)|(i==n))%(i〉=j)&((n—i)>=(nn-j)))|((i==0)|(i==n))为可以存在状态的约束条件A(kx,1:3)=[i,j,1];%生成状态数组集合D`A(kx+1,1:3)=[i,j,0];kx=kx+2;endendj=nn;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。

数学建模:研究商人过河问题

数学建模:研究商人过河问题

数学建模实验一报告实验题目:研究商人过河问题一、实验目的:编写一个程序(可以是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程序完整)培训讲学

商人们怎样安全过河-(附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。

商人过河的MATLAB程序

商人过河的MATLAB程序

商人过河的MATLAB程序n=4;m=4;h=2; %初始状态及数据m0=0;n0=0;ticLS=0; % 允许的状态集合S与个数LSLD=0; %允许的决策集合D与个数LDfor i=0:nfor j=0:mif i>=j&n-i>=m-j|i==n|i==0LS=LS+1;S(LS,:)=[i j];endif i+j>0&i+j<=h&(i>=j|i==0)LD=LD+1;D(LD,:)=[i j];endendend%用搜寻法找出符合条件的渡河方案N=18;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<="" p="">k=1;sa=[];sb=[];for i0=1:le %第n次允许的策略集逐次搜索s0=q(i0,:);breakendfor i=1:LD %由s0搜索D后得到允许的状态s1=s0+(-1)^t*D(i,:); if s1==[m0,n0]sa=[m0,n0];sb=D(i,:);f0=1;breakendfor j=2:LS-1 %搜索对比S后允许状态if s1==S(j,:)if k==1sa(k,:)=s1;sb(k,:)=D(i,:);k=k+1;breakendif k>1 %对重复状态删除处理f1=0;for ii=1:k-1if s1==sa(ii,:)f1=1;breakendendend %……if f1==0sa(k,:)=s1;sb(k,:)=D(i,:);breakendendend %…………………end %………………………………end %……………………………………………q=sa; le=size(q,1);Q1(1:le,t*2-1:t*2)=q;Q2(1:le,t*2-1:t*2)=sb;t=t+1;endif length(q)==6tr=t-1;saa1=sa;SA=zeros(tr,2);SB=zeros(tr,2);for k=tr:-1:2k1=k-1;f0=0;sbb=Q2(:,k*2-1:k*2);saa=Q1(:,k1*2-1:k1*2);for i=1:2*Nsaa2=saa1-(-1)^k*sbb(i,:);for j=1:2*Nif saa2==saa(j,:)saa1=saa2;sbb1=sbb(i,:);f0=1;breakendendif f0==1endendSA(k1,:)=saa1;SB(k,:)=sbb1;endSA(tr,:)=[m0 n0];SB(1,:)=[m,n]-SA(1,:); %………………………………………………………………………………………………¥¥disp '初始状态:'X0=[m,n]disp '状态为:'SAdisp '决策为:'SBtocendif length(q)~=6disp '没有可行的方法过河'enddisp '可以走的状态为:';q。

n-m-k商人渡河问题解的存在性及算法实现

n-m-k商人渡河问题解的存在性及算法实现

n-m-k商人渡河问题解的存在性及算法实现付艳玲;刘高峰;张伟【摘要】We extend the businessmen-crossing-river problem into the most general case,i.e.the n-m-k businessmen-crossing-river problem,and establish the multi-step-decision mathematical model for this problem.Firstly,a state space tree corresponding to this mathematical model is created and an algorithm for traversing the state space tree by recursion and backtracking methods is designed.Secondly,the analysis of algorithm complexity is evaluated based on experimental results.Finally,the existence of solution for this problem is analyzed,and some theorems and proofs are introduced.The obtained results are potentially beneficial to some real life problems.%本文将商人渡河问题推广到最一般情况,即n-m-k商人渡河问题,建立了该问题的多步决策数学模型.首先,根据该数学模型得到一棵状态空间树,设计了采用递归和回溯方法遍历该状态空间树的算法步骤.其次,根据部分运行结果,分析了该问题的算法复杂度.最后,分析了该问题解的存在性,并给出了若干定理及其证明.本文已将商人渡河问题扩展成为广泛的经典例子,有利于解决实际生活中的问题.【期刊名称】《工程数学学报》【年(卷),期】2013(030)004【总页数】8页(P561-568)【关键词】商人渡河问题;算法实现;解的存在性【作者】付艳玲;刘高峰;张伟【作者单位】河南财政税务高等专科学校信息工程系,郑州451464;西安电子科技大学雷达信号处理国家重点实验室,西安710071;河南理工大学万方科技学院,郑州451400【正文语种】中文【中图分类】O2441 引言渡河问题[1,2]始于公元8世纪,至今它仍是一个逻辑难题.这个问题指的是:有不同的对象或生物,他们其中一些相互不共存,逐步地让一小群体从河的一岸到另一岸,经过有限步后,该群体全部从一岸达到另一岸,并且要求没有任何损失.渡河问题有不同的版本,如传教士和食人族难题,猜疑的丈夫问题,人狼羊菜问题,商人和随从渡河问题等,但是解决方法是类似的.商人和随从渡河问题通常指三名商人各带一个随从乘船渡河,一只小船只能容纳二人,由他们自己划行.随从们秘约:在河的任一岸,一旦随从的人数比商人多,就杀人越货.乘船渡河的大权掌握在商人们手中[3,4],商人们需要安排合理的渡河方案,以确保安全渡河.这类问题常作为数理逻辑、数学建模、图论以及算法设计的经典例子[5-8].到目前为止,n个商人n个随从船满载k人的渡河问题[1](以下简称n−n−k商人渡河问题)的程序实现虽已给出了,但n−n−k商人渡河问题解的存在性问题还不存在相关的结论.针对上面的情况,本文将渡河问题推广到最一般的情况,给出了n个商人m个随从船满载k人的渡河问题(以下简称n−m−k商人渡河问题)程序实现的方法,最后详细讨论了n−m−k商人渡河问题解的存在性问题并对相关结论进行了严格的证明.2 n−m−k商人渡河问题的数学模型本文考虑的商人渡河问题是最一般的情况,即n个商人与m个随从渡河,其中n≥m,渡河的小船至多可以容纳k人,并且n,m,k的取值互不影响.游戏的规则是在岸边一旦随从的人数比商人多,就杀人越货.针对这个问题,建立多步决策模型,其具体建模过程如下:本文把商人渡河问题视为一个多步决策过程,每一步(即船由此岸驶向彼岸或彼岸驶向此岸)都要对船上的人员作出决策(即决定船载几个商人与几个随从),在保证安全的前提下(即在两岸都不会发生杀人越货),经过有限步后使人员全部过河.用状态变量表示此岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,这样商人渡河问题就转化为在状态允许的变化范围内(即满足安全渡河的条件下)确定每一步的决策,达到安全渡河的目的.记第i次渡河前此岸的商人数为xi,随从数为yi,xi∈ {0,1,···,n},yi∈ {0,1,···,m}.将二维向量si=(xi,yi)定义为状态.将满足安全渡河条件下的状态集合称为允许状态集合,记为记第i次渡河时船上的商人数为ui,随从数为vi,将二维向量di=(ui,vi)定义为第i 次渡河决策.将所有允许决策(考虑到:小船有容量限制并且在船上商人数同样不得少于随从数)构成的集合称为允许决策集合,记为其中允许决策集合D的元素个数当i为奇数时,船从此岸驶向彼岸.当i为偶数时,船从彼岸驶向此岸,所以状态si随决策dj变化的规律是称这个规律为状态转移律.于是,确定安全渡河方案就归结为如下的多步决策问题:求每一步渡河的决策dj∈D,使得状态si∈S按照状态转移律由初始状态s1=(n,m),经有限步到达状态(0,0).至此,我们已经把n−m−k商人渡河问题用数学模型描述出来了.3 n−m−k商人渡河问题的算法求解3.1 算法思想n−m−k商人渡河问题的算法基本思想是:通过遍历状态空间树来搜索可行的渡河方案.在搜索过程中,用到了回溯法和剪枝法,针对渡河期间的某一步,当从允许决策集合S中选取所有决策方案都不能安全渡河时,说明这一步往下渡河是行不通的,那么这一步下面的状态空间树就不用搜索了(即剪枝),并且要求回溯到这一步的上一步,重新选择渡河决策.在搜索的过程中当此岸的商人和随从数一旦为0和0,表示已经找到了一个可行解,就输出这种渡河方案,然后继续搜索状态空间树的剩余部分,直至状态空间树被搜索完为止.这种算法思想可以求解出所有的渡河方案.n−m−k商人渡河问题状态空间树的每一个支点的分支数目与k有直接的联系,因为直接决定每一步渡河时的决策,即决定允许决策集合D,例如k=2时,可选的渡河决策就有5个,它们分别为(1,1),(2,0),(0,2),(1,0),(0,1).这样状态空间树就形如图1样子.因为渡河中的每一个状态往下有5种决策进行选择,所以状态空间树的每一支点有5个分支.图1 :状态空间树其次n−m−k商人渡河问题的关键问题是在当前此岸状态下怎样合理地选择允许决策集合D中的决策.设此岸的当前状态为si=(xi,yi),决策dj=(uj,vj)∈D,下一步此岸的状态si+1=si+(−1)idj.合理地选择允许决策集合D中的决策应满足的条件是:1) 满足渡河的规则:对此岸而言要求要么xi+1=0,要么xi+1̸=0,并且xi+1≥yi+1.对彼岸而言,要么n−xi+1=0,要么n−xi+1̸=0,并且n−xi+1≥m−yi+1;2) 不可重复性:如果当前是第i次渡河,那么下一步的状态si+1不能与前面的同奇偶次渡河后的状态相同.比如,前面第3次渡河后此岸状态为(1,1),后面第9次渡河后的此岸状态仍为(1,1),这就出现了重复,也就是说第9次渡河时选择的渡河决策是错误的,因为它出现了重复.不可重复性用来避免程序进行递归调用时出现无穷递归,或者说在遍历状态空间树时,避免了状态空间树的层数出现无穷大.3.2 算法描述n−m−k商人渡河问题的算法描述如下(采用了递归算法):算法的主体是:递归调用渡河子函数f(si,i,V),其中参数si表示当前准备渡河时此岸的商人与随从数,参数i表示当前状态是第几步状态,V表示从最开始到目前为止渡河过程中此岸所经历状态的集合.1) 初始化数据.设定商人数n,随从数m,船满载量k,允许决策集合D,允许状态集S,状态变量i=0,此岸初始状态si=(n,m),彼岸状态sp=(0,0),V={s0};2) 调用渡河子函数f(si,i,V).渡河子函数f(si,i,V)的执行步骤如下:设当前还没有渡河时的此岸人数为si,当前是第i步状态设j=1;(a) 若j>|D|,则结束当前的渡河子函数f(si,i,V)运行;若j≤|D|,则从允许决策集合D中选择允许决策向量dj;(b) 利用状态转移律计算si+1=si+(−1)idj;(c) 判断si+1和(n,m)−si+1是否在允许状态集S中,si+1是否与前面的状态不重复.如果都满足条件,则执行(d);如果存在一个条件不成立,则j=j+1,转到(a);(d) 将si+1添加到记录V中的第i+1位置,判断si+1=sp是否成立,如果成立,则说明找到了一种渡河方案,输出渡河方案(记录V中从1到i+1的元素);若不成立,则递归调用渡河子函数f(si+1,i+1,V);3) 第2)步结束以后,若有输出,则说明渡河问题有解,并且输出的解是渡河问题的所有可行解;若没有输出,则说明渡河问题无解.3.3 n−m−k商人渡河问题的算法复杂度分析n−m−k商人渡河问题的算法建立在状态空间树图1上.该算法的复杂度取决于算法在状态空间树上搜索时所遍历的树枝个数.算法在当前节点往下层搜索的树枝个数取决于当前的此岸与彼岸状态以及船满载人数.另外为了不让算法的状态出现重复情况,往下层搜索的树枝个数同样取决于以往所有出现的状态,所以该算法所搜索的状态空间树的树枝个数很难用一个解析式来表达,但我们可以分析出本文的n−m−k商人渡河问题是一个NP难问题.因为船满载人数k决定状态空间树节点的分支数目,公式为随着k的增加,状态空间树每个节点的分支数目为以k2数量级增加,另外随着n,m或k的增加,状态空间树的层数也会增加,于是算法所遍历的状态空间树枝个数会以指数复杂度形式增加.为了方便显示遍历树枝个数增长的情况,图2至图4的纵坐标采用了自然对数ln(·).在图2中,横坐标表示商人数(其中商人数=随从数,船满载人数固定为4人),纵坐标表示遍历树枝个数的自然对数,图2的曲线接近于一条斜率较小的直线,又因为纵坐标采取了自然对数的运算,这说明遍历树枝个数随着商人数(其中商人数=随从数,船满载人数固定为4人)的增加是成指数形式增加的.在图3中,横坐标表示商人数(其中商人数=随从数=船满载人数),纵坐标表示遍历树枝个数的自然对数,同样说明了遍历树枝个数随着商人数(其中商人数=随从数=船满载人数)的增加是成指数形式增加的.又因为图3的斜率略大于图2的斜率,所以在图3中遍历树枝个数随着商人数的增加而增长地更加剧烈.图2 : 当船满载人数为4时,遍历的树枝个数与商人数的关系(商人数=随从数)图3 : 人数与遍历树枝个数的关系(其中人数=商人数=随从数=船满载人数)图4 :船满载人数与遍历树枝个数的关系,其中商人数=随从数=4另外,当商人数n与随从数m都固定时,随着船满载人数k的增加,遍历的树枝个数也成指数增长.但当k>n+m后,随着船满载人数的增加,遍历树枝个数不会增长,这是因为此时船每次过河的决策方案与k=n+m时的决策方案相同,不会再随k的增加而变化,状态空间树每一个节点的分枝数目不再变化了.图4验证了上面的分析.当商人数与随从数固定时,即商人数=随从数=4,船满载人数从2到4这一段,遍历树枝个数的自然对数图形为一斜直线,说明在这一段,遍历树枝个数随船满载人数成指数增长.另外,后一段图形基本是一条水平直线,说明当船满载人数≥5时,遍历树枝个数的变化不大,并且定量结果显示:当k=8与9时,遍历的树枝个数是相同的,不再随着k的增加而变化.4 n−m−k商人渡河问题解的存在性根据3.3节的算法复杂度分析,得到n−m−k商人渡河问题在某些情况下解存在性的结论:1) 若k=2,n=m=1,2,3,n−m−k商人渡河问题有解;2) 若k=3,n=m=1,2,3,4,5,n−m−k商人渡河问题有解;3) 若k=2,n=m≥4,n−m−k商人渡河问题无解;4) 若k=3,n=m≥6,n−m−k商人渡河问题无解.下面给出除了上面情况之外的n−m−k商人渡河问题解的存在性定理及其证明.定理1 对任意的k≥2以及任意的n>m,n−m−k商人渡河问题有解.证明首先采用数学归纳法证明:开始时刻此岸为(n,m),彼岸为(0,0),船在此岸,经过有限步渡河后,总可以变成此岸为(n−m,0),彼岸为(m,m),船在此岸.1) 下面推导(n,m)和(0,0)变成(n−1,m−1)和(1,1),如表1.表1 :初时刻状态转移过程状态序号此岸状态彼岸状态商人数随从数商人数随从数1 n m 0 02 n−1 m−1 1 13 n−1 m 1 04 n−2 m−1 2 15 n−1 m−1 1 12) 假设满足定理条件的n−m−k商人渡河问题存在着状态(n−i,m−i)和(i,i),并且船在此岸,下面证明在此状态的基础上可以推导出状态(n−i−1,m−i−1)和(i+1,i+1),船在此岸,如表2.表2 :i时刻状态转移过程状态序号此岸状态彼岸状态商人数随从数商人数随从数x1 n−i m−i i i x2 n−i−1 m−i−1 i+1 i+1 x3 n−i−1 m−i i+1 i x4 n−i−2 m−i−1 i+2 i+1 x5 n−i−1 m−i−1 i+1 i+1综合以上1)和2),并且n>m,由数学归纳法得到开始时刻此岸为(n,m),彼岸为(0,0),船在此岸,经过有限步渡河后,总可以变成此岸为(n−m,0),彼岸为(m,m),船在此岸.设开始状态为:此岸状态为(n−m,0),彼岸状态为(m,m)以及船停在此岸;结束状态为:此岸状态为(0,0),彼岸状态为(n,m),船停在彼岸.下面给出如何从开始状态推导到结束状态.当n−m=1或2时,船直接将余下的商人载过河即可;若n−m>2,只需要重复过程:每次从此岸到彼岸时,船载2个商人.回来时,即从彼岸到此岸,船载1个商人.经过有限步总可以将余下的商人安全渡过河.证毕定理2 对任意的k≥4以及任意的n,m(n≥m),n−m−k商人渡河问题有解.证明假设商人数n大于随从数m,根据定理1,商人渡河问题有解.因此,只需考虑商人数n等于随从数m的情形.当k≥4且n=m时,要求船从此岸到彼岸始终载2个商人和2个随从过河,船从彼岸到此岸始终载1个商人和1个随从过河.交替重复以上过程,这样在任意时刻,两岸始终满足游戏规则,即商人数不会少于随从数,并且一个来回以后,此岸的人数在减少,彼岸人数在增加.当n和m是奇数时,则最后一步从此岸到彼岸,船载1个商人和1个随从过河,就可以载完所有的人;当n和m是偶数时,则最后一步从此岸到彼岸,船载2个商人和2个随从,就可以载完所有的人.证毕参考文献:[1]储理才.用Mathematica求解商人渡河问题[J].大学数学,2005,21(3):117-122 Chu L ing Mathematica to solve the businessmen-crossing-river problem[J].College Mathematics,2005,21(3):117-122[2]Ascher M.A river-crossing problem in cross-culturalperspective[J].Mathematics Magazine,1990,63(1):26-29[3]李天瑞.安全渡河问题的计算机求解和模拟[J].工科数学,1999,15(1):119-123 Li T R.Safe crossing river problem solving by computer andsimulation[J].Journal of Mathematics for Technology,1999,15(1):119-123 [4]王家华,王湘波.安全渡河问题的图解新法[J].西安石油大学学报(自然科学版),2007,22(4):103-105 Wang J H,Wang X B.A new graphic method for safe crossing river problem[J].Journal of Xi’an Shiyou Unive rsity(Natural Science Edition),2007,22(4):103-105[5]Lampis M,Mitsou V.Generalizing Alcuin’s river crossingproblem[C]//11th Panhellenic Conference in Informatics,2007:617-626 [6]Garey M R,Johnson D puters and Intractability:a Guide to the Theory of NP-completeness[M].New York:Freeman Company Press,1979 [7]Wells D G.The Penguin Book of Curious and InterestingPuzzles[M].London:Penguin Books,1992[8]Kraitchik M.Mathematical Recreations[M].New York:DoverPublications,1953。

商人过河数学模型

商人过河数学模型

商人过河数学模型专业信息与计算科学班级113010102姓名罗彪学号11301010229一、问题重述3名商人各带一名随从乘船渡河,一只小船只能容纳二人,由他们自己划行。

随从们密约,在河的任一岸,一旦随从的人数比商人多,就杀人越货。

但是如何乘船渡河的大权掌握在商人们手中。

商人们怎样才能安全过河呢?二、问题分析商随过河问题可以视为一个多步决策过程,通过多次优化,最后获取一个全局最优的决策方案。

对于每一步,即船由此岸驶向彼岸或由彼岸驶向此岸,都要对船上的人员作出决策,在保证两岸的商人数不少于随从数的前提下,在有限步内使全部人员过河。

用状态变量表示某一岸的人员状况,决策变量表示船上的人员状况,可以找出状态随决策变化的规律,问题转化为在状态的允许变化范围内(即安全渡河条件),确定每一步的决策,达到安全渡河的目标。

三、模型假设1.每个商人和随从都会划船;2.只有一条船,且每条船上最多只能乘坐两个人;3.所有商人与随从之间没有矛盾,不会出现两人不愿意坐一条船的现象;4.船在渡河的过程中不受外界环境的影响。

四、模型的建立与求解 1.模型建立k x ~第k 次渡河前此岸的商人数,k y ~第k 次渡河前此岸的随从数k x , k y =0,1,2,3; k =1,2,… …k S =(k x , k y , c k )~过程的状态,其中k x , k y , c k 分别表示对应时刻此岸的商人,仆人数以及船的行进方向,其中c 取值1表示即将向彼岸运行,为0表示即将向此岸运行S ~ 允许状态集合,S={(x , y )| x =0, y =0,1,2,3; x =3 ,y =0,1,2,3; x =y =1,2}k u ~第k 次渡船上的商人数 k v ~第k 次渡船上的随从数k d =(k u , k v )~决策,D={(u , v )| 21≤+≤v u ,k u , k v =0,1,2} ~允许决策集合k =1,2,… …因为k 为奇数时船从此岸驶向彼岸,k 为偶数时船从彼岸驶向此岸,所以状态k S 随决策k d 的变化规律是1+k S =k S +k )1(-k d ~状态转移律求k d ∈D(k =1,2, …n), 使k S ∈S, 并按转移律由1S =(3,3,1)到达状态1+n S =(0,0,0(1))。

商人过河

商人过河

数学建模题目:商人安全过河问题学院:数理与信息工程学院专业:数学与应用数学组员:指导老师:评分:摘要本文通过MATLAB编程来解决商人安全过河问题。

运用编程来计算分析,动态规划思想的应用步骤。

最后利用计算机编程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题。

针对此问题,为了求解3个商人和3个随从的过河问题,用数学分析方法,建立多步决策数学模型,并且加以求解。

首先通过图解法求解3个商人和3个随从的过河问题,引进状态、允许状态集合、状态转移等,通过多步决策将初始状态到最终状态来解决问题。

总之,问题转化为多步决策模型通过计算机、图解法解决了问题过河需要经过11此来回。

关键词:多步决策;计算机求解;状态转移律;图解法;MATLAB程序1 问题重述三名商人各带一个随从过河,一只小船只能容纳两个人,随从们约定,只要在河的任何一岸,一旦随从人数多于商人人数就杀人越货,但是商人们知道了他们的约定,并且如何过河的大权掌握在商人们手中,商人们该采取怎样的策略才能安全过河呢?S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。

商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。

但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?2 模型假设1.假设记第k次过河前A岸的商人数为X K,随从数为Y K,k=1,2,⋯ X K,Y K=0,1,2,3,将二维向量S K=(X K,Y K)定义为状态.把满足安全渡河条件下的状态集合称为允许状态集合。

记作S。

则S={(X K,Y K)|(X K=0,Y K=0,1,2,3),(X K=3,Y K=0,1,2,3),(X K=Y K=1)(X K =Y K=2)}2.假设记第k次过河船上的商人数为U K,随从数为V K将二维向量D K=(U K ,V K)定义为决策。

由小船的容量可知允许决策集合(记作D)为D={(U K ,V K)|U K+V K=1,2}={(0,1);(0,2);(1,0);(1,1);(2,0)}3 模型的建立与求解3.1 问题一3.1.1 问题分解在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。

商人过河问题

商人过河问题

商人过河问题摘要:为了求解3个商人和3个随从的过河问题,用数学分析方法,建立数学模型,并且加以求解,展示动态规划思想的应用步骤。

最后利用计算机编程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题的作用。

关键词:多步决策计算机求解状态转移律图解法 MATLAB程序一.问题提出S个商人各带一个随从乘船过河,一只小船只能容纳K人,由他们自己划船。

商人们窃听到随从们密谋,在河的任意一岸上,只要随从的人数比商人多,就杀掉商人。

但是如何乘船渡河的决策权在商人手中,商人们如何安排渡河计划确保自身安全?二.问题的关键解决的关键集中在商人和随从的数量上,以及小船的容量上,该问题就是考虑过河步骤的安排和数量上。

各个步骤对应的状态及决策的表示法也是关键。

三.问题的分析在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。

由于船上人数限制,这需要多步决策过程,必须考虑每一步船上的人员。

动态规划法正是求解多步决策的有效方法。

它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。

直到可以直接求出其解的子问题为止。

分解成所有子问题按层次关系构成一棵子问题树.树根是原问题。

原问题的解依赖于子问题树中所有子问题的解。

四.模型假设记第k次过河前A岸的商人数为XK,随从数为YK k=1,2,⋯ XK ,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)}五.模型建立:动态规划法正是求解多步决策的有效方法。

商人过河问题程序

商人过河问题程序
return;
end;
function jueche=guohe
%%%%%%%%%%%%%%%%%%%%%%
程序开始需要知道商人和仆人数;
n=input(‘输入商人数目:’,’12’);
nn=input(‘输入仆人数目:’,’12’);
nnn=input(‘输入船的最大容量:’,’20’);
if nn>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)
c=A(i,:)+d(j,:) ;
x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3))) ;
v(i,x)=1; %x为空不会改变v值
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dijstra算法
{
int x;
int y;

数学建模商人过河__论文

数学建模商人过河__论文

组长:王鹏道110714组员:任利伟110713、孙祎110706小组成员负责情况:王鹏道:选择论文题目、设计论文版面字体、分配成员任务、总结任利伟:一、问题提出、关键、分析。

二、模型假设、三、模型建立孙祎:四、模型求解、五、模型的检验、拓展及延伸2014年11月24日摘要为了求解3个商人与3个随从的过河问题,用数学分析方法,建立数学模型,并且加以求解,展示动态规划思想的应用步骤。

最后利用计算机蝙程进行求解,获得过河问题的完整求解过程;有效地求解类似多步决策问题的作用。

关键词:多步决策计算机求解状态转移律图解法一、问题的提出随从们密约, 在河的任一岸, 一旦随从的人数比商人多, 就杀人越货,但就是乘船渡河的方案由商人决定、商人们怎样才能安全过河?二、问题的关键解决的关键集中在商人与随从的数量上,以及小船的容量上,该问题就就是考虑过河步骤的安排与数量上。

各个步骤对应的状态及决策的表示法也就是关键。

三、问题的分析在安全的前提下(两岸的随从数不比商人多),经有限步使全体人员过河。

由于船上人数限制,这需要多步决策过程,必须考虑每一步船上的人员。

动态规划法正就是求解多步决策的有效方法。

它要求把解的问题一层一层地分解成一级一级、规模逐步缩小的子问题。

直到可以直接求出其解的子问题为止。

分解成所有子问题按层次关系构成一棵子问题树.树根就是原问题。

原问题的解依赖于子问题树中所有子问题的解。

四、模型假设记第k 次过河前A 岸的商人数为X K ,随从数为Y K k=1,2,⋯X K ,Y K =0,1,2,3,将二维向量S K =(X K ,Y K )定义为状态.把满足安全渡河条件下的状态集合称为允许状态集合。

记作S 。

则S={(X K ,Y K )|(X K =0,Y K =0,1,2,3),(X K =3,Y K =0,1,2,3),(X K =Y K =1)(X K =Y K =2)} 记第k 次过河船上的商人数为U K随从数为V K将二维向量D K =(U K ,V K )定义为决策.由小船的容量可知允许决策集合(记作D)为D={(U K ,V K )|U K +V K =l,2}={(O,1);(O,2);(1,O);(1,1);(2,O)}五、 模型建立:动态规划法正就是求解多步决策的有效方法。

商人过河问题matlab程序只是分享

商人过河问题matlab程序只是分享

商人过河functionjueche=guohe%程序开始需要知道商人和仆人数;n=input('输入商人数目:');nn=input('输入仆人数目:');nnn=input('输入船的最大容量:');ifnn>nn=input(''输入商人数目:');nn=input('输入仆人数目:');nnn=input('输入船的最大容量:');end%决策生成jc=1;%决策向量放在矩阵d中,jc为插入新元素的行标初始为1;for i=0:nnnfor j=0:nnnif(i+j<=nnn)&(i+j>0)%满足条D={(u,v)|1<=u+v<=nnn,u,v=0,1,2}d(jc,1:3)=[i,j,1];%生成一个决策向量立刻扩充为三维;d(jc+1,1:3)=[-i,-j,-1];%同时生成他的负向量;jc=jc+2;%由于生成两个决策向量,则jc要向下移动两个;end endj=0;end%状态数组生成kx=1;%状态向量放在A矩阵中,生成方法同矩阵生成;for i=n:-1:0for j=nn:-1:0if((i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))%(i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))为可以存在状态的约束条件A(kx,1:3)=[i,j,1];%生成状态数组集合D`A(kx+1,1:3)=[i,j,0];kx=kx+2;endendj=nn;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;elsed=find(T==mi);d=d(1);P(d)=mi;T(d)=inf;k=d;S(d)=1;endendif lmd(y)==infjueche='cannotreach'; 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)=[];。

商人过河matlab程序以及解析

商人过河matlab程序以及解析

商人过河m a t l a b程序以及解析The latest revision on November 22, 2020数学建模作业班级:数学131姓名:丁延辉学号:(二)商人过河Matlab代码三个商人三个随从z=zeros(30,3);%z为由(a,b,c)的列向量组成的3行30列数组,初始化为0矩阵,a,b,c代表此刻此岸的商人,仆人数量以及船的运行状态,c=1表示即将向彼岸运行m=zeros(1,20);%m为一维行向量,初始化为1矩阵,用于在后面的程序中判断第k次选择的乘船方案d=[0,1,1;0,2,1;1,0,1;1,1,1;2,0,1];%共有5种可以选择的乘船方案,最后面一列全为1,即用于在后面表示使得z(k,3)的取值保持随着k的奇偶性保持着0-1变换.z(1,:)=[3,3,1];%初始状态为[3,3,1]k=1;m(k)=1;%第一次默认的乘船方案为决策1——d(1)flag=1;%用于在后面判断是否成功找到方案answer=0;%用于在后面判断是否找到答案whilek>0%保持k>0ifm(k)>5flag=0;break;endp=0;z(k+1,:)=z(k,:)+(-1)^k*d(m(k),:);%每一次的运算规则都是z(k+1)=z(k)-(-1)^k*d(m(k),:),d(m(k),:)表示决策方案a=z(k+1,1);%将当前情况的矩阵数值复制给a商人,b仆人b=z(k+1,2);c=z(k+1,3);if(a==3&&(b==0||b==1||b==2||b==3))||(a==1&&b==1)||(a==2&&b= =2)||(a==0&&(b==0||b==1||b==2||b==3))%判断(a,b)是否符合限定情况forj=1:k%判断是否此岸a,b,c与之前有重复,如果是,结束此次循环,重新选择乘船方案ifa==z(j,1)&&b==z(j,2)&&c==z(j,3)ifm(k)~=5%决策方案只有5种,所以m(k)<=5,m(k)=m(k)+1;%因为有重复,所以换下一种决策方案elsewhile(m(k)==5)&&(k>1)k=k-1;%回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案end%while循环的目的是防止前面几步的决策都是5,导致k=k-1,m(k)=m(k)+1后数组越界,一直找到前面不是m(k)=5的步骤m(k)=m(k)+1;endp=1;break;elsep=0;endendifp==1%程序在跳出内层for循环之后,因为要换成决策方案,所以同时跳出,直接进入下一次while循环,continue;endifa==0&&b==0%判断是否达到目标情况answer=1;fprintf('Successfullyfound!\n每一次的此岸人员分布:商人仆人\n')fori=1:100fprintf('第%2d次%d%d\n',i,z(i,1),z(i,2))ifz(i,1)==0&&z(i,2)==0break;endend%如果不是,进入下一步骤,计算z(k+2)ifm(k)~=5m(k)=m(k)+1;%这是正常的进入下一次,所以仍从d1乘船决策1开始elsewhile(m(k)==5)&&(k>1)k=k-1;end;m(k)=m(k)+1;endcontinue;elsek=k+1;%如果不是,进入下一步骤,计算z(k+2)m(k)=1;%这是正常的进入下一次,所以仍从d1乘船决策1开始continue;endelseifm(k)~=5m(k)=m(k)+1;%如果没有符合限定情况,结束该次循环,改变上一次的乘船方案elsewhile(m(k)==5)&&(k>1)k=k-1;endm(k)=m(k)+1;%回溯,这一步骤已经把所有决策取尽,无可用解法,于是将后退一步,同时换下一种决策方案continue;endendendifanswer==0&&flag==0fprintf('NoAnswer!\n')end。

商人过河

商人过河

可用 ∑ xi , ∑ y j 表示岸上或船上的商人和随从人数。 具体过河顺序如
i =1
i =1

4
4

下图所示: 北岸 (4, 4) 船上 (0, 2) (1, 1) (4, 3) (4, 3) (4, 1) (4, 2) (2, 2) (3, 3) (0, 3) (0, 4) (0, 2) (0, 3) (0, 1) (0, 2) (0, 0) (1,0) (0, 1) (0, 2) (0, 1) (2, 0) (1, 1) (3, 0) (0, 1) (0, 2) (0, 1) (0, 2) (0, 1) (0, 2) 南岸 (0,2) (1,1) (0,1) (0, 1) (0, 3) (0, 2) (2, 2) (1, 1) (4, 1) (4, 1) (4, 2) (4, 1) (4, 3) (4, 2) (4, 4)
3
3

下图所示:
北岸 {3,3}
船上 {0,2} {1,1}
南岸 {0,2} {1,1} {0,1} {0,1} {0,3} {0,2} {2,2} {1,1} {3,1} {3,0} {3,2} {3,1} {3,3}
{3,2} {3,2} {3,0} {3,1} {3,1} {2,2} {2,2} {0,2} {0,3} {0,1} {0,2}
4
4
x1 + x2 + x3 + x4 ≠ 4 x1 + x2 + x3 + x4 ≠ 0
综合以上三个约束条件,得到商人和随从的合理分配方法,用 matlab 编程求解: (得到允许决策矩阵 100 个,附:程序文件二) 决策安排
0 0 0 0 0 4 4 4 4 4 1 2 3 0 1 2 3 4 0 1 2 3 4 1 2 3

商人带工人过河matlab程序

商人带工人过河matlab程序

商人带工人过河matlab程序function boat(m,k)%输入变量m表示商人或工人数,k表示小船的最大容量.%%本程序编程思路是用单元型变量B和C分别表示允许状态集合S和决策d.%将S中的每一个元素用所有决策d按照状态转移律迭代.%对于每一步中每一个元素的迭代结果,剔除掉不符合事实的情况.%当某一个迭代结果是[0,0]时,说明当商人或工人个数是m个,小船的最大容量是k时可以在有限的步骤下安全过河.%当所有迭代结果都被剔除时,说明当商人或工人个数是m个,小船的最大容量是k个时不可以在有限的步骤下安全过河.%%本程序的优点是可以计算出小船最大容量超过2时的情况.%%下面三个for语句是根据参数m算出所有允许状态集合S中的元素,用B表示.for i=1:m+1A=[m,i-1];B{i}=A;endfor i=m+2:2*mA=[i-(m+1),i-(m+1)];B{i}=A;endfor i=2*m+1:3*m+1A=[0,i-(2*m+1)];B{i}=A;end%下面的for语句是根据参数k算出所有决策d,用C表示. t=1;for u=0:1:kfor v=0:1:kif u+v>=1&u+v<=kC{t}=[u,v];t=t+1;endendendD{1,1}=[m,m];% D{1,1}表示初始状态.w=1;% w控制是否能够迭代成功.h=1;% h控制元素的个数.j=2;% j表示迭代的次数.x=0;% x是用来剔除掉不在允许状态集合中的元素.y=0;% y是防止重复剔除同一个元素.l=0;% l使用来标记元素是否被剔除.z(1)=0;z(2)=1;% z(j)表示上一步迭代后所剩下的所有元素.while w>0% p表示可以进行下一步迭代的所有元素.for p=z(j-1)+1:z(j)% q表示每一个元素要经过k*(k+3)/2种决策迭代.for q=1:k*(k+3)/2D{h+1,j}=D{p,j-1}+(-1)^(j-1).*C{q};h=h+1;l=1;%下面的for语句是核查迭代结果是否在允许状态集合B 中.for e=1:3*m+1if D{h,j}==B{e}x=1;break;endendif x==0h=h-1;y=1;l=0;end%下面的if语句是剔除掉本次迭代过程中出现的重复元素.if j>2&y==0for i=z(j)+1:h-1if D{h,j}==D{i,j};h=h-1;l=0;break;endendend%下面的if语句是剔除掉以前重复的元素.if j>2&y==0if j==3for i=z(1)+1:z(2)if D{h,j}==D{i,j-2} h=h-1;l=0;break;endendelsefor i=z(j-2)+1:z(j-1)if D{h,j}==D{i,j-2} h=h-1;l=0;break;endendendendif l==1for g=1:j-1D{h,g}=D{p,g};endendif l==1&D{h,j}==[0,0]w=-1;%w=-1表示商人和工人可以在有限的步骤下安全过河.break;endx=0;y=0;l=0;endif w==-1;%w=-1表示商人和工人可以在有限的步骤下安全过河.break;endendj=j+1;z(j)=h;if z(j)==z(j-1)w=-2;%w=-2表示商人和工人不可以在有限的步骤下安全过河.break;endendif w==-1disp('商人和工人可以在有限的步骤下安全过河') disp('步骤如下:')for g=1:j-1D{h,g}endendif w==-2disp('商人和工人不可以在有限的步骤下安全过河') end。

商人过河问题(二)java实现

商人过河问题(二)java实现

商⼈过河问题(⼆)java实现反正我是没跑通。

⾃⼰调了很久。

不多说,直接贴代码。

运⾏不通过找我。

通⽤版实现。

package mechants_River;/*** m 商⼈⼈数* s 随从⼈数* dual 对象表⽰商⼈和随从的组成状态,也就是⼀次渡河⽅案。

* add minus 状态变迁的计算* @author tina**/public class Dual {int m, s;public Dual(int m, int s) {this.m = m;this.s = s;}Dual add(Dual e) {return new Dual(this.m + e.m, this.s + e.s);}Dual minus(Dual e) {return new Dual(this.m - e.m, this.s - e.s);}public boolean greaterOrEqual(Dual d){//System.out.println("is Valid"+this.m+" "+this.s+"----"+d.m+" "+d.s);return (this.m>=d.m&&this.s>=d.s? true:false);}}View Codepackage mechants_River;import java.util.ArrayList;import java.util.List;import java.util.Set;import java.util.TreeSet;public class Path {Dual carryingSchema[]; // ⼩船可提供的载⼈⽅案Dual initStatus; // 初始状态Dual endStatus; // 终⽌状态List<Node> path = new ArrayList<Node>(); // 过河路径Set<Node> iNode = new TreeSet(); // 孤⽴结点public Path(int merchant, int servant, int carrying) {initStatus = new Dual(merchant, servant);endStatus = new Dual(0, 0);buildCarryingSchema(carrying);findPath();if (path.isEmpty()) {System.out.println("Can't solve the problem");} else {for (Node e : path) {System.out.println(e);}}}public static void main(String[] args) {Path p = new Path(5, 5, 2);}public boolean isRepeat() {return path.contains(this);}/*** 构建渡河⽅案根据⼩船的最⼤可载⼈数且⼩船不能空计算可⾏⽅案每个⽅案表⽰⼀个dual 对象并把保存在carryingSchema中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3名(或多名)商人各带一名随从乘船渡河,只有一条小船,且此船只能容纳2人,由他们自己划行,随从们密约,在河的任意岸,一旦随从人数比商人多,就杀商人,此密约被商人知道,如何乘船渡河的大权掌握在商人们手中,那么商人们应怎样安排每次乘船方案,才能安全渡河呢?
function foot=merchant
%%%%%%%%%%%%%%%%%%%%%% 程序开始需要知道商人数,仆人数,船的最大容量
n=input('输入商人数目:');
nn=input('输入仆人数目:');
nnn=input('输入船的最大容量:');
if nn>n
n=input('输入商人数目:');
nn=input('输入仆人数目:');
nnn=input('输入船的最大容量:');
end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 决策生成
jc=1; % 决策向量存放在矩阵“d”中,jc为插入新元素的行标初始为1 for i=0:nnn
for j=0:nnn
if(i+j<=nnn)&(i+j>0) % 满足条
件D={(u,v)|1<=u+v<=nnn,u,v=0,1,2}
d(jc,1:3)=[i,j 1]; %生成一个决策向量后立刻将他扩充为三维(再末尾加“1”)
d(jc+1,1:3)=[-i,-j,-1]; % 同时生成他的负向量
jc=jc+2; % 由于一气生成两个决策向量,jc指标需要往下移动两个单位
end
end
j=0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 状态数组生成
kx=1; % 状态数组存放在矩阵“A”中,生成方法同决策生成
for i=n:-1:0
for j=nn:-1:0
if((i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))
% (i>=j)&((n-i)>=(nn-j)))|((i==0)|(i==n))为可以存在的状态的约束
条件
A(kx,1:3)=[i,j,1];
% 生成状态数组集合D`
A(kx+1,1:3)=[i,j,0];
kx=kx+2;
end
end
j=nn;
end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 将状态数组生成抽象矩

k=(1/2)*size(A,1);
CX=zeros(2*k,2*k);
a=size(d,1);
for i=1:2*k
for j=1:a
c=A(i,:)+d(j,:) ;
x=find((A(:,1)==c(1))&(A(:,2)==c(2))&(A(:,3)==c(3))) ;
v(i,x)=1; % x为空不会改变v的值
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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)==m
break;
end
for j=1:size(a,1)
pp=a(j,1);
if v(k,pp)~=0
if T(pp)>(P(k)+v(k,pp))
T(pp)=(P(k)+v(k,pp));
lmd(pp)=k;
end
end
end
mi=min(T(a));
if mi==inf
break;
else
d=find(T==mi);
d=d(1);
P(d)=mi;
T(d)=inf;
k=d;
S(d)=1;
end
end
if lmd(y)==inf
foot='can not reach';
return;
end
foot(1)=y;
g=2; h=y;
while(1)
if h==x
break;。

相关文档
最新文档