单机job-shop生产调度问题的遗传算法(Matlab)

本篇遗传算法根据下述文章进行编写,框架一致
https://blog.csdn.net/qq_38757869/article/details/107598731

1 导入调度数据集

数据集需要符合下述格式(数据集描述见代码所述),否则需要自己修改代码。
在这里插入图片描述

2 主程序

%%%%%%%%%%%%遗传算法解决single-machine job-shop问题%%%%%%%%%%%%%%%%%%%%
clear all;                      %清除所有变量
close all;                      %清图
clc;       %清屏

maxrun=10;  %最大运行次数
maxgen=10;  %最大迭代次数
NP=200;                          %种群规模
OW=0.5;                          %目标1权重

T=importdata('task.txt');    %导入任务数据
%%%%%%%%%%%task.txt数据格式%%%%%%%%%%%%
%工件    ……………………
%加工时间……………………
%到达时间……………………
%交货期  ……………………
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N=size(T,2);                     %染色体长度
NJ=N;                            %工件数量
mbest=zeros(maxrun,N+3);  %每次运行的最佳个体,及其三个目标值

CL=zeros(1,NJ);    

for li=1:NJ                    %工件工序数,为1
      CL(1,li)= 1;
end

for run=1:maxrun                                        %运行maxrun次
     Bestg=zeros(1,maxgen);
     [f1]=initial(T,NP,NJ);                         %种群初始化
     OP=0;
     [fitness]=fit(f1,NP,N,T,NJ,OP,OW);        %适应度计算
     OP=min(fitness(:,1))/min(fitness(:,2));           %双目标折衷值
     fitness(:,3)=OW*fitness(:,1)+OP*(1-OW)*fitness(:,2);
     [f1,f2]=select(f1,fitness,N);                %选择
     Bestgen=f2;
    for gen=1:maxgen                                    %迭代maxgen代
         
          [f1]=cross(f1,T,N,NP,NJ,CL);   %交叉(里面有变异)
          [fitness]=fit(f1,NP,N,T,NJ,OP,OW);    %适应度计算
          [f1,f2]=select(f1,fitness,N);           %选择
          if(f2(1,N+3)<Bestgen(1,N+3))
             Bestgen=f2; 
          end
          Bestg(1,gen)=min(Bestgen(1,N+3),f2(1,N+3));        
    end
    figure(run);
    plot(Bestg);
    mbest(run,:)=Bestgen;
end
dlmwrite('best_result.txt',mbest);  %将最优结果存入文件

3 初始化函数

function [fi1] = initial(T,NP,NJ)
    %随机初始化任务调度和AGV分配种群%
    fi1=zeros(NP,NJ);                   %用于存储任务调度种群
    for ii=1:NP    %种群初始化
        fi1(ii,:)=T(1,randperm(NJ));          %随机生成初始种群
    end
end

4 适应度计算函数

function [fitf] = fit(f1,NP,N,T,NJ,OP,OW)
%目标1:最大完工时间;
%目标2:总延迟;
fitf=zeros(NP,3);   %个体适应值:最大完工时间;最大功耗;双目标
for i1=1:NP
Mi=0;   % 存储机器最早开始时间
Ci=zeros(1,NJ);   % 存储工件完工时刻
Et=T(3,:);   % 工件最早开始时间

 for i2=1:N
    Ci(1,f1(i1,i2))=max(Mi,Et(1,f1(i1,i2)))+T(2,f1(i1,i2));  %机器和工件的最迟开始时间+加工时间
    Mi=Ci(1,f1(i1,i2));
 end
 Dt=max(0,Ci-T(4,:));   
 fitf(i1,1)=Mi;     %完工时间
 fitf(i1,2)=sum(Dt);  %总延迟
 fitf(i1,3)=OW*fitf(i1,1)+OP*(1-OW)*fitf(i1,2);
end
end

5 选择函数

function [fs1,fs2] = select(f1,fitness,N)
%   优先权选择:选择最优个体,适应度1:20;适应度2:20;适应度3:60;
    Ns1=20;
    Ns2=20;
    Ns3=60;
    CH=[f1,fitness];   
    CHa=sortrows(CH,N+3);
    Best=CHa(1:Ns3,:);
    CHa=sortrows(CH,N+2);
    Best=[Best;CHa(1:Ns2,:)];
    CHa=sortrows(CH,N+1);
    Best=[Best;CHa(1:Ns1,:)];
    fs1=Best(:,1:N);
    fs2=Best(1,:);
end

6 子代生成函数

function [fc1] = cross(f1,T,N,NP,NJ,CL)
%从最优的100个体生成100个后代
%随机生成100个后代
%概率交叉完成后概率变异 
   Pc=0.8;  %交叉概率
   Pm=0.2;  %变异概率
   Nr=NP/2;  %随机子代数量
   Rc=NP/4;   %交叉数范围
   fc1=[];
   
    for ic=1:Rc  % 产生NP/2个后代
       pcp=unidrnd(Rc);  %选择交叉父代
       p1f1=f1(pcp,:);
       p2f1=f1(pcp+Rc,:);
      if(rand()<Pc)         
       
       cr=unidrnd(N-2)+1;  %产生交叉点
       temp1=p1f1(1,cr:N);       %父代染色体互换
       p1f1=p1f1(1,1:cr-1);
       temp2=p2f1(1,cr:N);
       p2f1=p2f1(1,1:cr-1);
       p1f1=[p1f1,temp2];
       p2f1=[p2f1,temp1];
       
       CLt=CL;
       for le=1:N             %父代1染色体合法化
           for lei=1:NJ
               if(p1f1(1,le)==lei)
                  if(CLt(1,lei)>0)
                      CLt(1,lei)= CLt(1,lei)-1;
                      break;
                  else
                      p1f1(1,le)=0;
                      break;
                  end
               end
           end
       end
       for le=1:N
          if(p1f1(1,le)==0)
              for lei=1:NJ
                  if(CLt(1,lei)>0)
                      p1f1(1,le)=lei;
                      CLt(1,lei)= CLt(1,lei)-1;
                      break;
                  end
              end
          end                
       end
       CLt=CL;
       for le=1:N                %父代2染色体合法化
           for lei=1:NJ
               if(p2f1(1,le)==lei)
                  if(CLt(1,lei)>0)
                      CLt(1,lei)= CLt(1,lei)-1;
                      break;
                  else
                      p2f1(1,le)=0;
                      break;
                  end
               end
           end
       end
       for le=1:N
          if(p2f1(1,le)==0)
              for lei=1:NJ
                  if(CLt(1,lei)>0)
                      p2f1(1,le)=lei;
                      CLt(1,lei)= CLt(1,lei)-1;
                      break;
                  end
              end
          end                
       end
        
       if(rand()<Pm)          %概率变异
           cm=unidrnd(N-2)+1;  %产生变异点
           jm=unidrnd(NJ);  %产生变异 工件
           mg=p1f1(1,cm);
           p1f1(1,cm)=jm;
           for mi=1:N                %p1f1合法化
              if(p1f1(1,mi)==jm)
                  p1f1(1,mi)=mg;
                  break;
              end
           end
             
           cm=unidrnd(N-2)+1;  %产生变异点
           jm=unidrnd(NJ);  %产生变异 工件
           mg=p2f1(1,cm);
           p2f1(1,cm)=jm;
           for mi=1:N                %p2f1合法化
              if(p2f1(1,mi)==jm)
                  p2f1(1,mi)=mg;
                  break;
              end
           end                   
       end
      end
      fc1=[fc1;p1f1;p2f1];
    end
   for ri=1:Nr    %生成随机个体
         fr1(ri,:)=T(1,randperm(NJ));          %随机生成初始种群
   end   
   fc1=[fc1;fr1];
end

备注:此算法仅为最基本的遗传算法对单机调度问题的多目标求解应用,仅供初学者参考,用于对遗传算法和单机调度问题的了解,算法的性能不能保证最好。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值