|
@@ -8,6 +8,8 @@ import com.rongwei.rwapsserver.aps.domain.*;
|
|
|
import com.rongwei.rwapsserver.aps.util.ApsConstants;
|
|
|
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
|
|
|
import org.optaplanner.core.api.score.stream.*;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
@@ -35,6 +37,8 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
|
|
|
seriesProduceWashingFurnace(constraintFactory),
|
|
|
seriesProduceWashTimeWait(constraintFactory),
|
|
|
+
|
|
|
+ sameProcessSeries(constraintFactory),
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -559,7 +563,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
pp.setEndTime(equipmentRunTime.getEndRunTime());
|
|
|
pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
// 铸轧工序合金设置
|
|
|
- String[] hjs = equipmentRunTime.getSeriesProduceMark().split("^_^");
|
|
|
+ String[] hjs = equipmentRunTime.getSeriesProduceMark().split("\\^_\\^");
|
|
|
if(hjs.length>0){
|
|
|
pp.setVolumeMetal(hjs[0]);
|
|
|
}
|
|
@@ -665,8 +669,8 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
|
|
|
if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
|
|
|
if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
|
|
|
- String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
- String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
|
|
|
// 换辊时长(分钟)
|
|
|
int jgtime = hasStartTimeProcess.get(i).getCutfinishmin() + hasStartTimeProcess.get(i+1).getPrepressworkmin();
|
|
|
// 立板时长(分钟)
|
|
@@ -676,7 +680,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
if(standingtime>jgtime){
|
|
|
maxTime = standingtime;
|
|
|
}
|
|
|
- if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ if(serspre.length == 5 && sersafter.length == 5){
|
|
|
// 合金不同则需要换辊和立板
|
|
|
if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(maxTime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
@@ -689,13 +693,13 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
String s1 = serspre[2];
|
|
|
String s2 = sersafter[2];
|
|
|
try{
|
|
|
- Integer i1 = Integer.parseInt(s1);
|
|
|
- Integer i2 = Integer.parseInt(s2);
|
|
|
- if(i1<i2){
|
|
|
+ BigDecimal i1 = new BigDecimal(s1);
|
|
|
+ BigDecimal i2 = new BigDecimal(s2);
|
|
|
+ if(i1.compareTo(i2)<0){
|
|
|
if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(maxTime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
b++;
|
|
|
}
|
|
|
- }else if(i1>i2){
|
|
|
+ }else if(i1.compareTo(i2)>0){
|
|
|
if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(standingtime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
b++;
|
|
|
}
|
|
@@ -707,9 +711,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
}
|
|
|
} else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
|
|
|
- String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
- String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
- if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ if(serspre.length == 5 && sersafter.length == 5){
|
|
|
if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
.plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
@@ -719,9 +723,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
String s1 = serspre[2];
|
|
|
String s2 = sersafter[2];
|
|
|
try{
|
|
|
- Integer i1 = Integer.parseInt(s1);
|
|
|
- Integer i2 = Integer.parseInt(s2);
|
|
|
- if(i1<i2){
|
|
|
+ BigDecimal i1 = new BigDecimal(s1);
|
|
|
+ BigDecimal i2 = new BigDecimal(s2);
|
|
|
+ if(i1.compareTo(i2)<0){
|
|
|
if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
|
|
|
.plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
|
|
|
b++;
|
|
@@ -928,22 +932,23 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
*/
|
|
|
private Constraint seriesProduce(ConstraintFactory constraintFactory){
|
|
|
return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .filter((processes) -> "铸轧".equals(processes.getProcessType()) || "冷轧".equals(processes.getProcessType()))
|
|
|
.groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
|
|
|
.filter((equipmentId,processes) -> {
|
|
|
if(processes != null && processes.size()>0){
|
|
|
- if(!processes.get(0).getProcessType().equals("铸轧") && !processes.get(0).getProcessType().equals("冷轧")){
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
}
|
|
|
- int countNum = seriesProduceCount(processes);
|
|
|
+ /*int countNum = seriesProduceCount(processes);
|
|
|
if(countNum>0){
|
|
|
return true;
|
|
|
}
|
|
|
- return false;
|
|
|
+ return false;*/
|
|
|
})
|
|
|
.penalize(HardSoftScore.ONE_SOFT,(equipmentId,processes)->{
|
|
|
int countNum = seriesProduceCount(processes);
|
|
|
- return countNum*10000;
|
|
|
+ return countNum*100;
|
|
|
})
|
|
|
.asConstraint("seriesProduce");
|
|
|
|
|
@@ -959,11 +964,14 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
// 设备占用时间参与连续生产排程
|
|
|
if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
|
|
|
for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
|
|
|
- ProductionProcesses pp = new ProductionProcesses();
|
|
|
- pp.setStartTime(equipmentRunTime.getStartRunTime());
|
|
|
- pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
- pp.setProcessType(equipmentRunTime.getProcessType());
|
|
|
- hasStartTimeProcess.add(pp);
|
|
|
+ if(equipmentRunTime.getOccupyType().equals("process")){
|
|
|
+ ProductionProcesses pp = new ProductionProcesses();
|
|
|
+ pp.setStartTime(equipmentRunTime.getStartRunTime());
|
|
|
+ pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
+ pp.setProcessType(equipmentRunTime.getProcessType());
|
|
|
+ pp.setBsProcessesId(Arrays.asList(new String[]{"haspcprocess"}));
|
|
|
+ hasStartTimeProcess.add(pp);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
// 按照开始时间排序
|
|
@@ -973,14 +981,15 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
ProductionProcesses pp = new ProductionProcesses();
|
|
|
pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
|
|
|
pp.setProcessType(equipment.getLastProcessType());
|
|
|
+ pp.setBsProcessesId(Arrays.asList(new String[]{"lastprocess"}));
|
|
|
hasStartTimeProcess.add(0,pp);
|
|
|
}
|
|
|
for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
|
|
|
if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
|
|
|
- String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
- String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
- if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ if(serspre.length == 5 && sersafter.length == 5){
|
|
|
// 合金不同或者产品类型不同则需要换辊和立板
|
|
|
if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
b = b+2;
|
|
@@ -991,11 +1000,11 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
String s1 = serspre[2];
|
|
|
String s2 = sersafter[2];
|
|
|
try{
|
|
|
- Integer i1 = Integer.parseInt(s1);
|
|
|
- Integer i2 = Integer.parseInt(s2);
|
|
|
- if(i1<i2){
|
|
|
+ BigDecimal i1 = new BigDecimal(s1);
|
|
|
+ BigDecimal i2 = new BigDecimal(s2);
|
|
|
+ if(i1.compareTo(i2)<0){
|
|
|
b = b+2;
|
|
|
- }else if(i1>i2){
|
|
|
+ }else if(i1.compareTo(i2)>0){
|
|
|
b++;
|
|
|
}
|
|
|
}catch (Exception e){
|
|
@@ -1004,19 +1013,54 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
}
|
|
|
}
|
|
|
} else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
|
|
|
- String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
|
|
|
- String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
|
|
|
- if(serspre.length == 3 && sersafter.length == 3){
|
|
|
+ String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
|
|
|
+ // 前后道所属作业ID
|
|
|
+ String processId1 = hasStartTimeProcess.get(i).getBsProcessesId().get(0);
|
|
|
+ String processId2 = hasStartTimeProcess.get(i+1).getBsProcessesId().get(0);
|
|
|
+ if(serspre.length == 5 && sersafter.length == 5){
|
|
|
if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
|
|
|
- b++;
|
|
|
+ b = b+10;
|
|
|
}else{
|
|
|
+ // 前道工序宽度、输入物料厚度、输出物料厚度
|
|
|
String s1 = serspre[2];
|
|
|
+ BigDecimal t1 = new BigDecimal(serspre[3]);
|
|
|
+ BigDecimal to1 = new BigDecimal(serspre[4]);
|
|
|
+ // 后道工序宽度、输入物料厚度、输出物料厚度
|
|
|
String s2 = sersafter[2];
|
|
|
+ BigDecimal t2 = new BigDecimal(sersafter[3]);
|
|
|
+ BigDecimal to2 = new BigDecimal(sersafter[4]);
|
|
|
try{
|
|
|
- Integer i1 = Integer.parseInt(s1);
|
|
|
- Integer i2 = Integer.parseInt(s2);
|
|
|
- if(i1<i2){
|
|
|
- b++;
|
|
|
+ BigDecimal i1 = new BigDecimal(s1);
|
|
|
+ BigDecimal i2 = new BigDecimal(s2);
|
|
|
+ // 后端工序大于前道工序,并且大于30mm
|
|
|
+ if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
|
|
|
+ b = b+6;
|
|
|
+ }
|
|
|
+ // 后端工序大于前道工序,并且小于30mm
|
|
|
+ else if(i1.compareTo(i2)<0 && (i1.add(new BigDecimal("30"))).compareTo(i2)>=0){
|
|
|
+ b = b+5;
|
|
|
+ }
|
|
|
+ // 后端工序小于前道工序
|
|
|
+ else if(i1.compareTo(i2)>0){
|
|
|
+ b = b+4;
|
|
|
+ }
|
|
|
+ // 宽度相等的情况下
|
|
|
+ else{
|
|
|
+ // 输入厚度不同
|
|
|
+ if(t1.compareTo(t2) != 0){
|
|
|
+ b = b+3;
|
|
|
+ }else{
|
|
|
+ // 输出厚度不同
|
|
|
+ if(to1.compareTo(to2) != 0){
|
|
|
+ b = b+2;
|
|
|
+ }else{
|
|
|
+ // 不属于同一作业
|
|
|
+ if(!processId1.equals(processId2)){
|
|
|
+ b = b+1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}catch (Exception e){
|
|
|
e.printStackTrace();
|
|
@@ -1037,20 +1081,20 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
private Constraint seriesProduceWashingFurnace(ConstraintFactory constraintFactory){
|
|
|
return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
.filter((process)->{
|
|
|
- return StrUtil.isNotBlank(process.getEquipmentEquassociated());
|
|
|
+ return StrUtil.isNotBlank(process.getEquipmentEquassociated()) && "铸轧".equals(process.getProcessType());
|
|
|
})
|
|
|
.groupBy(ProductionProcesses::getEquipmentEquassociated,ConstraintCollectors.toList())
|
|
|
.filter((equipmentEquassociated,processes) -> {
|
|
|
if(processes != null && processes.size()>0){
|
|
|
- if(!processes.get(0).getProcessType().equals("铸轧")){
|
|
|
- return false;
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ }else{
|
|
|
+ return false;
|
|
|
}
|
|
|
- int washingFurnaceCount = seriesProduceWashingFurnaceCount(processes);
|
|
|
+ /*int washingFurnaceCount = seriesProduceWashingFurnaceCount(processes);
|
|
|
if(washingFurnaceCount>0){
|
|
|
return true;
|
|
|
}
|
|
|
- return false;
|
|
|
+ return false;*/
|
|
|
})
|
|
|
.penalize(HardSoftScore.ONE_SOFT,(equipmentEquassociated, processess) -> {
|
|
|
int washingFurnaceCount = seriesProduceWashingFurnaceCount(processess);
|
|
@@ -1087,7 +1131,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
pp.setEndTime(equipmentRunTime.getEndRunTime());
|
|
|
pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
|
|
|
// 铸轧工序合金设置
|
|
|
- String[] hjs = equipmentRunTime.getSeriesProduceMark().split("^_^");
|
|
|
+ String[] hjs = equipmentRunTime.getSeriesProduceMark().split("\\^_\\^");
|
|
|
if(hjs.length>0){
|
|
|
pp.setVolumeMetal(hjs[0]);
|
|
|
}
|
|
@@ -1119,4 +1163,34 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
|
|
|
return notSeriesNum;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 相同作业连续生产约束
|
|
|
+ * @param constraintFactory
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Constraint sameProcessSeries(ConstraintFactory constraintFactory){
|
|
|
+ return constraintFactory.forEach(ProductionProcesses.class)
|
|
|
+ .filter((process)->{
|
|
|
+ return StrUtil.isNotBlank(process.getEquipmentId()) && StrUtil.isNotBlank(process.getProcessType())
|
|
|
+ && !"成退".equals(process.getProcessType()) && !"中退".equals(process.getProcessType());
|
|
|
+ })
|
|
|
+ .groupBy(ProductionProcesses::getEquipmentId,ConstraintCollectors.toList())
|
|
|
+ .penalize(HardSoftScore.ONE_SOFT,(equipmentId, processess) -> {
|
|
|
+ int notSeriesNum = 0;
|
|
|
+ List<ProductionProcesses> hasStartTimeProcess = processess.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
|
|
|
+ // 根据开始时间排序
|
|
|
+ Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
|
|
|
+ // 评分计算
|
|
|
+ for(int i=0;i<hasStartTimeProcess.size()-1;i++){
|
|
|
+ ProductionProcesses pre = hasStartTimeProcess.get(i);
|
|
|
+ ProductionProcesses next = hasStartTimeProcess.get(i+1);
|
|
|
+ if(!pre.getBsProcessesId().get(0).equals(next.getBsProcessesId().get(0))){
|
|
|
+ notSeriesNum++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return notSeriesNum;
|
|
|
+ })
|
|
|
+ .asConstraint("sameProcessSeries");
|
|
|
+ }
|
|
|
}
|