求解PFSP的关键路径
背景介绍
求解FJSP中的关键路径-附带Matlab源码
在之前的文章中写过,要想缩小完工时间,最关键的是要减少关键路径上工序的等待时间或者加工时间。
本文研究的是如何求解分布式异构置换流水车间中关键工厂的关键路径,分解到每个工厂中就是一个PFSP问题,即求解PFSP问题的关键路径。
置换流水车间调度问题-PFSP
相较于FJSP问题来说,更加简单。一共有N个工件,和M台机器,每个工件按顺序从1-M号机器上进行加工,在机器1上N个工序是什么顺序,在其他机器上就是什么顺序。即为流水线调度。
转换为析取图
一个PFSP的甘特图可以转换成为一个析取图,同工件工序之间连接弧为“连接弧”,同机器工序之间的连接弧为“析取弧”。那么在图中的关系就很明显,每个工序的下两个工序一定是,自己的同工件工序和同机器的工序。由于在不同机器上工序顺序是一样的,则图形成了向网格形式的连接状态。
如何求图中的关键路径
请参考这篇文章。简单来说就是从开始节点出发,先计算最早开始时间,所有入度为当前节点的上一个节点,用自身的最早开始时间加上自身的加工时间,从中选取最大的值为当前节点的最早开始时间。直到算到最后一个节点。
再计算最晚完成时间,从最后一个节点开始算,每个节点,找到所有自己出度的下一个节点,用所有下节点的最晚完成时间减去自己的加工时间,从中选最小的作为自己的值。直到算到开始节点。
用最晚完成时间减去最早开始时间,如果值为0或者在所有等待时间中是最小的,那么这些最小值组成的路径在图中是无法退后或者提前开始,那么就是关键节点即为关键工序,关键节点组成的路径为关键路径。
Matlab源码
如果对你有帮助,请引用我的相关论文谢谢个人主页
[1]R. Li, W. Gong*, L.Wang, C. Lu, Two-stage knowledge-driven evolutionary algorithm for distributed flexible job shop scheduling problem with type-2 fuzzy processing time, Swarm and Evolutionary Computation.
[2]R. Li, W. Gong*, L. Wang, C.Lu, A Learning-based Memetic Algorithm for Energy-Efficient Flexible Job Shop Sc heduling With Type-2 Fuzzy Processing Time, IEEE Transctions on Evolutionary Computation
[3]R. Li, W. Gong*, C. Lu, A reinforcement learning based RMOEA/D for bi-objective fuzzy flexible job shop scheduling, Expert System With Application. 2022, 203, 117380
[4]R. Li, W. Gong*, C. Lu, Self-adaptive multi-objective evolutionary algorithm for flexible job shop scheduling with fuzzy processing time, Computers & Industrial Enginering. 2022, 168, 108099
function [CriticalPath]=FindCriticalPathDPFSP(p_chrom,v_chrom,f_index)
%置换流水车间的关键路径非常好找,图的关系也非常的简单,图中每个节点的关系是固定的
%每个节点的直接下一个节点为自己的下个工序即,下台机器的工序,机器加工顺序是从1:TM固定
%每个节点的析取弧的下一个节点为自己的同台机器上的下个工件的当前工序,每台机器上工序顺序一致
%所以在计算析取图的时候,先计算第一个工件的第一台机器上的所有后续工件的最早开始时间和自己后续工序的最早开始时间
%再计算第二个工件第二台机器上从自身开始往后的析取工序和直接工序的最早开始时间。
%从(1,1)算到(1,TM)和(N,1)再从(2,2)算到(2,TM)和(N,2)以此类推,每次算(i,i)的时间
%同理计算最晚开始时间。倒序即可
global H time TM;
N=length(p_chrom);
% JOBN=length(FJ);
% SH=length(p_chrom)*TM;
% drawFJSP(p_chrom,m_chrom,FJ);
%计算最早开始时间
VLTime=zeros(N,TM);
i=1;k=1;
while i<=N && k<=TM
for j=i:N
job=p_chrom(j);
if j==1&&k==1
VLTime(j,k)=0;
elseif k==1&&j~=1
lastjob=p_chrom(j-1);
t1=VLTime(j-1,k)+time{
f_index,lastjob,k}/v_chrom(1,lastjob,k);
t2=0;
VLTime(j,k)=max(t1,t2);
else
lastjob1=p_chrom(j-1);
t1=VLTime(j-1,k)+time{
f_index,lastjob1,k}/v_chrom(1,lastjob1,k);
t2=VLTime(j,k-1)+time{
f_index,job,k-1}/v_chrom(1,job,k-1);
VLTime(j,k)=max(t1,t2);
end
end
for h=k:TM
job=p_chrom(i);
if h==i
continue;
elseif h~=1&&i==1
t1=0;
t2=VLTime(i,h-1)+time{
f_index,job,h-1}/v_chrom(1,job,h-1);
VLTime(i,h)=max(t1,t2);
else
lastjob1=p_chrom(i-1);
t1=VLTime(i-1,h)+time{
f_index,lastjob1,h}/v_chrom(1,lastjob1,h);
t2=VLTime(i,h-1)+time{
f_index,job,h-1}/v_chrom(1,job,h-1);
VLTime(i,h)=max(t1,t2);
end
end
i=i+1;k=i;
end
% if i==N &&k==TM
% job=p_chrom(i);
% lastjob1=p_chrom(i-1);
% t1=VLTime(i-1,k)+time{
f_index,lastjob1,k}/v_chrom(1,lastjob1,k);
% t2=VLTime(i,k-1)+time{
f_index,job,k-1}/v_chrom(1,job,k-1);
% VLTime(i,k)=max(t1,t2);
% end
job=p_chrom(N);
LastNode=VLTime(N,TM)+time{
f_index,job,TM}/v_chrom(1,job,TM);
%计算最晚结束时间
VETime=zeros(N,TM);
i=N;k=TM;
while i>=1 && k>=1
for j=i:-1:1
job=p_chrom(j);
if j==N&&k==TM
VETime(j,k)=LastNode-time{
f_index,job,TM}/v_chrom(1,job,TM);
elseif k==TM&&j<N
VETime(j,k)=VETime(j+1,k)-time{
f_index,job,k}/v_chrom(1,job,k);
else
pt=time{
f_index,job,k}/v_chrom(1,job,k);
t1=VETime(j+1,k)-pt;
t2=VETime(j,k+1)-pt;
VETime(j,k)=min(t1,t2);
end
end
for h=k:-1:1
job=p_chrom(i);
if h==i
continue;
elseif h==TM &&i==N
VETime(i,h)=LastNode-time{
f_index,job,h}/v_chrom(1,job,h);
elseif h<TM&&i==N
VETime(i,h)=VETime(i,h+1)-time{
f_index,job,h}/v_chrom(1,job,h);
else
pt=time{
f_index,job,h}/v_chrom(1,job,h);
t1=VETime(i+1,h)-pt;
t2=VETime(i,h+1)-pt;
VETime(i,h)=min(t1,t2);
end
end
i=i-1;k=k-1;
end
% if i==1 &&k==1
% job=p_chrom(i);
% pt=time{
f_index,job,k}/v_chrom(1,job,k);
% t1=VLTime(i+1,k)-pt;
% t2=VLTime(i,k+1)-pt;
% VETime(i,k)=min(t1,t2);
% end
Idletime=ones(N,TM);
for i=1:N
for k=1:TM
Idletime(i,k)=VETime(i,k)-VLTime(i,k);
if Idletime(i,k)<1e-5
Idletime(i,k)=0;
end
end
end
MinIdleT=Idletime(1,1);
value=zeros(1,2);
CriticalPath=[];
for i=1:N
for k=1:TM
if Idletime(i,k)==MinIdleT
value(1,1)=p_chrom(i);value(1,2)=k;
CriticalPath=[CriticalPath;value];
end
end
end
end