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

问题背景:

        问题四:根据实际情况,现需要扩大生产规模,将生产线每天的运行时间从 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/653017.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

香橙派Orange AI Pro 初体验

什么是香橙派 &#xff1f; 香橙派&#xff08;Orange Pi&#xff09;是深圳市迅龙软件有限公司旗下的开源产品品牌。它专注于为全球个人和企业提供高性价比的开源硬件、开源软件以及OEM/ODM服务。香橙派已经迭代了30多款产品&#xff0c;形成了涵盖开源硬件、开源软件、开源芯…

vue3主题切换按钮与功能实现

代码: <template><div class"slideThree"><label class"theme-switch"><inputtype"checkbox"class"checkbox"v-model"isChecked"change"setTheme"id"slideThree"name"check…

三品软件:打造高效安全的图文档管理体系

在数字化转型的浪潮中&#xff0c;工程设计单位和企业设计部门面临着电子图文档管理的巨大挑战。随着电子图纸和文档数量的激增&#xff0c;如何有效组织、管理和共享这些资源&#xff0c;成为提升工作效率和保障信息安全的关键。本文将探讨当前图文档管理面临的问题&#xff0…

html+CSS部分基础运用7

项目1 设计简易灯箱画廊 1.实验所需素材 在trees文件夹中提供一个MP3文件和18个JPG文件&#xff0c;设计页面时可以使用。 2.编程实现简易灯箱画廊&#xff0c;鼠标单击任一个图像超链接&#xff0c;在底部浮动框架中显示大图像&#xff0c;效果如图4-1所示的页面。 图4-1 简…

香橙派 AIpro开发板开箱测评(代码开源)

前言&#xff1a;有幸能够收到一块梦寐以求的 AI 边缘计算开发板 OrangePi AIpro&#xff0c;非常感谢官方大大给予的宝贵机会。OrangePi AIpro是香橙派官方跟华为昇腾合作的新一代边缘计算产品&#xff0c;其使用华为昇腾 AI 技术路线&#xff0c;搭配集成图像处理器&#xff…

颈椎引起的头晕,背后的秘密震惊你!

颈椎引起的头晕相对来说还是比较少见的。国外呢一些文献基本上你就见不到颈性眩晕这个词。 有一个病叫弓猎人综合征&#xff0c;可能和颈椎有关系&#xff0c;就是在军队上&#xff0c;军人在拉弓的时候出现眩晕这种情况&#xff0c;后来发现在旋转颈部的时候&#xff0c;压迫到…

今日好料推荐(Altium Designer + 仿真器驱动)

今日好料推荐&#xff08;Altium Designer 仿真器驱动&#xff09; 参考资料在文末获取&#xff0c;关注我&#xff0c;获取优质资源。 Altium Designer Altium Designer 是一种高度集成的电子设计自动化 (EDA) 软件工具&#xff0c;广泛应用于电子电路和印刷电路板 (PCB) …

Java核心: 使用asm操作字节码

在上一篇<Java核心: 注解处理器>中我们提到&#xff0c;通过实现AbstractProcessor&#xff0c;并调用javac -processor能够生成代码来实现特殊逻辑。不过它存在两个明显的问题: 只能新增源文件来扩展逻辑&#xff0c;无法修改现有的类或方法 必须有一个单独的编译过程&a…

酒店提前线上订房小程序源码系统 PHP+MySQL组合开发 源码开源可二开 带完整的安装代码包以及搭建教程

系统概述 随着移动互联网的普及&#xff0c;越来越多的人习惯通过手机进行酒店预订。传统的线下订房方式逐渐无法满足用户的需求&#xff0c;酒店提前线上订房小程序的出现成为必然趋势。该源码系统的开发旨在为酒店提供一个便捷、高效的线上订房平台&#xff0c;提升用户体验…

UE5 CommonUI的使用(附源码版)

UE5 CommonUI的使用 前言快速配置配置Game Viewport Client ClassCommonGameViewportClient源代码 创建CommonInputAction表默认导航Action设置CommonUIInputData源码 Bind CommonInputBaseControllerDataCommonInputBaseControllerData源码 Common UI控件库和控件样式CommonUs…

深度神经网络——贝叶斯与朴素贝叶斯定理

概述 贝叶斯定理是概率论中一个非常重要的概念&#xff0c;它提供了一种在已知某些相关事件的概率时&#xff0c;计算另一个事件发生概率的方法。在你提供的内容中&#xff0c;贝叶斯定理被描述为一种“魔法”&#xff0c;因为它能够使计算机通过分析大量的数据来预测人们可能…

亚马逊自养号与机刷有何区别?

在亚马逊这一全球电商巨头中&#xff0c;买家评价的重要性如同指南针般引领着消费者的购买决策。在购买前&#xff0c;消费者们往往会驻足查看产品的评论&#xff0c;仔细比较不同产品的买家口碑&#xff0c;以确保自己的选择既明智又满意。因此&#xff0c;测评成为了各大电商…

安装sbt利用开发工具IntelliJ IDEA编写Spark应用程序(Scala+SBT)参考林子雨教程

文章目录 1、安装sbt2、下载安装IDEA3、给IDEA安装中文插件4、在Intellij里安装scala插件&#xff0c;构建基于SBT的Scala项目利用SBT 添加依赖包 创建WordCount实例 1、安装sbt sbt&#xff08;Simple Build Tool&#xff09;是对Scala或Java语言进行编译的一个工具&#xff…

多态(C++)

多态(C) 本文如果有错误或者不足的地方&#xff0c;希望各位大佬多多指点。 【本文目录】 1.多态的概念2.多态的定义及实现3.抽象类4.多态的原理5.单继承和多继承的虚函数表 1.多态的概念 多态的概念就是&#xff1a;多种形态 多态就是可以有多种的形态。不同的身份去实现同一…

【JavaScript】P2 JavaScript 书写位置

本博文总结&#xff1a; JavaScript 书写位置&#xff1a; 内部外部行内 注意事项&#xff1a; 书写的位置尽量写到 </body> 之前外部 js 标签中间不写任何内容&#xff0c;因为不予以展示 正文&#xff1a; 交互效果示例 一个简单的交互效果示例&#xff1b; <…

Echarts图表库推荐以及使用Echarts实现饼图端头弧形效果

推荐Echarts图表库官方链接http://www.ppchart.com/#/ 下面是一段实现饼图端头弧形效果的Echarts代码 虽然有了上面的图表库&#xff0c;里面案例也挺多&#xff0c;但是就是没找到我想要的这种效果&#xff0c;索性就手写了一个 下面代码可以直接去我上面的图标库运行看效果…

【CTF Web】CTFShow web11 Writeup(RCE+PHP+代码审计)

web11 1 阿呆听完自己菜死了&#xff0c;自己呆了。决定修好漏洞&#xff0c;绝对不能让自己再菜死了。 解法 可知 flag 在 config.php。 <?php # flag in config.php include("config.php"); if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/system…

线性稳压电路和开关稳压电路

稳压二极管稳压电路 电网电压增大&#xff0c;导到u1端的电压增大&#xff0c;从而使输出电压&#xff0c;稳压二极管两端的电压增大&#xff0c;稳压二极管两端电压增大&#xff0c;使流过的电注增大。那么&#xff0c;流过线性电阻R的总电流增大。 Ur电压增大&#xff0c;从…

数据挖掘与机器学习——分类算法

目录 机器学习算法最普通分类&#xff1a; 分类算法的定义&#xff1a; 分类算法的应用&#xff1a; 分类器实现分类&#xff1a; 分类器的构建标准&#xff1a; 概率模型&#xff1a; 贝叶斯公式&#xff1a; 朴素贝叶斯算法&#xff08;朴素贝叶斯分类器&#xff09;…

ShardingSphere使用案例

文章目录 一、分表1. 项目架构搭建2. 数据库搭建3. 案例开发一、分库1. 创建新的库2. 修改配置文件一、分表 1. 项目架构搭建 创建Maven项目导入相关依赖<dependencies><