目录
1 概述
班组(Crew)以j作为其序号,每个班组具有特定的任务能力(如能做某类任务,不能做某类任务);针对其能力所及的任务﹐班组因其人员组成的能力或配置的设备能力不同,具有不同的作业效率(效率采用完成该任务的小时数来表示)。对班组根据其任务能力和作业效率进行班组类别(Crew_Type)划分,即相同类别的班组完成同一任务的作业效率相等。
对于企业管理者来说,如何合理的分配员工去完成任务,是降低企业运行费用,提升企业产品开发的重要手段。现代化企业需要制定一套科学的方法对员工进行任务分配,以达到最大的效益。一般来说,该类问题可以归结到指派问题上。但是,随着社会发展,人员类型变得越来越复杂。不同的任务之间往往存在先后顺序以及优先级关系。
传统的方法通常首先对该问题进行数学建模。在这个过程中,需要考虑问题的相关特性,并用数学语言进行表述。然后可以通过线性规划等方法对问题进行优化,最后得到排班结果。然而,由于现实世界并非总是线性的,因此问题的数学模型将包含非线性部分。一般来说,可以通过一些方法,比如引入辅助决策变量,将模型的非线性部分转化为线性部分,从而达到使用传统方法求解的效果。该类方法在不破坏数学模型的前提下具有较好的效果,因此被广泛研究和应用。但是该方法也会导致数学模型与真实世界存在差别。
另一方面,随着考虑问题维度的增加,员工调度问题往往是一个多目标优化问题。在对问题进行优化时,需要考虑完成时间、员工工资等目标函数。不是一般性,我们定义多目标优化问题如下:
传统的线性规划方法在处理多目标优化问题时,通常通过事先给定的一组权重向量把多目标优化问题转化成单目标优化问题,例如线性加权方法。该方法形式简单、实现容易,因此一直是处理多目标优化问题的一个考虑方向。但是,线性加权方法具有许多弊端,具体表现在:1、权重向量难以确定。多个目标函数之间必然存在矛盾,如果使用简单的线性加权的话,只能通过调节权值大小来获得多组不同的解。但是这样权值的确定其实是很难的,往往需要通过多次实验来确定。二、各个目标之间量纲的不统一,可能会造成单目标优化问题鲁棒性差。对于现实世界中的工程问题,各个目标之间量纲往往不统一,比如买车价格为10万至100万,而舒适度为0到1。为了平衡各个目标之间的量纲,往往需要设置较大的权值。而如果小量纲的目标函数包含noise的话,很大的权值就会对整个目标函数产生巨大的影响,从而导致问题的鲁棒性较差。三、单目标加权求和只能逼近凸的帕累托面。加权求和的方式只能逼近帕累托前沿面为凸集的情况,如果多目标优化问题的帕累托面为非凸,则加权求和的方式就不能和原多目标优化问题等价,此时只有直接处理原多目标优化问题才能解决。四、多目标优化问题的帕累托解集包含更多有效信息。多目标优化问题的求解是会得到一个帕累托解集的,这个解集里边包含着很多的信息,例如可以分析目标之间的关系,便于决策者更好地了解模型。
针对上述提到的问题,进化多目标优化(Evolutionary multiobjective optimization,EMO)算法越来越得到学界的广泛关注。EMO算法受自然界生物进化适应环境的启发,通过模拟进化的过程去搜索问题的最优解。由于EMO算法不受模型的约束,能够处理非线性问题,并且在目标个数较低时,如2或3目标优化问题,能够给出令决策者满意的帕累托最优解集,因此被应用在许多的工程问题上。全部文章见第3部分。
部分代码:
%% 解码
global m Rjd salary Tjd_min
% 按照任务顺序分配任务,直到完成
FTd = zeros(1,m); %任务完成时间
STd = zeros(1,m); %任务的开始时间
FTpd = zeros(1,m); %前序工作的完成时间
Td = zeros(1,m); %任务d的工期
total_salary = 0;
next_time_work = zeros(1,40); %辅助变量
a=-log(0.91)/log(2);
b=-log(1-0.04)/log(2);
%基本想法,每次分配完任务,更新Tijd表。
index = 1;
e_index = 1;
record = [];
for i=1:1:m
%看一下前序工作的完成时间
if i==3
STd(i) = FTd(2);
end
if i==5
STd(i) = max(FTd(1),FTd(2));
end
if i==6
STd(i) = max(FTd(1),FTd(4));
end
if i==7
STd(i) = max(FTd(3),FTd(5));
end
if i==8
STd(i) = FTd(3);
end
if i==9
STd(i) = max(FTd(6),max(FTd(7),FTd(8)));
end
if i==10
STd(i) = FTd(9);
end
%找到需要的技能
skill = find(Rjd(:,i)==1);
needtime = zeros(1,numel(skill));
for j=1:1:numel(skill)
%找到相关人员
worker = x(index);
total_salary = total_salary + salary(worker);
needtime(j) = Tijd(worker,skill(j),i);
%检查工人什么时候可以开工
if STd(i) > next_time_work(worker) %任务开始时,工人处于空闲
%buganshenme
else %任务开始时,工人处于忙碌状态
needtime(j) = needtime(j) + next_time_work(worker) - STd(i);
end
next_time_work(worker) = STd(i) + needtime(j);
record(index,:) = [worker i skill(j) STd(i) next_time_work(worker)];
index = index+1;
end
Td(i) = max(needtime); %工期是最大的工人工作时间
%分配完一个任务之后,更新Eij
for j=1:1:numel(skill)
%找到相关人员
worker = x(e_index);
Eij(worker,skill(j)) = Eij(worker,skill(j)) * (needtime(j)^a) * (Td(i)-needtime(j))^b;
%更新T表
Tijd(worker,skill(j),i) = Tjd_min(skill(j),i)/Eij(worker,skill(j));
e_index = e_index+1;
end
FTd(i) = STd(i) + Td(i);
end
final_date = max(FTd);
z=[final_date;total_salary];
figure
color=['r','g','y','c','m','b','k','r','g','c',];
for i=1:m
rec(1) = STd(i);%矩形的横坐标
rec(2) = i-0.5; %矩形的纵坐标
rec(3) = FTd(i)-STd(i); %矩形的x轴方向的长度
rec(4) = 1;
rectangle('Position',rec,'LineWidth',0.5,'LineStyle','-','FaceColor',color(i));%draw every rectangle
end
2 运行结果
部分理论引用网络文献,如有侵权请联系删除。
3 参考文献
[1]章坚民,吴鑫淼,陈耀军,肖丰,王剑辉,章法源.供电公司移动作业排班调度优化模型及算法[J].电力系统自动化,2013,37(14):81-88