2019-mathorcupB题-环形穿梭机调度模型(代码篇)

全程代码用matlab实现,用最近原则算法求解第一问的主函数代码如下。在(思路篇)中已经提到过,若考虑车子本身长度,则只需要修改回溯函数即可。

clc;clear;
%求最短距离
S=[0	23.5	0	0	0	0	0	0	0	0	0	0	0
0	0	23.5	0	0	0	0	0	0	0	0	0	0
0	0	0	23.5	0	0	0	0	0	0	0	0	0
0	0	0	0	23.5	0	0	0	0	0	0	0	0
0	0	0	0	0	6	0	0	0	0	0	0	0
0	0	0	0	0	0	13.4285714	0	0	0	0	0	0
0	0	0	0	0	0	0	13.4285714	0	0	0	0	0
0	0	0	0	0	0	0	0	13.4285714	0	0	0	0
0	0	0	0	0	0	0	0	0	13.4285714	0	0	0
0	0	0	0	0	0	0	0	0	0	13.4285714	0	0
0	0	0	0	0	0	0	0	0	0	0	13.4285714	0
0	0	0	0	0	0	0	0	0	0	0	0	13.4285714
0	0	0	0	0	0	0	0	0	0	0	0	0
];
Dajk=[2	4
1	4
4	2
3	1
1	3
4	2
3	1
3	2
1	3
4	2
3	4
2	1
2	3
2	1
1	4
3	4
4	1
1	3
3	3
4	3
2	3
3	2
2	3
4	3
2	3
1	2
3	4
3	1
3	2
1	4
1	4
1	3
1	3
3	4
4	3
4	3
1	3
1	3
3	2
3	1
3	3
3	1
3	1
2	3
3	4
1	3
2	3
1	4
3	3
3	3
3	1
3	2
2	3
3	2
4	1
3	3
3	4
3	1
1	2
3	4
3	1
1	4
4	3
2	3
2	1
4	3
4	1
2	3
3	4
2	1
1	2
3	1
3	3
4	3
1	3
2	4
3	4
2	4
1	4
3	4
3	1
3	4
2	1
2	3
3	3
1	2
1	3
3	3
2	3
2	3
3	1
3	1
3	4
3	2
3	3
4	1
1	4
4	3
3	4
1	3
];
wzqlovecr=[1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	1	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	1	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
1	0	0	1
];
msum=sum(wzqlovecr);
m=[1,1,1,1];
for i=1:100
    for j=1:2
        if Dajk(i,j)==1
            Dajk(i,j)=6;
        end
        if Dajk(i,j)==2
            Dajk(i,j)=8;
        end
        if Dajk(i,j)==3
            Dajk(i,j)=10;
        end
        if Dajk(i,j)==4
            Dajk(i,j)=12;
        end
    end
end
k1=1;
k2=1;
i=1;
j=3;
while j-i<13
    S(i,j)=S(i,j-1)+S(j-1,j);
    if j<13
        j=j+1;
        i=i+1;
    else
        j=j-i+2;
        i=1;
    end
end
for i=1:13
    for j=1:13
        if S(i,j)==0&&i~=j
            S(i,j)=94*2+6*2-S(j,i);
        end
    end
end
%init
v=1.5;
UPA=[4,5];
UPB=[7,9,11,13];
DOWNA=[1,2,3];
DOWNB=[6,8,10,12];
status=[4,11.75,4;4,11.74,4;4,11.73,4];
status=[status;status;status];
N=9;
next=ones(1,N)*4;
TSUM=0;
wzqcr=0;
while 1
    wzqcr=wzqcr+1;
[status2,T] = FF(status,next,S,v );%状态转移
status = FF2(status,status2,S,v);
[next,k1,k2,m] = updata(next,status, k1,k2,Dajk,UPA,UPB,S,m,DOWNA);%对下一个停靠窗口进行确定
if k1>=100
     S(:,4)=1000000;
end
if k2>=100
     S(:,5)=1000000; 
end
if(m(1)>=msum(1))
    S(:,7)=10000000;
end
if(m(2)>=msum(2))
    S(:,9)=10000000;
end
if(m(3)>=msum(3))
    S(:,11)=10000000;
end
if(m(4)>=msum(4))
    S(:,13)=10000000;
end
 status = jc( status,k1,k2,m,msum,UPA,UPB,S,v );
status
TSUM=TSUM+T;

if (k1>=100)&&(k2>=100)&&(m(1)>=msum(1))&&(m(2)>=msum(2))&&(m(3)>=msum(3))&&(m(4)>=msum(4))
    break
end
end
disp('总共用时间:')
TSUM
disp('总共循环次数:')
wzqcr

单个穿梭车状态转移函数定义如下

function statusout = f( statusin,i,next,S,v)
%对每一个i的status考虑next是整个的
a=statusin(1);
b=statusin(2);
c=statusin(3);
if a==1
    statusout(1)=3;
    statusout(2)=S(c,next(i))/v;
    statusout(3)=next(i);
end
if a==2
    statusout(1)=4;
    statusout(2)=S(c,next(i))/v;
    statusout(3)=next(i);
end
if a==3
    statusout(1)=2;
    statusout(2)=10;%上下料时间
    statusout(3)=statusin(3);
end
if a==4
    statusout(1)=1;
    statusout(2)=10;%上下料时间
    statusout(3)=statusin(3);
end
end


回溯函数如下:

function [next,k1out,k2out,mout] = updata(nextin,status,k1in,k2in,Dajk,UPA,UPB,S,minn,DOWNA)
%Dajk,k1,k2
%最近原则决策算法
N=length(nextin);
k1out=k1in;
k2out=k2in;
mout=minn;
next=nextin;
for i=1:N
    if status(i,1)==1&&status(i,3)==UPA(1)&&status(i,2)==10
        next(i)=Dajk(k1in,1);
        k2out=k2in;
        k1out=k1in+1;
    end
    if status(i,1)==1&&status(i,3)==UPA(2)&&status(i,2)==10
        next(i)=Dajk(k2in,2);
        k1out=k1in;
        k2out=k2in+1;
    end
    if status(i,1)==1&&ismember(status(i,3),UPB)
        smin=199999;
        xmin=1;
        for x=1:length(DOWNA)
            if S(status(i,3),DOWNA(x))<smin
                smin=S(status(i,3),DOWNA(x));
                xmin=DOWNA(x);
            end
        end
        next(i)=xmin;
        k1out=k1in;
        k2out=k2in;
        mout(find(UPB==status(i,3)))= mout(find(UPB==status(i,3)))+1;
    end
    if status(i,1)==2
        smin=199999;
        UPAUPB=[UPA,UPB];
        xmin=1;
        for x=1:length(UPAUPB)
            if S(status(i,3),UPAUPB(x))<smin
                smin=S(status(i,3),UPAUPB(x));
                xmin=UPAUPB(x);
            end
        end
        next(i)=xmin;
        k1out=k1in;
        k2out=k2in;
    end
    
        
end

end


整体状态转移函数如下:

function [statusout,T] = FF(  statusin,next,S,v )
%整个status(N*3)
[N,three]=size(statusin);
cr=statusin(:,2);
cr=cr(end:-1:1);
[T,mini]=min(cr);
mini=N-mini+1;
for i=1:N
    if i~=mini
        statusout(i,:)=[statusin(i,1),statusin(i,2)-T,statusin(i,3)];
    else
          statusout(i,:)=f(  statusin(i,:),i,next,S,v);
    end
end

end

猜你喜欢

转载自blog.csdn.net/weixin_39529891/article/details/89418976