商人過河 Matlab程序實現



這是我在本科的時候,即08年8月數學建模競賽前 編寫並優化後的 “商人過河” 程序,實用性不大,但對於建模思想的培養還是挺重要的,已有多個轉帖,但在最近無意間發現一篇一模一樣的版本, 卻沒有標明出處,我表示很無語!

其實,作爲一個開源社區的堅定支持者,尊重別人的勞動成果是最最基本的原則,這裏我重新編輯併發這個程序 就是想說明:開源因相互尊重而越加精彩!

原文發表地址:http://hi.baidu.com/gujinjin2008/item/63f05d8775199eddd0f8cd35

後來改進的通用搜索程序:http://hi.baidu.com/gujinjin2008/item/6cb5e4d92a44e03d49e1dd31


clear all % 080817
clc         % n爲商人數,m爲僕人數,h爲每次過河的最多人數 
n=3;m=3;h=2; %初始狀態及數據
m0=0;n0=0;
tic
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,:);
%------------------------------------------------------
disp '初始狀態:'
X0=[m,n]
disp '狀態爲:'
SA
disp '決策爲:'
SB


toc


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章