Commit c57474f5 authored by 李驰骋's avatar 李驰骋

排程逻辑调整

parent 04d12828
......@@ -125,7 +125,7 @@ public class ProWorkorderController extends BaseController {
proWorkorder.getProductName());
query.in(StringUtils.isNotEmpty(proWorkorder.getStatusArr()), "t1.status",
proWorkorder.getStatusArr());
query.in(StringUtils.isNotEmpty(proWorkorder.getStatusArr()), "t1.status",
query.in("t1.status",
new String[]{WorkorderStatusEnum.PREPARE.getValue(), WorkorderStatusEnum.PUBLISHED.getValue()});
query.gt("t1.quantity-t1.quantity_scheduled", 0);
query.orderByDesc("request_date");
......
package com.ximai.mes.pro.domain.task;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class WorkorderScheduleParams {
......@@ -11,6 +13,10 @@ public class WorkorderScheduleParams {
@ApiModelProperty("工单ID")
Long workorderId;
@ApiModelProperty("排产开始日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime scheduleDate;
@ApiModelProperty("本次排产数量")
BigDecimal scheduleQuantity;
......
......@@ -8,6 +8,7 @@ import lombok.Data;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Data
public class Equipment extends Resource{
......@@ -20,6 +21,7 @@ public class Equipment extends Resource{
private Long workCenterId;
private String workCenterCode;
private String workCenterName;
private Integer serial;
/**
* 固化时间
*/
......@@ -125,4 +127,16 @@ public class Equipment extends Resource{
public void initEquipmentFunction(MdWorkunitVo workUnit){
BeanUtil.copyProperties(workUnit, this.getEquipmentFunction());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Equipment resource = (Equipment) o;
return Objects.equals(super.getId(), resource.getId());
}
@Override
public int hashCode() {
return Objects.hash(super.getId());
}
}
package com.ximai.mes.pro.schedule;
import cn.hutool.core.bean.BeanUtil;
import com.ximai.mes.md.service.IMdWorkunitService;
import com.ximai.mes.pro.schedule.strategy.EquipmentSelectionResult;
import com.ximai.mes.pro.schedule.strategy.EquipmentSelectionStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class GreedyAlgThXM implements IAlgorithm{
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
public GreedyAlgThXM(EquipmentSelectionStrategy equipmentSelectionStrategy){
this.equipmentSelectionStrategy = equipmentSelectionStrategy;
}
@Override
public List<Job> schedule(List<Job> jobs, List<Resource> resources, List<Calendar> calendars) {
calendarManager = new CalendarManager();
this.sortedJobs = jobs.stream().collect(Collectors.toList());
this.resources = resources.stream().collect(Collectors.toList());
for (Job job : jobs) {
for (Task task : job.getTasks())
{
task.setCalendarManager(calendarManager);
}
}
for (Resource res : resources) {
res.setCalendarManager(calendarManager);
}
for (Calendar cld : calendars) {
if (cld instanceof Calendar.WorkingCalendar) {
calendarManager.addWorkingCalendar((Calendar.WorkingCalendar)cld);
}
}
for (Calendar cld : calendars) {
if (cld instanceof Calendar.OccupiedCalendar)
calendarManager.addOccupiedCalendar((Calendar.OccupiedCalendar)cld);
}
scheduleJobs();
return sortedJobs;
}
/**
* Job集合排产
* @return 本次被排产的Task个数
*/
private int scheduleJobs() {
AtomicInteger scheduledTaskCount = new AtomicInteger(0);
sortedJobs.forEach(job -> scheduledTaskCount.addAndGet(scheduleJob(job)));
return scheduledTaskCount.get();
}
/**
* Job排产
* @param job
* @return 本次被排产的Task个数
*/
private int scheduleJob(Job job) {
int scheduledTaskCount = 0;
job.setScheduleStatus(ScheduleStatus.Success);
if (job.getTasks().size() > 0) {
Task firstTask = job.getTasks().getFirst();
Task task = null;
scheduledTaskCount += scheduleTask(firstTask, null);
for (int i=0;i<job.getTasks().size()-1;i++) {
Task preTask = job.getTasks().get(i);
task = job.getTasks().get(i+1);
if(job.getScheduleStatus() == ScheduleStatus.Success) {
LimitedTimeCalculateContext limitedTimeCalculateContext = new LimitedTimeCalculateContext(job, task, preTask);
ILimitedTimeCalculator.LimitedTimeCalculatedResult limitedTimeCalculatedResult = task.getLimitedTimeCalculator().calculate(limitedTimeCalculateContext);
task.getLmtStartedTime().addOptional(limitedTimeCalculatedResult.getLmtStartedTime());
task.getLmtEndedTime().addOptional(limitedTimeCalculatedResult.getLmtEndedTime());
scheduledTaskCount += scheduleTask(task, preTask);
}
}
job.setScheduledStartedTime(job.getTasks().getFirst().getScheduledStartedTime());
job.setScheduledEndedTime(job.getTasks().getLast().getScheduledEndedTime());
if (job.getScheduleStatus()!= ScheduleStatus.Waiting && job.getScheduledEndedTime()!=null
&& job.getScheduledEndedTime().getSeconds() > job.getLmtEndedTime().get().getSeconds()) {
job.setScheduleStatus(ScheduleStatus.Delay);
}
}
return scheduledTaskCount;
}
/**
* Task排产
* @param task
* @return 本次是否排产
*/
private int scheduleTask(Task task, Task preTask) {
task.setPreTask(preTask);
if (task.getScheduleStatus() == ScheduleStatus.Success) {
return 0;
}
if (task.getLmtEndedTime().Waiting() || task.getLmtStartedTime().Waiting()) {
task.setScheduleStatus(ScheduleStatus.Waiting);
task.getJob().setScheduleStatus(ScheduleStatus.Waiting);
return 0;
}
EquipmentSelectionResult selectionResult = equipmentSelectionStrategy.evaluateOptionalEquipment(task);
logger.info(task.getProcessName()+",设备评分结果");
logger.info(selectionResult.getEvaluateDetail().toString());
List<EvaluateOptionalEquipmentResult> evaluateResultList = selectionResult.getSelectList();
if(task.isOutsourced()){
//查询外委作业单元
Optional<Resource> equipmentResource = this.resources.stream().filter(s-> IMdWorkunitService.OUTSOURCE_WORKUNIT_ID.equals(((Equipment)s).getId())).findFirst();
if(!equipmentResource.isPresent()){
task.setScheduleStatus(ScheduleStatus.InadequateTime);
task.getJob().setScheduleStatus(ScheduleStatus.InadequateTime);
task.getJob().setScheduleDesc("未找到外协作业单元");
return 0;
}
//外委工序固定三天加工工时
task.setScheduleStatus(ScheduleStatus.Success);
//首工序外协,使用当前时间作业开始时间
if(preTask==null){
task.setScheduledStartedTime(Duration.ofSeconds(0));
}else{
task.setScheduledStartedTime(preTask.getScheduledEndedTime());//使用上道任务结束时间
}
task.setScheduledEndedTime(task.getScheduledStartedTime().plusDays(3));
task.setScheduledEquipment((Equipment) equipmentResource.get());//固定外委作业单元
return 1;
}else if (evaluateResultList.isEmpty()) {
task.setScheduleStatus(ScheduleStatus.InadequateTime);
task.getJob().setScheduleStatus(ScheduleStatus.InadequateTime);
if(selectionResult.getCause() == EquipmentSelectionResult.EquipmentSelectionCause.UN_MATCH){
task.getJob().setScheduleDesc(String.format("工序%s,未匹配到可排产设备", task.getProcessName()));
}else if(selectionResult.getCause() == EquipmentSelectionResult.EquipmentSelectionCause.UN_EQUIPMENT){
task.getJob().setScheduleDesc(String.format("工序%s,未找到可排产设备", task.getProcessName()));
}else {
StringBuffer temp = new StringBuffer();
task.getOptionalEquipments().forEach(s -> {
temp.append("-" + s.getWorkUnitName());
});
task.getJob().setScheduleDesc(temp.toString());
}
return 0;
}
//任务分派到多台设备,拆分任务
if(evaluateResultList.size()>1){
List<Task> splitTask = new ArrayList<Task>();
task.setScheduleStatus(ScheduleStatus.Success);
evaluateResultList.forEach(selectedEquipment->{
if(task.getScheduledStartedTime()==null){
task.setScheduledStartedTime(selectedEquipment.getStartedTime());
}
if(task.getScheduledEndedTime()==null){
task.setScheduledEndedTime(selectedEquipment.getEndedTime());
}
if(task.getScheduledEndedTime().compareTo(selectedEquipment.getEndedTime())<0){
task.setScheduledEndedTime(selectedEquipment.getEndedTime());
}
Task subtask = new Task(0l, task.getJob());
BeanUtil.copyProperties(task, subtask);
subtask.setScheduledStartedTime(selectedEquipment.getStartedTime());
subtask.setScheduledEndedTime(selectedEquipment.getEndedTime());
subtask.setScheduledEquipment(selectedEquipment.getEquipment());
BigDecimal scheduleQuantity= selectedEquipment.getDetails().stream().map(s->s.getQuantity()).reduce(BigDecimal.ZERO, BigDecimal::add);
subtask.setOrderQuantity(scheduleQuantity);
splitTask.add(subtask);
});
task.setSplitTask(splitTask);
}else{
EvaluateOptionalEquipmentResult selectedEquipment = evaluateResultList.get(0);
task.setScheduleStatus(ScheduleStatus.Success);
task.setScheduledStartedTime(selectedEquipment.getStartedTime());
task.setScheduledEndedTime(selectedEquipment.getEndedTime());
task.setScheduledEquipment(selectedEquipment.getEquipment());
}
return evaluateResultList.size();
}
private List<Job> sortedJobs;
private List<Resource> resources;
private CalendarManager calendarManager;
private EquipmentSelectionStrategy equipmentSelectionStrategy;
}
......@@ -11,6 +11,9 @@ public class TaskSchedulingContext {
private Equipment equipment;
/**
* 设备日历排产结果
*/
@AllArgsConstructor
@Data
public static class TaskSchedulingResultContext{
......
......@@ -10,7 +10,7 @@ import java.util.List;
/**
* 物料领料申请单/调拨申请单
*/
@Component
public class MaterialRequestBuild implements ScheduleBusiProcess{
@Autowired
......
......@@ -10,7 +10,7 @@ import java.util.List;
/**
* 排产生成刀具申请领用单
*/
@Component
public class ToolRequestBuild implements ScheduleBusiProcess{
@Autowired
......
package com.ximai.mes.pro.schedule.strategy;
import com.ximai.mes.pro.schedule.*;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 资源设备选择策略
*/
public class EquipmentSelectionStrategyThXMImpl implements EquipmentSelectionStrategy{
boolean isMultiple = true;
private final List<EvaluateEquipment> evaluateEquipmentList = new ArrayList<EvaluateEquipment>(){{
}};
@Override
public EquipmentSelectionResult evaluateOptionalEquipment(Task task) {
EquipmentSelectionResult rst = new EquipmentSelectionResult();
List<IOperationTimeCalculator.OperationTimePlan> operationTimePlans = new ArrayList<IOperationTimeCalculator.OperationTimePlan>();
//必选设备逻辑添加
List<Equipment> matchEquipments = this.matchEquipment(task, task.getOptionalEquipments());
List<TaskSchedulingContext.TaskSchedulingResultContext> taskSchResults = new ArrayList<>();
if(task.getOptionalEquipments().isEmpty()){
rst.setCause(EquipmentSelectionResult.EquipmentSelectionCause.UN_EQUIPMENT);
return rst;
}else if(matchEquipments.isEmpty()){
rst.setCause(EquipmentSelectionResult.EquipmentSelectionCause.UN_MATCH);
return rst;
}
matchEquipments.forEach(eqt -> {
TaskSchedulingContext context = new TaskSchedulingContext()
{{
setJob(task.getJob());
setTask(task);
setEquipment(eqt);
}};
IOperationTimeCalculator.OperationTimePlan opertionTimePlan = task.getOperationTimeCalculator().calculate(context);
taskSchResults.add(new TaskSchedulingContext.TaskSchedulingResultContext(eqt, opertionTimePlan, context));
});
taskSchResults.forEach(s->{
//依次评估设备
evaluateEquipmentList.forEach(e->{
double evaluate = e.evaluate(s.getTaskSchedulingContext(), s.getOpertionTimePlan(), taskSchResults);
rst.getEvaluateDetail().append(e.getClass().getSimpleName()).append(":").append(evaluate).append("*").append(e.weight()).append(",");
s.getOpertionTimePlan().setScore((evaluate* e.weight())+s.getOpertionTimePlan().getScore());
});
rst.getEvaluateDetail().append(s.getEquipment().getWorkUnitName()).append(",合计:").append(s.getOpertionTimePlan().getScore()).append(System.getProperty("line.separator"));
operationTimePlans.add(s.getOpertionTimePlan());
});
if(operationTimePlans.isEmpty()){
rst.setCause(EquipmentSelectionResult.EquipmentSelectionCause.UN_CALENDER);
return rst;
}
rst.setSelectList(this.evaluateOptionalEquipment(task, operationTimePlans));
return rst;
}
/*
根据设备评估得分,返回合适的设备产能
评分第一如直接返回该设备,评分相同返回任意一台设备
*/
private List<EvaluateOptionalEquipmentResult> evaluateOptionalEquipment(Task task, List<IOperationTimeCalculator.OperationTimePlan> operationTimePlanList) {
List<EvaluateOptionalEquipmentResult> rst = new ArrayList<EvaluateOptionalEquipmentResult>();
List<IOperationTimeCalculator.OperationTimePlan> evaludateOpertionTimePlanList = new ArrayList<IOperationTimeCalculator.OperationTimePlan>();
//按评分倒排
operationTimePlanList.sort(Comparator.comparing(IOperationTimeCalculator.OperationTimePlan::getScore, Collections.reverseOrder()));
//评分第一如果数量满足任务,直接返回该数据
IOperationTimeCalculator.OperationTimePlan firstOperationTimePlan = operationTimePlanList.get(0);
BigDecimal totalQuantity = firstOperationTimePlan.getPlan().stream().map(s->s.getQuantity()).reduce(BigDecimal.ZERO, BigDecimal::add);
evaludateOpertionTimePlanList.add(firstOperationTimePlan);
if(task.getOrderQuantity().compareTo(totalQuantity)>0){
return rst;
}
evaludateOpertionTimePlanList.forEach(operationTimePlan->{
EvaluateOptionalEquipmentResult evaluateOptionalEquipmentResult = new EvaluateOptionalEquipmentResult()
{{
setEquipment(operationTimePlan.getEquipment());
setDetails(new ArrayList<DetailPlan>());
setStartedTime(Duration.ofSeconds(Long.MAX_VALUE));
setEndedTime(Duration.ZERO);
setScore(operationTimePlan.getScore());
}};
for (IOperationTimeCalculator.OperationTimePlanItem item : operationTimePlan.getPlan()) {
if (evaluateOptionalEquipmentResult.getStartedTime().getSeconds() > item.getStartedTime().getSeconds()) {
evaluateOptionalEquipmentResult.setStartedTime(item.getStartedTime());
}
if (evaluateOptionalEquipmentResult.getEndedTime().getSeconds() < item.getEndedTime().getSeconds()) {
evaluateOptionalEquipmentResult.setEndedTime(item.getEndedTime());
}
evaluateOptionalEquipmentResult.getDetails().add(new EvaluateOptionalEquipmentResult.DetailPlan(){{
setStartedTime(item.getStartedTime());
setEndedTime(item.getEndedTime());
setQuantity(item.getQuantity());
}});
}
rst.add(evaluateOptionalEquipmentResult);
});
return rst;
}
/**
* 添加设备评分规则
* @param evaluateEquipment
*/
public void addEvaluateEquipment(EvaluateEquipment evaluateEquipment){
evaluateEquipmentList.add(evaluateEquipment);
}
/**
* 完全匹配工序设备选择
* @param task
* @param equipments
* @return
*/
private List<Equipment> matchEquipment(Task task, List<Equipment> equipments) {
return equipments;
}
}
package com.ximai.mes.pro.schedule.strategy;
import cn.hutool.core.util.NumberUtil;
import com.ximai.mes.pro.schedule.Equipment;
import com.ximai.mes.pro.schedule.IOperationTimeCalculator;
import com.ximai.mes.pro.schedule.Task;
import com.ximai.mes.pro.schedule.TaskSchedulingContext;
import java.time.Duration;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 设备序列号评估
* 相同工作中心的工序,工序1取设备1、工序2取设备2
*/
public class EvaluateEquipmentSerial implements EvaluateEquipment{
@Override
public double evaluate(TaskSchedulingContext context, IOperationTimeCalculator.OperationTimePlan operationTimePlan
, List<TaskSchedulingContext.TaskSchedulingResultContext> scheduleResult) {
//设备按序号排序
List<Equipment> allEquipment = scheduleResult.stream().map(s->{
if(s.getEquipment().getSerial()==null){//为空优先级靠后
s.getEquipment().setSerial(99);
}
return s.getEquipment();
}).sorted(Comparator.comparing(Equipment::getSerial)).collect(Collectors.toList());
int index = 0;
Task currTask = context.getTask();
Equipment currEquip = context.getEquipment();
for(Task task : context.getJob().getTasks()){
if(task.getId().equals(currTask.getId())){
break;
}
if(task.getWorkCenterId().equals(currTask.getWorkCenterId())){
index++;
}
}
if(index>=allEquipment.size()){
index = index%allEquipment.size();
}
if(currEquip.getId().equals(allEquipment.get(index).getId())){
return 10;
}
return 0;
}
@Override
public int weight() {
return 1;
}
}
......@@ -430,7 +430,7 @@ public class ProWorkorderServiceImpl implements IProWorkorderService {
}
proWorkorder.setStatus(WorkorderStatusEnum.CLOSE.getValue());
this.updateWorkorderState(proWorkorder, WorkorderStatusEnum.CLOSE);
proWorkorderService.updateWorkorderState(proWorkorder, WorkorderStatusEnum.CLOSE);
return this.updateProWorkorder(proWorkorder);
}
......
......@@ -47,7 +47,11 @@ import com.ximai.mes.pro.schedule.AlgorithmDataSource;
import com.ximai.mes.pro.schedule.AlgorithmExtendDataSource;
import com.ximai.mes.pro.schedule.AlgorithmResultProcess;
import com.ximai.mes.pro.schedule.impl.BaoshenScheduleAlgorithmAdapter;
import com.ximai.mes.pro.schedule.impl.IScheduleAlgorithmAdapter;
import com.ximai.mes.pro.schedule.impl.ThXMScheduleAlgorithmAdapter;
import com.ximai.mes.pro.schedule.strategy.EquipmentSelectionStrategyImpl;
import com.ximai.mes.pro.schedule.strategy.EquipmentSelectionStrategyThXMImpl;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentSerial;
import com.ximai.mes.pro.service.*;
import com.ximai.mes.pro.service.proWorkOrder.IProWorkorderService;
import com.ximai.mes.pro.service.task.IProTaskService;
......@@ -66,6 +70,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -147,6 +152,7 @@ public class ProTaskServiceImpl implements IProTaskService {
@Autowired
private AlgorithmResultProcess algorithmResultProcess;
@Autowired
@Qualifier("algorithmDataSourceThXMImpl")
private AlgorithmDataSource algorithmDataSource;
@Autowired
private AlgorithmExtendDataSource equipmentNewestTaskAlgorithmData;
......@@ -1293,20 +1299,20 @@ public class ProTaskServiceImpl implements IProTaskService {
@Transactional
@Override
public void schedule(List<WorkorderScheduleParams> workorderScheduleParams) {
BaoshenScheduleAlgorithmAdapter baoshenScheduleAlgorithmAdapter = new BaoshenScheduleAlgorithmAdapter();
baoshenScheduleAlgorithmAdapter.setAlgorithmDataSource(algorithmDataSource);
baoshenScheduleAlgorithmAdapter.setAlgorithmResultProcess(algorithmResultProcess);
EquipmentSelectionStrategyImpl defaultStrategy = new EquipmentSelectionStrategyImpl();
baoshenScheduleAlgorithmAdapter.setEquipmentSelectionStrategy(defaultStrategy);
baoshenScheduleAlgorithmAdapter.setAlgorithmExtendDataSources(new ArrayList<AlgorithmExtendDataSource>() {
ThXMScheduleAlgorithmAdapter scheduleAlgorithmAdapter = new ThXMScheduleAlgorithmAdapter();
scheduleAlgorithmAdapter.setAlgorithmDataSource(algorithmDataSource);
scheduleAlgorithmAdapter.setAlgorithmResultProcess(algorithmResultProcess);
EquipmentSelectionStrategyThXMImpl defaultStrategy = new EquipmentSelectionStrategyThXMImpl();
defaultStrategy.addEvaluateEquipment(new EvaluateEquipmentSerial());
scheduleAlgorithmAdapter.setEquipmentSelectionStrategy(defaultStrategy);
scheduleAlgorithmAdapter.setAlgorithmExtendDataSources(new ArrayList<AlgorithmExtendDataSource>() {
private static final long serialVersionUID = -4466020352312471396L;
{
add(equipmentNewestTaskAlgorithmData);
add(scheduleSetupRuleAlgorithmData);
}
});
baoshenScheduleAlgorithmAdapter.schedule(LocalDateTime.now(),
workorderScheduleParams);
scheduleAlgorithmAdapter.schedule(LocalDateTime.now(), workorderScheduleParams);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
......
......@@ -24,10 +24,7 @@ public class CalendarManagerTest {
this.setStartedTime(Duration.ofMinutes(60*8));
this.setEndedTime(Duration.ofMinutes(60*10));
this.setQuantity(BigDecimal.valueOf(500));
this.setResource(new Equipment(){{
setIsParallel(false);
setId(1l);
}});
this.setResource(resource);
}});
List<Calendar.LeisureCalendar> leisureCalendarList = calendarManager.getLeisureCalendar(resource);
Assert.assertEquals(Duration.ofMinutes(60*10), leisureCalendarList.get(0).getStartedTime());
......@@ -38,10 +35,7 @@ public class CalendarManagerTest {
this.setStartedTime(Duration.ofMinutes(60*6));
this.setEndedTime(Duration.ofMinutes(60*14));
this.setQuantity(BigDecimal.valueOf(500));
this.setResource(new Equipment(){{
setIsParallel(false);
setId(1l);
}});
this.setResource(resource);
}});
leisureCalendarList = calendarManager.getLeisureCalendar(resource);
//第一个空闲时间被删除
......@@ -55,10 +49,7 @@ public class CalendarManagerTest {
this.setStartedTime(Duration.ofMinutes(60*9));
this.setEndedTime(Duration.ofMinutes(60*10+25));
this.setQuantity(BigDecimal.valueOf(500));
this.setResource(new Equipment(){{
setIsParallel(false);
setId(1l);
}});
this.setResource(resource);
}});
leisureCalendarList = calendarManager.getLeisureCalendar(resource);
Assert.assertEquals(leisureCalendarList.size(), 4);
......
package com.bs.mes.schedule.strategy;
import com.ximai.mes.pro.schedule.*;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentCapacity;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentDeliveryTime;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentSerial;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class EvaluateEquipmentSerialTest {
@Test public void evaluate(){
EvaluateEquipmentSerial evaluateEquipmentSerial = new EvaluateEquipmentSerial();
TaskSchedulingContext context = new TaskSchedulingContext();
Equipment equipment1 = new Equipment();
equipment1.setId(1L);
equipment1.setSerial(1);
Equipment equipment2 = new Equipment();
equipment2.setId(2L);
equipment2.setSerial(2);
Equipment equipment3 = new Equipment();
equipment3.setId(3L);
equipment3.setSerial(3);
Equipment equipment4 = new Equipment();
equipment4.setId(4L);
equipment4.setSerial(4);
List<TaskSchedulingContext.TaskSchedulingResultContext> scheduleResult = new ArrayList<>();
scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment1, null, null));
scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment2, null, null));
scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment3, null, null));
scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment4, null, null));
IOperationTimeCalculator.OperationTimePlan operationTimePlan = new IOperationTimeCalculator.OperationTimePlan();
Job job = new Job("1", Duration.ofHours(5));
LinkedList<Task> jobTasks = new LinkedList<>();
jobTasks.add(new Task(1l, job));
jobTasks.add(new Task(2l, job));
jobTasks.add(new Task(3l, job));
jobTasks.add(new Task(4l, job));
jobTasks.add(new Task(5l, job));
jobTasks.get(0).setWorkCenterId(1l);
jobTasks.get(1).setWorkCenterId(1l);
jobTasks.get(2).setWorkCenterId(2l);
jobTasks.get(3).setWorkCenterId(3l);
jobTasks.get(4).setWorkCenterId(4l);
job.setTasks(jobTasks);
Task currTask = jobTasks.get(1);
context.setTask(currTask);
context.setJob(job);
context.setEquipment(equipment1);
//2道序,设备1:0分、设备2:10分
double rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment2);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
// 相同工作中心任务数超过设备数,重头开始计算
jobTasks.add(new Task(6l, job));
jobTasks.add(new Task(7l, job));
jobTasks.add(new Task(8l, job));
jobTasks.get(5).setWorkCenterId(1l);
jobTasks.get(6).setWorkCenterId(1l);
jobTasks.get(7).setWorkCenterId(1l);
context.setTask(jobTasks.get(7));
context.setEquipment(equipment1);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
//验证设备序号为空情况
equipment3.setSerial(null);
//任务1,匹配的设备1
context.setTask(jobTasks.get(0));
context.setEquipment(equipment1);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
context.setEquipment(equipment2);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment3);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment4);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
//任务2匹配设备2
context.setTask(jobTasks.get(1));
context.setEquipment(equipment1);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment2);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
context.setEquipment(equipment3);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment4);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
//任务6匹配设备4
context.setTask(jobTasks.get(5));
context.setEquipment(equipment1);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment2);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment3);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment4);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
//任务7匹配设备3
context.setTask(jobTasks.get(6));
context.setEquipment(equipment1);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment2);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
context.setEquipment(equipment3);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(10, rst, 0.1);
context.setEquipment(equipment4);
rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
Assert.assertEquals(0, rst, 0.1);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment