编程渡河问题
❶ 编程问题:渡河问题。一个农夫带着一条狼、一只山羊和一篮蔬菜过河,
首先把羊运到对岸(因为狼不吃菜),再把狼运到对岸同时把羊带回来放到岸这边(有农夫在羊不会吃菜),这一次把菜运到对岸空着回来(理由仍然是狼不吃菜),最后再次把羊运到对岸完成渡河。
❷ 利用MATLAB编程实现:三名商人
像商人过河这么复杂的问题,要不是刚好之前回答过,手上有这程序,恐怕没有人会帮你编的。
具体代码我不贴了,见参考资料的链接。
程序运行的结果如下:
第1步:0商2仆过河,0商1仆返回
第2步:0商2仆过河,0商1仆返回
第3步:2商0仆过河,1商1仆返回
第4步:2商0仆过河,0商1仆返回
第5步:0商2仆过河,0商1仆返回
第6步:0商2仆过河,完成
❸ 利用MATLAB编程实现:三名商人(求程序)
% n为商人数,m为仆人数,h为每次过河的最多人数
clear
n=3;m=3;h=2;
m0=0;n0=0;
LS=0; % 允许的状态集合S与个数LS
LD=0; % 允许的决策集合D与个数LD
for i=0:n
for j=0:m
if i>=j&n-i>=m-j|i==n|i==0
LS=LS+1;S(LS,:)=[i j];
end
if i+j>0&i+j<=h&(i>=j|i==0)
LD=LD+1;D(LD,:)=[i j];
end
end
end
% 用搜寻法找出符合条件的渡河方案
N=15;
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<N %搜索可行的策略
k=1;
sa=[];
sb=[];
for i0=1:le % 第n次允许的策略集逐次搜索
s0=q(i0,:);
if f0==1
break
end
for i=1:LD % 由s0搜索D后得到允许的状态
s1=s0+(-1)^t*D(i,:);
if s1==[m0,n0]
sa=[m0,n0];
sb=D(i,:);
f0=1;
break
end
for j=2:LS-1 % 搜索对比S后允许状态
if s1==S(j,:)
if k==1
sa(k,:)=s1;
sb(k,:)=D(i,:);
k=k+1;
break
end
if k>1 % 对重复状态删除处理
f1=0;
for ii=1:k-1
if s1==sa(ii,:)
f1=1;
break
end
end
end
if f1==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);
for k=tr:-1:2
k1=k-1;f0=0;
sbb=Q2(:,k*2-1:k*2);
saa=Q1(:,k1*2-1:k1*2);
for i=1:2*N
saa2=saa1-(-1)^k*sbb(i,:);
for j=1:2*N
if saa2==saa(j,:)
saa1=saa2;
sbb1=sbb(i,:);
f0=1;
break
end
end
if f0==1
break
end
end
SA(k1,:)=saa1;
SB(k,:)=sbb1;
end
SA(tr,:)=[m0 n0];
SB(1,:)=[m,n]-SA(1,:);
% 输出
SC = ones(size(SA))*3 - SA;
nStep = ceil( size(SB,1) / 2 );
fprintf('\n过河步骤:\n');
for i = 1 : nStep
fprintf('第%i步:%i商%i仆过河', i, SB(2*i-1,:));
if i < nStep
fprintf(',%i商%i仆返回\n', SB(2*i,:));
else
fprintf(',完成\n\n');
end
end
fprintf('过河过程中状态变化:\n步骤 此岸商 此岸仆 方向 彼岸商 彼岸仆\n');
for i = 1 : nStep
fprintf('%3i %4i%8i ==> %4i%8i\n', i, SA(2*i-1, :), SC(2*i-1, :));
if i < nStep
fprintf(' %4i%8i <== %4i%8i\n', SA(2*i, :), SC(2*i, :));
end
end