数学建模研究商人过河问题Word文件下载.docx
《数学建模研究商人过河问题Word文件下载.docx》由会员分享,可在线阅读,更多相关《数学建模研究商人过河问题Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
按照转移律,由初始状态
经有限n步到达
第三步:
模型求解。
#include"
stdio.h"
string.h"
#include<
memory>
stdlib.h>
iostream>
usingnamespacestd;
conio.h"
FILE*fp;
/*设立文件指针,以便将它用于其他函数中*/
structa{
longm,s;
structa*next;
};
/*数组类型a:
记录各种情况下船上的商人和仆人数,m:
代表商人数s:
代表仆人数*/
structa*jj,head;
/*head为头指针的链表单元(船上的人数的各种情况的链表)*/
intn,total=0,js=0;
/*total表示船上各种情况总数*/
structaim{
longm1,s1,m2,s2;
intn;
structaim*back,*next;
/*用于建立双向的指针链表,记入符合的情况,m1,s1表示要过岸的商人数和仆人数;
m2,s2表示过岸了的商人数和仆人数,n表示来回的次数*/
intk1,k2;
voidfreeit(structaim*p){
structaim*p1=p;
p1=p->
back;
free(p);
if(p1!
=NULL)
p1->
next=NULL;
return;
}/*释放该单元格,并将其上的单元格的next指针还原*/
intdeterm(structaim*p)
{structaim*p1=p;
if(p->
s1>
k2)return-1;
/*仆人数不能超过总仆人数*/
m1>
k1)return-1;
/*商人数不能超过总商人数*/
s2>
/*对岸,同上*/
m2>
s1<
0)return-1;
/*仆人数不能为负*/
s2<
/*商人数不能为负*/
m1<
m2<
m1!
=0)
p->
m1)return-1;
m2!
m2)return-1;
/*两岸商人数均不能小于仆人数*/
while(p1!
=NULL){
p1=p1->
if(p1->
n%2==p->
n%2)
s1==p->
s1)
s2==p->
s2)
m1==p->
m1)
m2==p->
m2)
return-1;
}/*用于解决重复,算法思想:
即将每次算出的链表单元与以前的相比较,若重复,则表示出现循环*/
s1==0&
&
m1==0)
n%2==0)return1;
elsereturn-1;
/*显然如果达到条件就说明ok了*/
return0;
}/*判断函数*/
intsign(intn){
if(n%2==0)return-1;
return1;
}/*符号函数*/
voidcopyit(structaim*p3,structaim*p){
p3->
s1=p->
s1;
s2=p->
s2;
m1=p->
m1;
m2=p->
m2;
n=p->
n+1;
back=p;
next=p3;
}/*复制容函数,将p中的容写入p3所指向的链表单元中*/
voidprint(structaim*p3){
structaim*p=p3;
js++;
while(p->
back){p=p->
}
printf("
\n第%d种方法:
\n"
js);
fprintf(fp,"
intcount=0;
while(p){printf("
%ld,%ld:
:
%ld,%ld\t"
p->
m1,p->
s1,p->
m2,p->
s2);
p=p->
next;
count++;
cout<
<
"
一共有"
count<
步完成"
endl;
}/*打印函数,将p3所指的容打印出来*/
voidtrans(structaim*p){
structaim*p3;
/*p3为申请的结构体指针*/
structa*fla;
inti,j,f;
fla=&
head;
p3=(structaim*)malloc(sizeof(structaim));
f=sign(p->
n);
for(i=0;
i<
total;
i++){
fla=fla->
copyit(p3,p);
s1-=fla->
m*f;
m1-=fla->
s*f;
s2+=fla->
m2+=fla->
/*运算过程,即过河过程*/
j=determ(p3);
/*判断,j记录判断结果*/
if(j==-1){
if(i<
total-1){continue;
else{
freeit(p3);
break;
}}
intcount1=0;
if(j==1){if(i<
total-1){print(p3);
count1++;
continue;
else{print(p3);
//cout<
cout1<
%d"
count1);
);
if(j==0)trans(p3);
}/*转移函数,即将人转移过河*/
/*n=0*/
voidmain()
{structaim*p,*p1;
intj,a,e,f;
structa*flag;
/*flag是用与记录头指针*/
FILE*fpt;
if((fpt=fopen("
c:
result.dat"
"
w+"
))==0){
can'
tcreatit\n"
exit(0);
fp=fpt;
system("
cls"
printf("
问题描述:
三个商人各带一个随从乘船过河,一只小船只能容纳X人,由他们自己划船。
三个商人窃听到随从们密谋,在河的任意一岸上,只要随从的人数比上人多,就杀掉商人。
但是如何乘船渡河的决策权在商人手里,商人们如何安排渡河计划确保自身安全?
p=(structaim*)malloc(sizeof(structaim));
back=NULL;
s2=0;
m2=0;
n=1;
/*设立初始头指针*/
pleaseinputthetotalofpeopleontheboard\n"
\n请输入船上的人数\n"
scanf("
&
\n%d\n"
n);
flag=&
for(e=0;
e<
=n;
e++)
for(f=0;
f<
f++)
if(e+f>
0&
e+f<
=n)
{total++;
jj=(structa*)malloc(sizeof(structa));
jj->
m=e;
s=f;
flag->
next=jj;
flag=jj;
}
/*********************************/
pleaseinputthetotalofmerchantandsalventasfollow:
mechant,salvent;
\npleaseinputthetotalofmerchantandsalventasfollow:
%ld,%ld"
m1,&
s1);
\n%ld,%ld\n"
/**********************************/
k1=p->
k2=p->
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,03,2:
1,14,2:
0,12,2:
2,13,2:
1,1
2,1:
2,22,2:
2,10,2:
4,10,3:
4,00,1:
4,2
1,1:
3,20,0:
4,3一共有12步完成
第2种方法:
2,21,0:
3,31,1:
4,3一共有14步完成
第3种方法:
0,2:
4,10,0:
第4种方法:
2,11,1:
3,22,1:
2,20,1:
第5种方法:
第6种方法:
3,3
3,20,1:
4,20,2:
第7种方法:
第8种方法:
0,14,0:
0,34,1:
0,2
第9种方法:
第10种方法:
第11种方法:
第12种方法:
第13种方法:
第14种方法:
第15种方法:
1,13,3:
1,02,2:
第16种方法:
第17种方法:
第18种方法:
第19种方法:
第20种方法:
第21种方法:
第22种方法:
2,14,2:
0,1
4,0:
0,22,1:
4,1
0,3:
4,21,1:
第23种方法:
4,22,1:
3,2
0,0:
4,3一共有16步完成
第24种方法:
第25种方法:
第26种方法:
第27种方法:
第28种方法:
第29种方法:
0,04,1:
0,24,2:
0,13,2:
1,0
2,2:
1,12,1:
第30种方法:
第31种方法:
第32种方法:
第33种方法:
第34种方法:
1,