商人过河问题程序.docx

上传人:b****6 文档编号:7582667 上传时间:2023-01-25 格式:DOCX 页数:17 大小:20.43KB
下载 相关 举报
商人过河问题程序.docx_第1页
第1页 / 共17页
商人过河问题程序.docx_第2页
第2页 / 共17页
商人过河问题程序.docx_第3页
第3页 / 共17页
商人过河问题程序.docx_第4页
第4页 / 共17页
商人过河问题程序.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

商人过河问题程序.docx

《商人过河问题程序.docx》由会员分享,可在线阅读,更多相关《商人过河问题程序.docx(17页珍藏版)》请在冰豆网上搜索。

商人过河问题程序.docx

商人过河问题程序

3人的可以过河,4人的没有办法。

用递归的源程序如下:

运行结果是没有解,超过3人的没有解。

开始时商人,强盗所在的河的这边设为0状态,另一边设为1状态(也就是船开始时的一边设为0,当船驶到对岸是设为1状态,在这两个状态时,都必须符合条件)

#include

structnode/*建立一个类似栈的数据结构并且可以浏览每一个数据点*/

{

intx;

inty;

intstate;

structnode*next;

};

typedefstructnodestate;

typedefstate*link;

linkPPointer1=NULL;

linkPPointer2=NULL;

inta1,b1;

inta2,b2;

/*栈中每个数据都分为0,1状态*/

voidPush(inta,intb,intn)

{

linknewnode;

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;

}

}

voidPop()/*弹栈*/

{

linkpointer;

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;

}

inthistory(inta,intb,intn)/*比较输入的数据和栈中是否有重复的*/

{

linkpointer;

if(PPointer1==NULL)

return1;

else

{

pointer=PPointer1;

while(pointer!

=NULL)

{

if(pointer->x==a&&pointer->y==b&&pointer->state==n)

return0;

pointer=pointer->next;

}

return1;

}

}

intjudge(inta,intb,intc,intd,intn)/*判断这个状态是否可行,其中使用了history函数*/

{

if(history(a,b,n)==0)return0;

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)

{

case1:

{

if(a==3)

{

Push(a,b,n);

return1;

}

elseif(a==0)

{

Push(a,b,n);

return1;

}

elseif(a==b)

{

Push(a,b,n);

return1;

}

elsereturn0;

}

case0:

{

if(a==3)

{

Push(a,b,n);

return1;

}

elseif(a==0)

{

Push(a,b,n);

return1;

}

elseif(a>=b)

{

Push(a,b,n);

return1;

}

elsereturn0;

}

}

}

elsereturn0;

}

intDuhe(inta,intb,intn)/*递归法解决商人渡河问题,如果这一个状态符合*/

{/*则判断下一个状态,直至问题解决*/

if(a==0&&b==0)return1;

if(n==0)/*判断0状态时,商匪状态是否符合要求*/

{

if(judge(a-1,b-1,4-a,4-b,1))

{

if(Duhe(a-1,b-1,1)==1)

return1;

}

if(judge(a,b-2,3-a,5-b,1))

{

if(Duhe(a,b-2,1)==1)

return1;

}

if(judge(a-2,b,5-a,3-b,1))

{

if(Duhe(a-2,b,1)==1)

return1;

}

if(judge(a-1,b,4-a,3-b,1))

{

if(Duhe(a-1,b,1)==1)

return1;

}

if(judge(a,b-1,3-a,4-b,1))

{

if(Duhe(a,b-1,1)==1)

return1;

}

else

{

Pop(0);

return0;

}

}

if(n==1)/*判断0状态时,商匪状态是否符合要求*/

{

if(judge(a+1,b+1,2-a,2-b,0))

{

if(Duhe(a+1,b+1,0)==1)

return1;

}

if(judge(a,b+2,3-a,1-b,0))

{

if(Duhe(a,b+2,0)==1)

return1;

}

if(judge(a+2,b,1-a,3-b,0))

{

if(Duhe(a+2,b,0)==1)

return1;

}

if(judge(a+1,b,2-a,3-b,0))

{

if(Duhe(a+1,b,0)==1)

return1;

}

if(judge(a,b+1,3-a,2-b,0))

{

if(Duhe(a,b+1,0)==1)

return1;

}

else

{

Pop

(1);

return0;

}

}

return0;

}

main()

{

linkpointer;

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();

}

a=[

0,0;

0,1;

0,2;

0,3;

3,0;

3,1;

3,2;

3,3;

1,1;

2,2;

];%10enabledstates

s=[0,0;

0,1;

0,2;

0,3;

1,0;

1,1;

1,2;

1,3;

2,0;

2,1;

2,2;

2,3;

3,0;

3,1;

3,2;

3,3;

];

d=[

0,2;

2,0;

1,1;

0,1;

1,0;

];%5enableddecisions

i=1;

j=1;

k=1;

s(1,

=[3,3];

disp('Thisshore-OnBoat-Thatshore')

fori=1:

12

*R5P0S8N$a'E-O

&B4i4Z#s#zD7O7j;f

forj=1:

5

t=0;

r=mod(i,2);

m=r;

u=0;

fork=1:

10

ifs(i,

+(-1)^i*d(j,

==a(k,

t=1;

end

end

end

ift==1

ifu==0

s(i+1,

=s(i,

+(-1)^i*d(j,

;

c(i+1,

=d(j,

;

return;

elseifu==1

continue;

end

elsecontinue;

end

end;

ift==0

disp('NoResult');

return;

end;

b(i+1,

=[3,3]-s(i+1,

;

play=sprintf('{%d,%d}-{%d,%d}-{%d,%d}',s(i,1),s(i,2),c(i+1,1),c(i+1,2),b(i+1,1),b(i+1,2));

disp(play)

ifs(i+1,

==[0,0]

return;

end;

functionjueche=guohe

%%%%%%%%%%%%%%%%%%%%%%

程序开始需要知道商人和仆人数;

n=input(‘输入商人数目:

’,’12’);

nn=input(‘输入仆人数目:

’,’12’);

nnn=input(‘输入船的最大容量:

’,’20’);

ifnn>n

n=input(‘输入商人数目:

’,’23’);

nn=input(‘输入仆人数目:

’,’23’);

nnn=input(‘输入船的最大容量:

’,’34’);

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%决策生成

jc=1;%决策向量放在矩阵d中,jc为插入新元素的行标初始为1;

fori=0:

nnn

forj=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];%生成一个决策向量立刻扩充为三维;

d(jc+1,1:

3)=[-i,-j,-1];%同时生成他的负向量;

jc=jc+2;%由于生成两个决策向量,则jc要向下移动两个;end

end

j=0;

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%状态数组生成

kx=1;%状态向量放在A矩阵中,生成方法同矩阵生成;

fori=n:

-1:

0

forj=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);

fori=1:

2*k

forj=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);

ifsize(aa,1)==m

break;

end

forj=1:

size(a,1)

pp=a(j,1);

ifv(k,pp)~=0

ifT(pp)>(P(k)+v(k,pp))

T(pp)=(P(k)+v(k,pp));

lmd(pp)=k;

end

end

end

mi=min(T(a));

ifmi==inf

break;

else

d=find(T==mi);

d=d

(1);

P(d)=mi;

T(d)=inf;

k=d;

S(d)=1;

end

end

iflmd(y)==inf

jueche='cannotreach';

return;

end

jueche

(1)=y;

g=2;h=y;

while

(1)

ifh==x

break;

end

jueche(g)=lmd(h);

g=g+1;

h=lmd(h);

end

jueche=A(jueche,:

);

jueche(:

3)=[];

 

clearall%080817

clc        %n为商人数,m为仆人数,h为每次过河的最多人数

n=3;m=3;h=2;%初始状态及数据

m0=0;n0=0;

tic

LS=0;  %允许的状态集合S与个数LS

LD=0;  %允许的决策集合D与个数LD

fori=0:

n

   forj=0:

m

       ifi>=j&n-i>=m-j|i==n|i==0

           LS=LS+1;S(LS,:

)=[ij];

       end

       ifi+j>0&i+j<=h&(i>=j|i==0)

           LD=LD+1;D(LD,:

)=[ij];

       end

   end

end

%用搜寻法找出符合条件的渡河方案

%……………………………………………………………………………………………$$

N=15;

Q1=inf*ones(2*N,2*N);

Q2=inf*ones(2*N,2*N);

t=1;

le=1;

q=[mn];

f0=0;%判断循环终止标记

whilef0~=1&t

    k=1;

    sa=[];

    sb=[];

    fori0=1:

le           %第n次允许的策略集逐次搜索

        s0=q(i0,:

);

        iff0==1

           break

        end

        fori=1:

LD        %由s0搜索D后得到允许的状态

            s1=s0+(-1)^t*D(i,:

);

            ifs1==[m0,n0]

               sa=[m0,n0];

               sb=D(i,:

);

               f0=1;

               break

            end

            forj=2:

LS-1  %搜索对比S后允许状态

                ifs1==S(j,:

                   ifk==1

                      sa(k,:

)=s1;

                      sb(k,:

)=D(i,:

);

                      k=k+1;

                      break       

                   end

                   ifk>1         %对重复状态删除处理

                      f1=0;

                      forii=1:

k-1

                          ifs1==sa(ii,:

                             f1=1;

                             break                      

                          end

                      end

                   end            %……

                   iff1==0

                      sa(k,:

)=s1;

                      sb(k,:

)=D(i,:

);

                      k=k+1;

                      break

                   end   

                end       

            end          %…………………

        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;

end                       %………………………………………………………$$

%在可行方案集合中逆向搜寻唯一方案

%……………………………………………………………………………………………¥¥

tr=t-1;saa1=sa;

SA=zeros(tr,2);SB=zeros(tr,2);

fork=tr:

-1:

2

   k1=k-1;f0=0;

   sbb=Q2(:

k*2-1:

k*2);

   saa=Q1(:

k1*2-1:

k1*2);

   fori=1:

2*N

       saa2=saa1-(-1)^k*sbb(i,:

);

       forj=1:

2*N

           ifsaa2==saa(j,:

               saa1=saa2;

               sbb1=sbb(i,:

);

               f0=1;

               break

           end

       end

       iff0==1

           break

       end

   end

   SA(k1,:

)=saa1;

   SB(k,:

)=sbb1;

end

SA(tr,:

)=[m0n0];

SB(1,:

)=[m,n]-SA(1,:

);

%………………………………………………………………………………………………¥¥

disp'初始状态:

'

X0=[m,n]

disp'状态为:

'

SA

disp'决策为:

'

SB

toc

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 数学

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

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