首页 > 编程语言 >2024 年“泰迪杯”A 题:生产线的故障自动识别与人员配置--第四题(用遗传算法解决生产线排班问题--matlab代码)

2024 年“泰迪杯”A 题:生产线的故障自动识别与人员配置--第四题(用遗传算法解决生产线排班问题--matlab代码)

时间:2024-05-25 20:32:18浏览次数:12  
标签:index 泰迪杯 end -- de 50 ran 生产线 geshu

问题背景:

        问题四:根据实际情况,现需要扩大生产规模,将生产线每天的运行时间从 8 小时增加 到 24 小时不间断生产,考虑生产线与操作人员的搭配,制定最佳的操作人员排班方案,要求满足以下条件:(1) 各操作人员做五休二,尽量连休 2 天; (2) 各操作人员每班连续工作 8 小时; (3) 班次时间:早班(8:00-16:00)、中班(16:00-24:00)、晚班(0:00-8:00); (4) 各工龄操作人员的人数比例与问题 3 中的比例相同; (5) 各操作人员的班次安排尽量均衡。

        已知问题三中原本每条生产线与相应操作人员对应如下:

1d2de51f364848f0a14ab40fd8795b69.png

问题分析:

        问题四为优化问题,考虑使用遗传算法,根据附件三给出的生产线与操作人员信息,无法将生产线与操作人员剥离开而单独讨论某条生产线或者某位操作人员的工作能力指标。因此,在本题中,固定生产线与相应工龄操作人员的搭配,即从理论上固定生产效率。那么,本题仅为优化问题中的排班问题,考虑如下约束条件:

1.每天10条线24小时工作;

2.一位操作人员每天工作8小时;

3.夜班之后必须至少休一天(考虑现实情况添加);

4.各操作人员上五休二,尽量连休;

5.各操作人员班次尽量均匀。

        其中,为了生产线的正常运行与操作人员身体健康,1-3为硬性约束,4-5为软约束,以此建立遗传算法优化模型,希望得到合理的排班表。考虑到24小时生产线不间断运营,并且要保证操作人员工龄比例与附件三相同,至少需要5组生产线操作人员,即50人,约定员工与产线有如下对应关系:

ff12e2b56570454893d849bb71cb0787.png

遗传算法排班:

        使用遗传算法进行排班,首先,需要确定染色体的编码,这里,每条染色体代表一个排班表,染色体中每两位二进制编码表示一种班型,对于一周7天,每天有操作人员50人,一条染色体由7×50条操作人员基因组成,每一个操作人员基因又由2位的班型基因(二进制编码)构成,因此,一条染色体由7×50×2位编码的基因组成。

pop = 50; %设定初始种群数量
length = 700; %种群基因编码长度,一周七天,每天50个排班人员,总共3种班型(用2位二进制编码表示)
gen = 500; %迭代次数
crossover_probablity = 0.9; %交叉概率     %交叉概率一般在0.6~0.9之间
variation_probablity = 0.1; %变异概率     %
initial_pop = round(rand(pop,length)); %生成初始种群

%算法迭代m次
for m=1:gen
    
    %将每一代 染色体长度为700位的二进制种群 转化为50*7的矩阵(50人,一周7天)
    x = zeros(50,7,pop);
    for i = 1:size(initial_pop,1) %分别遍历排班表
        for j = 1:7  %遍历一周七天
            for k = 1:50 %遍历50个排班人员
                for l = 1:2 %二进制班型转换为十进制
                    x(k,j,i) = initial_pop ( i,100*(j-1)+2*(k-1)+l ) * 2^(2-l) + x(k,j,i);   % 100是人数50×排班编码数2
                end
            end      
        end
        
        %%%%%确定每天每个班次不超过十人上班,若超过10人,按工龄比例随机保留10名员
        %%%%%工上班,其他人放假,且各工龄比例如题三
        for j=1:7
            for f = 0:2
                if sum(x(1:10,j,i)==f)>2     % 工龄1人数大于2
                    w = find(x(1:10,j,i)==f);   % 获取上班的人索引
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 生成随机索引 
                    n_de = n_geshu - 2;  % 要改为休假的员工人数
                    de_index = ran_index(1:n_de);  
                    dey_index = w(de_index,:);  % 随机抽取放假人员索引
                    x(dey_index,j,i) = 3; 
                end
                if sum(x(11:20,j,i)==f)>2     % 工龄2人数大于2
                    w = find(x(11:20,j,i)==f);  
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = n_geshu - 2; 
                    de_index = ran_index(1:n_de);
                    dey_index = w(de_index,:);
                    x(dey_index+10,j,i) = 3; 
                end
                if sum(x(21:25,j,i)==f)>1     % 工龄3人数大于2
                    w = find(x(21:25,j,i)==f);  
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = n_geshu - 1; 
                    de_index = ran_index(1:n_de);
                    dey_index = w(de_index,:);
                    x(dey_index+20,j,i) = 3; 
                end
                if sum(x(26:35,j,i)==f)>2     % 工龄4人数大于2
                    w = find(x(26:35,j,i)==f);   % 人索引
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = n_geshu - 2;  % 要取消的工作人数
                    de_index = ran_index(1:n_de);
                    dey_index = w(de_index,:);
                    x(dey_index+25,j,i) = 3; 
                end
                if sum(x(36:45,j,i)==f)>2     % 工龄5人数大于2
                    w = find(x(36:45,j,i)==f);  
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = n_geshu - 2;  
                    de_index = ran_index(1:n_de);
                    dey_index = w(de_index,:);
                    x(dey_index+35,j,i) = 3; 
                end
                if sum(x(46:50,j,i)==f)>1     % 工龄6人数大于2
                    w = find(x(46:50,j,i)==f);  
                    n_geshu = size(w,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = n_geshu - 1;  
                    de_index = ran_index(1:n_de);
                    dey_index = w(de_index,:);
                    x(dey_index+45,j,i) = 3; 
                end
            end
        end
        
        %%%!规定夜班后必是休息!
        for j = 1:6  %遍历一周前6天
            for k = 1:50 %遍历50个排班人员
                if x(k,j,i)==2
                    x(k,j+1,i)=3;
                end
            end
        end
        
        %%%%%确定每天每个班次不低于十人上班,若低于,随机选取改工龄内休假的人排班
        for j=1:7
            for f = 0:2
                if sum(x(1:10,j,i)==f)<2     
                    w = find(x(1:10,j,i)==f);   % 已经排班的人索引
                    n_geshu = size(w,1);
                    ww = find(x(1:10,j,i)==3);   % 休假人索引
                    nj_geshu = size(ww,1);
                    ran_index = randperm(nj_geshu);   % 随机索引 
                    n_cre = 2 - n_geshu;  % 要由休假变上班的人数
                    de_index = ran_index(1:n_cre);
                    dey_index = ww(de_index,:);
                    x(dey_index,j,i) = f; 
                end
                if sum(x(11:20,j,i)==f)<2     % 工龄2
                    w = find(x(11:20,j,i)==f);   
                    n_geshu = size(w,1);
                    ww = find(x(11:20,j,i)==3);   
                    nj_geshu = size(ww,1);
                    ran_index = randperm(nj_geshu);   % 随机索引 
                    n_cre = 2 - n_geshu;  
                    de_index = ran_index(1:n_cre);
                    dey_index = ww(de_index,:);
                    x(dey_index+10,j,i) = f; 
                end
                if sum(x(21:25,j,i)==f)==0     % 工龄3一班次只需一人,所以如果无人上班,添加一人
                    ww = find(x(21:25,j,i)==3);  
                    n_geshu = size(ww,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = 1;  
                    de_index = ran_index(1);
                    dey_index = ww(de_index,:);
                    x(dey_index+20,j,i) = f; 
                end
                if sum(x(26:35,j,i)==f)<2     % 工龄4
                    w = find(x(26:35,j,i)==f);  
                    n_geshu = size(w,1);
                    ww = find(x(26:35,j,i)==3);  
                    n_geshu = size(ww,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_cre = 2 - n_geshu;  
                    de_index = ran_index(1:n_cre);
                    dey_index = ww(de_index,:);
                    x(dey_index+25,j,i) = f; 
                end
                if sum(x(36:45,j,i)==f)<2     % 工龄5
                    w = find(x(36:45,j,i)==f);  
                    n_geshu = size(w,1);
                    ww = find(x(36:45,j,i)==3);  
                    n_geshu = size(ww,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_cre = 2 - n_geshu;  
                    de_index = ran_index(1:n_cre);
                    dey_index = ww(de_index,:);
                    x(dey_index+35,j,i) = f; 
                end
                if sum(x(46:50,j,i)==f)==0     % 工龄6
                    ww = find(x(46:50,j,i)==3);  
                    n_geshu = size(ww,1);
                    ran_index = randperm(n_geshu);   % 随机索引 
                    n_de = 1;  
                    de_index = ran_index(1);
                    dey_index = ww(de_index,:);
                    x(dey_index+45,j,i) = f; 
                end
            end
        end
    end
    
    %%%%%% 约束条件 %%%%%
    %约束1---  每天每班次上班十人,且工龄如题三比例  -------硬约束 --
    y1 = zeros(pop,7);%每天的适应值
    yy1 = zeros(pop,7);   % yy1,2,3表示早中晚班人员配置适应值
    yy2 = zeros(pop,7);
    yy3 = zeros(pop,7);
    yy4 = zeros(pop,7);   % yy4表示每天20人休息适应值--硬
    for i=1:size(initial_pop,1)
        for j=1:7
            yy1(i,j) = 1/((sum(x(1:10,j,i)==0)-2)^2 + (sum(x(11:20,j,i)==0)-2)^2 + (sum(x(21:25,j,i)==0)-1)^2 + (sum(x(26:35,j,i)==0)-2)^2 + (sum(x(36:45,j,i)==0)-2)^2 + (sum(x(46:50,j,i)==0)-1)^2 + 1);
                % 每个时间段的各年龄工人刚好和生产线匹配----早班,午班晚班类似
            yy2(i,j) = 1/((sum(x(1:10,j,i)==1)-2)^2 + (sum(x(11:20,j,i)==1)-2)^2 + (sum(x(21:25,j,i)==1)-1)^2 + (sum(x(26:35,j,i)==1)-2)^2 + (sum(x(36:45,j,i)==1)-2)^2 + (sum(x(46:50,j,i)==1)-1)^2 + 1);
            yy3(i,j) = 1/((sum(x(1:10,j,i)==2)-2)^2 + (sum(x(11:20,j,i)==2)-2)^2 + (sum(x(21:25,j,i)==2)-1)^2 + (sum(x(26:35,j,i)==2)-2)^2 + (sum(x(36:45,j,i)==2)-2)^2 + (sum(x(46:50,j,i)==2)-1)^2 + 1);
            yy4(i,j) = 1/((sum(x(1:10,j,i)==3)-4)^2 + (sum(x(11:20,j,i)==3)-4)^2 + (sum(x(21:25,j,i)==3)-2)^2 + (sum(x(26:35,j,i)==3)-4)^2 + (sum(x(36:45,j,i)==3)-4)^2 + (sum(x(46:50,j,i)==3)-2)^2 + 1);
            y1(i,j) = yy1(i,j) + yy2(i,j) + yy3(i,j) + yy4(i,j);
        end
    end
    
    %y1为每天的适应值(最大值为1),yw1为每周的适应值(理论最大值为7x4),此处为1
    for i=1:size(initial_pop,1)
        yw1(i,1) = sum(y1(i,:))/28;
    end

    %约束2-----   每人一周内上5休2  
    y2 = zeros(pop,7); %每人的适应值-硬 - 五休二
    y3 = ones(pop,k); %每人的适应值-软
    for i = 1:size(initial_pop,1) 
        for k = 1:49
            y2(i,k) = 1/((sum(x(k,1:7,i)==3) - 2)^2 + 1);   %最大 1  %上五休二 
            y4(i,k) = 1/((sum(x(k,1:7,i)==3)-sum(x(k+1,1:7,i)==3))^2 +1); 
            for j = 1:5  %遍历周一至周六
                if x(k,j,i) == 2    % 如果是放假--夜班后 
                    % 若放一天就继续工作的惩罚函数
                    y3(i,k) = y3(i,k) - 1/5 *( x(k,j+2,i)~=3 );   % 最大 1  尽量连休
                end
            end
        end
    end
    %y2,y3为每人的适应值(最大值为1),yr1,yr2为整个排班表的适应值(理论最大值为50),此处1
    for i=1:size(initial_pop,1)
        yr1(i,1) = sum( y2(pop,:) )/50;
        yr2(i,1) = sum( y3(pop,:) )/50;
        yr3(i,1) = sum( y4(pop,:) )/50;
    end
    % 权重凭感觉给的,实际应该考虑约束条件的重要性及达到约束的难易程度
    y = 0.8*yw1 +0.05*yr1 + 0.1*yr2 + 0.15*yr3;   
    
    %找到种群中的最优基因  
    [a,b] = max(y);  % a-单次迭代中最大y值; b-最大y的索引位置
    
    fit1=y/sum(y); %计算每个种群的适应度在总适应度里所占的比例
    fit2=cumsum(fit1); %累加

    %基因选择
    choose=sort(rand(pop,1)); %有序随机数序列
    k=1;
    i=1;
    while k<=pop
        if choose(k)<fit2(i)  % 此处使用的是--轮盘赌选择法
            choosen_population(k,:)=initial_pop(i,:);
            k=k+1;
        else
            i=i+1;
        end
    end
    
    %基因交叉--
    for i=1:2:pop-1
        if rand<crossover_probablity
            crossover_length=round(rand*(length-1))+1; %基因交叉长度
            crossover_population(i,:)=[choosen_population(i,1:crossover_length),choosen_population(i+1,crossover_length+1:end)];
            crossover_population(i+1,:)=[choosen_population(i+1,1:crossover_length),choosen_population(i,crossover_length+1:end)];
        else
            crossover_population(i:i+1,:) = choosen_population(i:i+1,:);
        end
    end
    
    %基因变异
    variation_population=crossover_population; 
    for i=1:pop
        if rand<variation_probablity
            variation_location=round(rand*(length-1))+1;
            variation_population(i,variation_location)=1-variation_population(i,variation_location);
        end
    end
    
    variation_population(end,:)=initial_pop(b,:); %保留该次迭代中的最优种群
    initial_pop=variation_population; %经选择、交叉、变异后的种群作为下一代的初始种群,从而完成迭代
    best(m,1)=y(b); % 记录下第m代的最优函数值
    best(m,2) = yw1(b);  %记录第m代的最优适应值们
    best(m,3) = yr1(b);
    best(m,4) = yr2(b);
    best(m,5) = yr3(b);
    best_pop(:,:,m) = x(:,:,b);  % 记录下第m代的最优排班表
end


%画图
y_smoothed = smooth(1:size(best,1),best(:,1), 0.5, 'loess');  %添加平滑曲线
figure;
plot(1:size(best,1),best(:,1),'-', 'LineWidth',1.2);hold on;
plot(1:size(best,1),y_smoothed,'-','color','red', 'LineWidth',1.2);hold on;
xlabel('迭代次数');
ylabel('适应值');
title('适应值变化曲线(排班一周)');

197f83306aef497882c99907b72d5c5c.png

标签:index,泰迪杯,end,--,de,50,ran,生产线,geshu
From: https://blog.csdn.net/wodertianna/article/details/138279136

相关文章

  • iptables防火墙
    目录什么是iptables防火墙?组件四表五链四表五链常用的链匹配顺序表的匹配顺序链的匹配顺序规则的匹配顺序iptables的安装iptables防火墙的配置方法iptables命令行配置命令格式常用的管理选项常用的匹配条件常用的控制类型iptables命令行使用如何保存规则规......
  • 通过K-means提取图片主颜色
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、基本流程是什么?二、使用步骤1.引入库2.从图像中提取主要颜色,并生成十六进制颜色列表3.生成颜色簇的直方图4.生成颜色分布的饼图,并保存或显示5.将颜色数据保存到Excel文件中6.批量处理文件......
  • 【计算理论】【《计算理论导引(原书第3版)》笔记】第〇章:绪论
    文章目录@[toc]第〇章:绪论0.1|自动机、可计算性与复杂性计算复杂性理论可计算性理论自动机理论0.2|数学概念和术语集合关系等价关系图简单路径连通图圈强连通图字符串和语言字母表上的字符串空串......
  • 数据可视化
    目录数据可视化:常见的数据可视化库:Echarts使用五步曲Echarts相关配置数据可视化:应对现在数据可视化趋势,越来越多企业需要在很多场景(营销数据,生产数据,用户数据)下使用,可视化图表来展示体现数据,让数据更加直观,数据特点更加突出主要目的:借助于图形化手段,清晰有效地传......
  • 【线性回归】梯度下降
    文章目录@[toc]数据数据集实际值估计值梯度下降算法估计误差代价函数学习率参数更新`Python`实现导包数据预处理迭代过程结果可视化完整代码结果可视化线性拟合结果代价变化数据数据集(......
  • Android跨进程通信--Binder机制及AIDL是什么?
    文章目录Binder机制Binder是什么?Binder相对于其他几种跨进程通信方式,有什么区别?谈一下BinderIPC通信过程:具体的通讯过程是什么?Binder如何处理发送请求与接收请求?Binder是通过什么方式来进行内存映射的?Binder是如何进行管理的?Binder、Socket的数据限制是多少?自己APP如......
  • android git提交代码命令以及常见命令的使用
    安装GitUbuntu:sudoapt-getinstallgit-core创建代码仓库:配置身份:gitconfig--globaluser.name"Tony"gitconfit--globaluser.email"[email protected]"查看身份:gitconfig--globaluser.namegitconfit--globaluser.email提交代码流程创建本地仓库:进......
  • 论文笔记:Inf-DiT: Upsampling Any-Resolution Image with Memory-Efficient Diffusion
    论文链接:[2405.04312]Inf-DiT:UpsamplingAny-ResolutionImagewithMemory-EfficientDiffusionTransformer(arxiv.org)论文代码:THUDM/Inf-DiT:OfficialimplementationofInf-DiT:UpsamplingAny-ResolutionImagewithMemory-EfficientDiffusionTransformer(gi......
  • [基础]tfcenter mount将Webdav服务挂载成本地磁盘(可显示使用空间)
    1、下载tfcentermount软件(1)点击官网 tfcenter官网 后下载挂载软件(2)以windows挂载为例,下载windows软件包(3)解压软件包,如下图所示2、配置tfcenter挂载(1)以管理员方式运行上图的tfcenter-mount.bat文件选择1安装tfcentermount服务到系统中选择3启动tfcentermount服务......
  • .NET Core中给上传图片的添加水印
    一.安装System.Drawing.Common库工具->NuGet包管理->程序包管理控制台输入命令Install-PackageSystem.Drawing.Common二.代码案例实现usingMicrosoft.AspNetCore.Http;usingMicrosoft.AspNetCore.Mvc;usingSystem.Drawing;usingSystem.Drawing.Imaging;usingSy......