数学建模:研究商人过河问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数学建模试验一陈述 【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|,=<+ 第三步:模子求解. #include "stdio.h" #include "string.h" #include #include #include 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;