要对若干工作中心(都是机台)进行有限产能的生产安排,要求机台的利用率越高越好。
影响排产的因素比较多。
一、工作中心能生产的工序、工序的类别(难易程度)要考虑
二、配置的技术人员不是一对一的,一个班次通常是两个技术人员,管理若干个机台。在每个任务生产前需要调机,占用技术人员的时间,一个技术员同一时间只能调一个机台。
三、工作中心有班次安排,计算起止时间需要考虑班次
四、工作中心有维护计划,在维护计划时段内的不能排单
五、同一任务可以分拆开,安排在不同机台上同时生产
六、如果某工作中心在此之前有生产过这个产品并且是这个工序的,优先考虑,调机时间为15分钟,如果没有生产过则调机时间为20分钟
七、如果上一班次未排完则下一班次继续,连续生产的不需要调机
相关的类简化后大致如下,求Calculate过程的算法实现:
class Test
{
/// <summary>
/// 排产计划
/// </summary>
/// <param name="tasks">等生产的任务列表</param>
/// <param name="date">排产日期</param>
/// <param name="shiftCode">班次,每个工作中心(机台)可能有1~2个班次,不指定班次则全部班次都要排</param>
/// <param name="peoples">技工人数,调机需要技工,技工不能同时调多机台</param>
/// <returns></returns>
public List<Plan> Calculate(List<Task> tasks, DateTime date, string shiftCode = "", int peoples = 2)
{
//此处写计算逻辑,要求用最短的时间完成任务,机台和人员利用率尽量高
//当前一班次有未完成的任务时,优先安排同工作中心继续生产,并且无需调机
//优先安排之前有生产过此产品此工序的工作中心生产,调机时间较少
//调机需要技工,技工不能同时出现在多个工作中心,上班时间与机台班次相同
//同一任务可以拆分到多个工作中心生产
//工作中心、排班等资料从数据库获取,此处省略获取方法
List<Workcenter> workcenters = new List<Workcenter>();
List<MaintenancePlan> MaintenancePlans = new List<MaintenancePlan>();
//其它参数及算法
return new List<Plan>();
}
}
/// <summary>
/// 工作中心
/// </summary>
class Workcenter
{
public int ID { get; set; }
}
/// <summary>
/// 工序
/// </summary>
class Process
{
public int ID { get; set; }
}
/// <summary>
/// 工序类型,例如难、中、易等
/// </summary>
class ProcessType
{
public int ID { get; set; }
}
/// <summary>
/// 工作中心可以生产的工序类型
/// </summary>
class WorkcenterProcessType
{
/// <summary>
/// 工作中心ID
/// </summary>
public int WorkcenterID { get; set; }
/// <summary>
/// 工序ID
/// </summary>
public int ProcessID { get; set; }
/// <summary>
/// 工序类型ID
/// </summary>
public int ProcessTypeID { get; set; }
}
/// <summary>
/// 班次
/// </summary>
class Shift
{
public string ShiftCode { get; set; }
}
/// <summary>
/// 班次明细
/// </summary>
class ShiftDetails
{
public string ShiftCode { get; set; }
/// <summary>
/// 班次开始时间,分钟数,例如中午12:00为720
/// 夜班跨天加1440分钟
/// </summary>
public int BeginTime { get; set; }
public int EndTime { get; set; }
}
/// <summary>
/// 维护计划,在维护计划时段内的机台不可用
/// </summary>
class MaintenancePlan
{
public int ID { get; set; }
public int WorkcenterID { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
/// <summary>
/// 生产任务
/// </summary>
class Task
{
public int ID { get; set; }
/// <summary>
/// 待生产的数量
/// </summary>
public decimal Qty { get; set; }
public int ProcessID { get; set; }
public int ProcessTypeID { get; set; }
/// <summary>
/// 前置时间,调机用时,需要技术员。技术员上班时间同机台排班
/// 如果工作中心有生产此产品、此工序则调机时间为15分钟,否则为20分钟
/// </summary>
public decimal PreMinutes { get; set; }
/// <summary>
/// 产能
/// </summary>
public int Capacity { get; set; }
}
/// <summary>
/// 排产结果
/// </summary>
class Plan
{
public int ID { get; set; }
public int TaskID { get; set; }
public int WorkcenterID { get; set; }
public DateTime Date { get; set; }
public string ShiftCode { get; set; }
public decimal Qty { get; set; }
public decimal PrevMinutes { get; set; }
/// <summary>
/// 开始生产的时间,包含前置的调机时间
/// 班次日期经过的分钟数
/// </summary>
public int StartTime { get; set; }
public int EndTime { get; set; }
}