|
@@ -14,6 +14,7 @@ import org.optaplanner.core.api.score.director.ScoreDirector;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -92,14 +93,13 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
}*/
|
|
|
LocalDateTime startDateTime = startTimeNewSet(process,scoreDirector);
|
|
|
|
|
|
- /*if(process.getDelay() != null && process.getDelay()>0){
|
|
|
- if(process.getProduceTime()>1000){
|
|
|
- int bc = (int) Math.ceil((double) process.getProduceTime() / 20);
|
|
|
- startDateTime = startDateTime.plusMinutes(process.getDelay() * bc);
|
|
|
- }else{
|
|
|
- startDateTime = startDateTime.plusMinutes(process.getDelay() * 30);
|
|
|
- }
|
|
|
- }*/
|
|
|
+ // 随机延时时间处理
|
|
|
+ if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")
|
|
|
+ || process.getProcessType().equals("铸轧") || process.getProcessType().equals("冷轧")){
|
|
|
+ startDateTime = startDateTime.plusMinutes(process.getDelay() * 60);
|
|
|
+ }else{
|
|
|
+ startDateTime = startDateTime.plusMinutes(process.getDelay() * 10);
|
|
|
+ }
|
|
|
scoreDirector.beforeVariableChanged(process, "startTime");
|
|
|
process.setStartTime(startDateTime);
|
|
|
scoreDirector.afterVariableChanged(process, "startTime");
|
|
@@ -473,6 +473,8 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
}
|
|
|
|
|
|
private LocalDateTime startTimeNewSet(ProductionProcesses process,ScoreDirector<ApsSolution> scoreDirector){
|
|
|
+ // 获取所有规划实体对象数据
|
|
|
+ ApsSolution workingSolution = scoreDirector.getWorkingSolution();
|
|
|
// 时间设定
|
|
|
LocalDateTime toUpdateStartTime = null;
|
|
|
if(process.getEquipment() != null){
|
|
@@ -505,18 +507,11 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
// 当前工序最大开始时间、结束时间
|
|
|
LocalDateTime proMaxStartTime = null;
|
|
|
LocalDateTime proMaxEndTime = null;
|
|
|
- if(preProcess.getMaxWaitTime() != null && preProcess.getMaxWaitTime()>0){
|
|
|
+ if(preProcess != null && preProcess.getMaxWaitTime() != null && preProcess.getMaxWaitTime()>0){
|
|
|
proMaxStartTime = proStartTime.plusMinutes(preProcess.getMaxWaitTime());
|
|
|
proMaxEndTime = proEndTime.plusMinutes(preProcess.getMaxWaitTime());
|
|
|
}
|
|
|
|
|
|
- // 随机延时时间处理
|
|
|
- if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")
|
|
|
- || process.getProcessType().equals("铸轧") || process.getProcessType().equals("冷轧")){
|
|
|
- proStartTime = proStartTime.plusMinutes(process.getDelay() * 60);
|
|
|
- }else{
|
|
|
- proStartTime = proStartTime.plusMinutes(process.getDelay() * 10);
|
|
|
- }
|
|
|
// 当前工序设备已占用时间
|
|
|
List<EquipmentRunTime> equipmentRunTimes = new ArrayList<>();
|
|
|
if(process.getEquipment().getEquipmentRunTimes() != null && process.getEquipment().getEquipmentRunTimes().size()>0){
|
|
@@ -524,37 +519,52 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
EquipmentRunTime copy = new EquipmentRunTime();
|
|
|
copy.setStartRunTime(equipmentRunTime.getStartRunTime());
|
|
|
copy.setEndRunTime(equipmentRunTime.getEndRunTime());
|
|
|
+ copy.setTotalVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
|
|
|
+ copy.setTotalSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
|
|
|
+ copy.setOccupyType(equipmentRunTime.getOccupyType());
|
|
|
copy.setLocked(true);
|
|
|
equipmentRunTimes.add(copy);
|
|
|
}
|
|
|
}
|
|
|
// 排程中当前设备其它作业占用时间
|
|
|
// 过滤同一设备存在开始时间不是当前工序的其它所有工序
|
|
|
- // 获取所有规划实体对象数据
|
|
|
- ApsSolution workingSolution = scoreDirector.getWorkingSolution();
|
|
|
Equipment pe = process.getEquipment();
|
|
|
List<ProductionProcesses> allProcessesList = workingSolution.getProcessesList();
|
|
|
+ if(workingSolution.isConstructionHeuristicEnd()){
|
|
|
+ allProcessesList = workingSolution.getStepBestProcessesList();
|
|
|
+ }
|
|
|
List<ProductionProcesses> filterProcess = allProcessesList.stream().filter(v -> {
|
|
|
return v.getEquipment() != null && v.getEquipment().getId().equals(pe.getId()) && v.getStartTime() != null && !v.getId().equals(process.getId());
|
|
|
}).sorted(Comparator.comparing(ProductionProcesses::getProduceTime)).collect(Collectors.toList());
|
|
|
+ /*if(process.getId().equals("066e031c712848bd8d40f5a3ae19d5f5")){
|
|
|
+ int i = workingSolution.getScore().initScore();
|
|
|
+ System.out.println("i:"+i);
|
|
|
+ if(i == 0){
|
|
|
+ List<ProductionProcesses> collect = allProcessesList.stream().filter(v -> v.getId().equals("96b9d96463524780ae7711c1f1bb8f20") && "2024-05-17 09:46".equals(v.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))).collect(Collectors.toList());
|
|
|
+ if(collect != null && collect.size()>0){
|
|
|
+ System.out.println(collect.get(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
if(filterProcess != null && filterProcess.size()>0){
|
|
|
for (ProductionProcesses productionProcesses : filterProcess) {
|
|
|
- if(equipmentRunTimes == null || equipmentRunTimes.size() == 0){
|
|
|
- continue;
|
|
|
- }
|
|
|
boolean merged = false;
|
|
|
if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")){
|
|
|
- for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
|
|
|
- // 判断当前排程的退火作业哪些是合并工序,只要开始时间到结束时间是包含关系即认为是合并工序
|
|
|
- if(equipmentRunTime.getStartRunTime().compareTo(productionProcesses.getStartTime())<=0
|
|
|
- && equipmentRunTime.getEndRunTime().compareTo(productionProcesses.getEndTime())>=0){
|
|
|
- // 合并退火作业总宽度、承重
|
|
|
- equipmentRunTime.setTotalVolumeWidth(equipmentRunTime.getTotalVolumeWidth().add(productionProcesses.getVolumeWidth()));
|
|
|
- equipmentRunTime.setTotalSinglerollweight(equipmentRunTime.getTotalSinglerollweight().add(productionProcesses.getSinglerollweight()));
|
|
|
- merged = true;
|
|
|
- break;
|
|
|
- }else{
|
|
|
- // 未锁定的是排程中的作业占用时间段,可以合并更大的加工时间
|
|
|
+ if(equipmentRunTimes != null && equipmentRunTimes.size()>0){
|
|
|
+ for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
|
|
|
+ if(equipmentRunTime.getOccupyType() != null && "maintenance".equals(equipmentRunTime.getOccupyType())){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 判断当前排程的退火作业哪些是合并工序,只要开始时间到结束时间是包含关系即认为是合并工序
|
|
|
+ if(equipmentRunTime.getStartRunTime().compareTo(productionProcesses.getStartTime())<=0
|
|
|
+ && equipmentRunTime.getEndRunTime().compareTo(productionProcesses.getEndTime())>=0){
|
|
|
+ // 合并退火作业总宽度、承重
|
|
|
+ equipmentRunTime.setTotalVolumeWidth(equipmentRunTime.getTotalVolumeWidth().add(productionProcesses.getVolumeWidth()));
|
|
|
+ equipmentRunTime.setTotalSinglerollweight(equipmentRunTime.getTotalSinglerollweight().add(productionProcesses.getSinglerollweight()));
|
|
|
+ merged = true;
|
|
|
+ break;
|
|
|
+ }else{
|
|
|
+ // 未锁定的是排程中的作业占用时间段,可以合并更大的加工时间
|
|
|
// if(!equipmentRunTime.isLocked()){
|
|
|
if(equipmentRunTime.getStartRunTime().compareTo(productionProcesses.getStartTime())>=0
|
|
|
&& equipmentRunTime.getEndRunTime().compareTo(productionProcesses.getEndTime())<=0){
|
|
@@ -567,6 +577,7 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
break;
|
|
|
}
|
|
|
// }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -575,6 +586,8 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
EquipmentRunTime copy = new EquipmentRunTime();
|
|
|
copy.setStartRunTime(productionProcesses.getStartTime());
|
|
|
copy.setEndRunTime(productionProcesses.getEndTime());
|
|
|
+ copy.setTotalVolumeWidth(productionProcesses.getVolumeWidth());
|
|
|
+ copy.setTotalSinglerollweight(productionProcesses.getSinglerollweight());
|
|
|
copy.setLocked(false);
|
|
|
equipmentRunTimes.add(copy);
|
|
|
}
|
|
@@ -588,27 +601,19 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
|
|
|
// 退火工序
|
|
|
if(process.getProcessType().equals("成退") || process.getProcessType().equals("中退")){
|
|
|
- if(equipmentRunTime.getEndRunTime().compareTo(proStartTime)<=0){
|
|
|
+ if(equipmentRunTime.getEndRunTime().compareTo(proStartTime)<=0 || equipmentRunTime.getStartRunTime().compareTo(proEndTime)>=0){
|
|
|
continue;
|
|
|
}else{
|
|
|
- if(equipmentRunTime.getStartRunTime().compareTo(proStartTime)<0){
|
|
|
- proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
|
|
|
- }else{
|
|
|
- if(equipmentRunTime.getStartRunTime().compareTo(proEndTime)<0){
|
|
|
- boolean merge = isMerge(pe, equipmentRunTime, process);
|
|
|
- if(merge){
|
|
|
- proStartTime = equipmentRunTime.getStartRunTime();
|
|
|
- }else{
|
|
|
- proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
|
|
|
- }
|
|
|
+ if((equipmentRunTime.getStartRunTime().compareTo(proStartTime)<=0 && equipmentRunTime.getEndRunTime().compareTo(proEndTime)>=0)
|
|
|
+ || (equipmentRunTime.getStartRunTime().compareTo(proStartTime)>=0 && equipmentRunTime.getEndRunTime().compareTo(proEndTime)<=0)){
|
|
|
+ boolean merge = isMerge(pe, equipmentRunTime, process);
|
|
|
+ if(merge){
|
|
|
+ proStartTime = equipmentRunTime.getStartRunTime();
|
|
|
}else{
|
|
|
- if(equipmentRunTime.getStartRunTime().compareTo(proMaxStartTime)<0){
|
|
|
- boolean merge = isMerge(pe, equipmentRunTime, process);
|
|
|
- if(merge){
|
|
|
- proStartTime = equipmentRunTime.getStartRunTime();
|
|
|
- }
|
|
|
- }
|
|
|
+ proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
|
|
|
}
|
|
|
+ }else{
|
|
|
+ proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -618,7 +623,7 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
continue;
|
|
|
}else{
|
|
|
proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
|
|
|
- proEndTime = proStartTime.plusMinutes(process.getProduceTime());
|
|
|
+// proEndTime = proStartTime.plusMinutes(process.getProduceTime());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -638,13 +643,18 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
|
|
|
*/
|
|
|
private boolean isMerge(Equipment pe,EquipmentRunTime equipmentRunTime,ProductionProcesses process){
|
|
|
boolean jumpMark = true;
|
|
|
- // 宽度余量
|
|
|
- if (pe.getEquipmentParameter().getEquipmentWidth().subtract(equipmentRunTime.getTotalVolumeWidth()).compareTo(process.getVolumeWidth()) < 0) {
|
|
|
- jumpMark = false;
|
|
|
- }
|
|
|
- // 重量余量
|
|
|
- if (pe.getEquipmentParameter().getEquipmentBearing().subtract(equipmentRunTime.getTotalSinglerollweight()).compareTo(process.getSinglerollweight()) < 0) {
|
|
|
+ // 保养维修占用时间不能合并
|
|
|
+ if("maintenance".equals(equipmentRunTime.getOccupyType())){
|
|
|
jumpMark = false;
|
|
|
+ }else{
|
|
|
+ // 宽度余量
|
|
|
+ if (pe.getEquipmentParameter().getEquipmentWidth().subtract(equipmentRunTime.getTotalVolumeWidth()).compareTo(process.getVolumeWidth()) < 0) {
|
|
|
+ jumpMark = false;
|
|
|
+ }
|
|
|
+ // 重量余量
|
|
|
+ if (pe.getEquipmentParameter().getEquipmentBearing().subtract(equipmentRunTime.getTotalSinglerollweight()).compareTo(process.getSinglerollweight()) < 0) {
|
|
|
+ jumpMark = false;
|
|
|
+ }
|
|
|
}
|
|
|
return jumpMark;
|
|
|
}
|