% function dog_chicken
%
clc;clear;close all;
s=[1,1,1,1]; % 初始状态
Ss=s; % 记录状态变化的数组
D=[1,0,0,0;1,1,0,0;1,0,1,0;1,0,0,1]; % 运载状态组成的矩阵
Ds=[]; % 记录运载状态变化的数组
v=[8,4,2,1]; % 二进制转化为十进制数的基
Vi=[3,6,7,8,9,12]; % 不允许状态向量对应的十进制数
k=1; % 标记往返的参数
while sum(s)>0.5;
if mod(k,2)==1; % 判断往返情况:1表示往,0表示返
x=find(s==0);% 找出在彼岸的物品
else
x=find(s==1);% 找出在此岸的物品
end
Dt=D;Dt(x,:)=[];% 计算出可能的状态矩阵
if ~isempty(Ds);
Dt=setdiff(Dt,Ds(end,:),'rows');% 删去上一步用过的运载状态向量,避免死循环
end
St=repmat(s,size(Dt,1),1);% 复制表示状态的向量使矩阵St和矩阵Dt的行数和列数相等
SD=mod(Dt+St,2); % 通过加法规则计算运载后的结果
Sv=sum(SD.*repmat(v,size(Dt,1),1),2); % 计算运载后状态向量对应的十进制数
V=setdiff(Sv,Vi','rows'); % 从运载后的状态中删去不允许的状态
x=find(Sv==min(V)); % 找出一个允许的运载状态
s=SD(x,:); % 得到运载后的状态向量
Ds=[Ds;Dt(x,:)]; % 把当前运载状态向量加入到矩阵Ds中
Ss=[Ss;s]; % 把当前状态向量加入到矩阵Ss中
k=k+1;% 更新标记往返的参数
end
Process=[Ss(1:7,:),Ds] % 输出状态向量及对应的运载状态向量,其中两部分合为一个矩阵Process显示
s % 输出最后结果
% S=[1,1,1,1];% 15
% S=[1,1,1,0];% 14
% S=[1,1,0,1];% 13
% S=[1,0,1,1];% 11
% S=[1,0,1,0];% 10
% S=[0,0,0,0];% 0
% S=[0,0,0,1];% 1
% S=[0,0,1,0];% 2
% S=[0,1,0,0];% 4
% S=[0,1,0,1];% 5
% v=[8,4,2,0]
% sum(S.*v)+S(4)
%
%
%
%