Explorar o código

连续生产约束优化

fangpy hai 1 ano
pai
achega
2b84adde94

+ 15 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ApsOverallConfig.java

@@ -3,6 +3,7 @@ package com.rongwei.rwapsserver.aps.domain;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -24,4 +25,18 @@ public class ApsOverallConfig {
      */
     private Map<String,Integer> roamTime;
 
+    /**
+     * 相近合金
+     */
+    private List<WashingMetal> closealloynames;
+
+    /**
+     * 洗炉时间(小时)
+     */
+    private Integer washingtime;
+    /**
+     * 立板时间(小时)
+     */
+    private Integer standingtime;
+
 }

+ 5 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/Equipment.java

@@ -103,6 +103,11 @@ public class Equipment extends Step{
      */
     private Integer lastProcessCutfinishmin;
 
+    /**
+     * 关联设备,铸轧机关联的熔炼炉
+     */
+    private String equassociated;
+
     /**
      * 设备上排产的工序
      */

+ 20 - 3
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ProductionProcesses.java

@@ -1,6 +1,7 @@
 package com.rongwei.rwapsserver.aps.domain;
 
 import cn.hutool.core.date.DateUtil;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.rongwei.rwapsserver.aps.listener.TaskStartTimeListener;
 import com.rongwei.rwapsserver.aps.util.DelayStrengthComparator;
@@ -74,6 +75,11 @@ public class ProductionProcesses extends Step{
      */
     private Equipment equipment;
 
+    /**
+     * 加工设备关联设备
+     */
+    private String equipmentEquassociated;
+
     /**
      * 延迟分钟数据(步长5分钟)
      */
@@ -154,11 +160,13 @@ public class ProductionProcesses extends Step{
     /**
      * 开始时间
      */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime startTime;
 
     /**
      * 结束时间
      */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime endTime;
 
     /**
@@ -295,7 +303,7 @@ public class ProductionProcesses extends Step{
                 return ValueRangeFactory.createIntValueRange(0, maxrange);
             }
         }
-        return ValueRangeFactory.createIntValueRange(0, 200);
+        return ValueRangeFactory.createIntValueRange(0, 50);
     }
 
     public void setOptionalProviderEquipments(List<Equipment> optionalProviderEquipments) {
@@ -324,6 +332,7 @@ public class ProductionProcesses extends Step{
             this.equipment = equipment;
             if(equipment != null){
                 this.equipmentId = equipment.getId();
+                this.equipmentEquassociated = equipment.getEquassociated();
             }
         }
     }
@@ -345,7 +354,7 @@ public class ProductionProcesses extends Step{
     }
 
     public void setStartTime(LocalDateTime startTime) {
-        if(!this.ifLock){
+//        if(!this.ifLock){
             this.startTime = startTime;
             if(startTime != null && this.getProduceTime() != null){
                 this.endTime = startTime.plusMinutes(produceTime);
@@ -361,7 +370,7 @@ public class ProductionProcesses extends Step{
 
                 }
             }*/
-        }
+//        }
     }
 
     public LocalDateTime getEndTime() {
@@ -642,6 +651,14 @@ public class ProductionProcesses extends Step{
         this.taskType = taskType;
     }
 
+    public String getEquipmentEquassociated() {
+        return equipmentEquassociated;
+    }
+
+    public void setEquipmentEquassociated(String equipmentEquassociated) {
+        this.equipmentEquassociated = equipmentEquassociated;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

+ 15 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/WashingMetal.java

@@ -0,0 +1,15 @@
+package com.rongwei.rwapsserver.aps.domain;
+
+import lombok.Data;
+
+/**
+ * 洗炉合金配置表
+ */
+@Data
+public class WashingMetal {
+
+    // 当前作业合金
+    private String processmetals;
+    // 下道作业合金
+    private String nextprocessmetals;
+}

+ 1 - 1
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/listener/TaskStartTimeListener.java

@@ -94,7 +94,7 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                     int bc = (int) Math.ceil((double) process.getProduceTime() / 20);
                     startDateTime = startDateTime.plusMinutes(process.getDelay() * bc);
                 }else{
-                    startDateTime = startDateTime.plusMinutes(process.getDelay() * 20);
+                    startDateTime = startDateTime.plusMinutes(process.getDelay() * 30);
                 }
             }
             scoreDirector.beforeVariableChanged(process, "startTime");

+ 380 - 312
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -4,10 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
-import com.rongwei.rwapsserver.aps.domain.Equipment;
-import com.rongwei.rwapsserver.aps.domain.EquipmentRunTime;
-import com.rongwei.rwapsserver.aps.domain.ProduceOrder;
-import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
+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.*;
@@ -35,6 +32,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 lzTimeLessMaxWait(constraintFactory),
                 equipmentRunTime(constraintFactory),
                 balancedEqUse(constraintFactory),
+
+                seriesProduceWashingFurnace(constraintFactory),
+                seriesProduceWashTimeWait(constraintFactory),
         };
     }
 
@@ -289,6 +289,10 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             nextProcesses.sort((o1, o2) -> o1.getNextAllProduceTime().compareTo(o2.getNextAllProduceTime()));
                             // 前道工序
                             LocalDateTime startTime = preProcess.getStartTime();
+                            if(startTime == null){
+                                System.out.println("preProcess.getId():"+preProcess.getId());
+                                System.out.println("productionProcesses.getId():"+productionProcesses.getId());
+                            }
                             LocalDateTime endTime = preProcess.getStartTime();
                             for (ProductionProcesses nextProcess : nextProcesses) {
                                 int i = preProcess.getUnitProduceTime() * nextProcess.getProducePcNum();
@@ -418,42 +422,6 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .asConstraint("equipmentRunTime");
     }
 
-    /**
-     * 退火炉等合并工序生产约束
-     * @param constraintFactory
-     * @return
-     */
-    /*private Constraint mergeProcess(ConstraintFactory constraintFactory) {
-        return constraintFactory.forEach(ProductionProcesses.class)
-                .filter(productionProcesses -> {
-                    boolean bol = false;
-                    // 退火炉特殊合并生产规则
-                    if(ApsConstants.EQUIPMENTTYPE_TUIHUOLU.equals(productionProcesses.getEquipmentType())){
-                        if(productionProcesses.getEquipment() != null && productionProcesses.getEquipment().getProcessesList() != null){
-                            // 当前工序所选设备生产中的或待生产的工序集合
-                            List<ProductionProcesses> processesList = productionProcesses.getEquipment().getProcessesList();
-                            for (ProductionProcesses processes : processesList) {
-                                // 开始时间和结束时间要么和已排产的工序一样,要么在这个范围之外
-                                if((productionProcesses.getStartTime().compareTo(processes.getStartTime())>0 && productionProcesses.getStartTime().compareTo(processes.getEndTime())<0)
-                                        || (productionProcesses.getEndTime().compareTo(processes.getStartTime())>0 && productionProcesses.getEndTime().compareTo(processes.getEndTime())<0)){
-                                    bol = true;
-                                    break;
-                                }
-                                // 开始时间结束时间在已排产的某个时间段内
-                                if(productionProcesses.getStartTime().compareTo(processes.getStartTime())>=0 && productionProcesses.getEndTime().compareTo(processes.getEndTime())<=0){
-
-                                }
-
-                            }
-                        }
-                    }
-                    return bol;
-                })
-                .penalize(HardSoftScore.ONE_HARD,(proc1)->80)
-                .asConstraint("mergeProcess");
-    }*/
-
-
     /**
      * 最大等待时间,不能小于流转时间
      * @param constraintFactory
@@ -493,171 +461,241 @@ public class ApsConstraintProvider implements ConstraintProvider {
     }
 
     /**
-     * 连续生产换辊时间考虑
+     * 连续生产洗炉时间约束
      * @param constraintFactory
      * @return
      */
-    private Constraint seriesProduceTimeWait(ConstraintFactory constraintFactory) {
+    private Constraint seriesProduceWashTimeWait(ConstraintFactory constraintFactory) {
         return constraintFactory.forEach(ProductionProcesses.class)
-                .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
-                .filter((equipmentId,processes) -> {
-                    Equipment equipment = null;
+                .filter((process)->StrUtil.isNotBlank(process.getEquipmentEquassociated()))
+                .groupBy(ProductionProcesses::getEquipmentEquassociated,ConstraintCollectors.toList())
+                .filter((equipmentEquassociated,processes) -> {
                     if(processes != null && processes.size()>0){
-                        equipment = processes.get(0).getEquipment();
+                        if(!processes.get(0).getProcessType().equals("铸轧")){
+                            return false;
+                        }
                     }
-                    List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
-                    // 设备占用时间参与连续生产排程
-                    if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
-                        for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                    int washingFurnaceCount = seriesProduceWashingTimeFurnaceCount(processes);
+                    if(washingFurnaceCount>0){
+                        return true;
+                    }
+                    return false;
+                })
+                .penalize(HardSoftScore.ONE_HARD,(equipmentEquassociated, processess) -> {
+                    int washingFurnaceCount = seriesProduceWashingTimeFurnaceCount(processess);
+                    return washingFurnaceCount*10;
+                })
+                .asConstraint("seriesProduceWashTimeWait");
+    }
+
+    /**
+     * 铸轧连续生产洗炉评分计算
+     * @param processes
+     */
+    private int seriesProduceWashingTimeFurnaceCount(List<ProductionProcesses> processes){
+        List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
+        if(hasStartTimeProcess == null || hasStartTimeProcess.size() == 0){
+            return 0;
+        }
+        // 获取所有设备,并获取设备的已排程铸轧作业占用时间段
+        List<Equipment> equipments = new ArrayList<>();
+        for (ProductionProcesses startTimeProcess : hasStartTimeProcess) {
+            if(equipments.size() == 0){
+                equipments.add(startTimeProcess.getEquipment());
+            }else{
+                List<Equipment> list = equipments.stream().filter(v -> v.getId().equals(startTimeProcess.getEquipmentId())).collect(Collectors.toList());
+                if(list == null || list.size() == 0){
+                    equipments.add(startTimeProcess.getEquipment());
+                }
+            }
+        }
+        if(equipments != null && equipments.size()>0){
+            for (Equipment equipment : equipments) {
+                if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
+                    for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                        if(equipmentRunTime.getProcessType() != null && equipmentRunTime.getProcessType().equals("铸轧") && equipmentRunTime.getSeriesProduceMark() != null){
                             ProductionProcesses pp = new ProductionProcesses();
                             pp.setStartTime(equipmentRunTime.getStartRunTime());
                             pp.setEndTime(equipmentRunTime.getEndRunTime());
                             pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
+                            // 铸轧工序合金设置
+                            String[] hjs = equipmentRunTime.getSeriesProduceMark().split("^_^");
+                            if(hjs.length>0){
+                                pp.setVolumeMetal(hjs[0]);
+                            }
                             pp.setProcessType(equipmentRunTime.getProcessType());
-                            pp.setPrepressworkmin(equipmentRunTime.getPrepressworkmin() == null ? 0 : equipmentRunTime.getPrepressworkmin());
-                            pp.setCutfinishmin(equipmentRunTime.getCutfinishmin() == null ? 0 : equipmentRunTime.getCutfinishmin());
+                            pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
                             hasStartTimeProcess.add(pp);
                         }
                     }
+                }
+            }
+        }
+        // 根据开始时间排序
+        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+        // 洗炉时间获取
+        Integer washingtime = hasStartTimeProcess.get(0).getApsOverallConfig().getWashingtime()*60;
+        int notSeriesNum = 0;
+        // 评分计算
+        for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+            List<WashingMetal> closealloynames = hasStartTimeProcess.get(i).getApsOverallConfig().getClosealloynames();
 
-                    if(hasStartTimeProcess != null && hasStartTimeProcess.size()>1){
-                        // 安装开始时间排序
-                        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
-                        // 获取设备已排程好的最后一个作业,计算连续加工
-                        if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
-                            ProductionProcesses pp = new ProductionProcesses();
-                            pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
-                            pp.setProcessType(equipment.getLastProcessType());
-                            pp.setCutfinishmin(equipment.getLastProcessCutfinishmin() == null ? 0 : equipment.getLastProcessCutfinishmin());
-                            pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
-                            hasStartTimeProcess.add(0,pp);
+            if(closealloynames != null && closealloynames.size()>0){
+                for (WashingMetal closealloyname : closealloynames) {
+                    // 当前合金和下道合金都在洗炉配置中则需要洗炉
+                    if(closealloyname.getProcessmetals().contains(hasStartTimeProcess.get(i).getVolumeMetal())
+                            && closealloyname.getNextprocessmetals().contains(hasStartTimeProcess.get(i+1).getVolumeMetal())){
+                        if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(washingtime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                            notSeriesNum++;
                         }
-                        // 临时标记
-                        Boolean a = false;
-                        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()) && "铸轧".equals(hasStartTimeProcess.get(i+1).getProcessType())){
-                                    if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
-                                        if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
-                                                .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
-                                            a = true;
-                                            break;
-                                        }
-                                    }
-                                } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType()) && "冷轧".equals(hasStartTimeProcess.get(i+1).getProcessType())) {
-                                    String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
-                                    String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
-                                    if(serspre.length == 3 && sersafter.length == 3){
-                                        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){
-                                                a = true;
-                                                break;
-                                            }
-                                        }else{
-                                            String s1 = serspre[2];
-                                            String s2 = sersafter[2];
-                                            try{
-                                                Integer i1 = Integer.parseInt(s1);
-                                                Integer i2 = Integer.parseInt(s2);
-                                                if(i1<i2 || (i1-i2)>30){
-                                                    if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
-                                                            .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
-                                                        a = true;
-                                                        break;
-                                                    }
-                                                }
-                                            }catch (Exception e){
-                                                e.printStackTrace();
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        return a;
-                    }else{
-                        return false;
+                        break;
                     }
-                })
-                .penalize(HardSoftScore.ONE_HARD,(equipmentId,processes)->{
-                    int b = 0;
-                    Equipment equipment = null;
+                }
+            }
+        }
+        return notSeriesNum;
+    }
+
+    /**
+     * 连续生产换辊、立板时间考虑
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint seriesProduceTimeWait(ConstraintFactory constraintFactory) {
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
+                .filter((equipmentId,processes) -> {
                     if(processes != null && processes.size()>0){
-                        equipment = processes.get(0).getEquipment();
-                    }
-                    List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
-                    // 设备占用时间参与连续生产排程
-                    if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
-                        for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
-                            ProductionProcesses pp = new ProductionProcesses();
-                            pp.setStartTime(equipmentRunTime.getStartRunTime());
-                            pp.setEndTime(equipmentRunTime.getEndRunTime());
-                            pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
-                            pp.setProcessType(equipmentRunTime.getProcessType());
-                            pp.setPrepressworkmin(equipmentRunTime.getPrepressworkmin() == null ? 0 : equipmentRunTime.getPrepressworkmin());
-                            pp.setCutfinishmin(equipmentRunTime.getCutfinishmin() == null ? 0 : equipmentRunTime.getCutfinishmin());
-                            hasStartTimeProcess.add(pp);
+                        if(!processes.get(0).getProcessType().equals("铸轧") && !processes.get(0).getProcessType().equals("冷轧")){
+                            return false;
                         }
                     }
-                    // 按照开始时间排序
-                    Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
-                    // 获取设备已排程好的最后一个作业,计算连续加工
-                    if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
-                        ProductionProcesses pp = new ProductionProcesses();
-                        pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
-                        pp.setProcessType(equipment.getLastProcessType());
-                        pp.setCutfinishmin(equipment.getLastProcessCutfinishmin() == null ? 0 : equipment.getLastProcessCutfinishmin());
-                        pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
-                        hasStartTimeProcess.add(0,pp);
+                    int counNum = seriesProduceTimeWaitCount(processes);
+                    if(counNum>0){
+                        return true;
                     }
-                    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())){
-                                if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
-                                    if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
-                                            .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
-                                        b++;
-                                    }
+                    return false;
+                })
+                .penalize(HardSoftScore.ONE_HARD,(equipmentId,processes)->{
+                    int counNum = seriesProduceTimeWaitCount(processes);
+                    return counNum*10;
+                })
+                .asConstraint("seriesProduceTimeWait");
+    }
+
+    /**
+     * 换辊和立板时间约束
+     * @param processes
+     * @return
+     */
+    private int seriesProduceTimeWaitCount(List<ProductionProcesses> processes){
+        int b = 0;
+        Equipment equipment = null;
+        if(processes != null && processes.size()>0){
+            equipment = processes.get(0).getEquipment();
+        }
+        List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
+        // 设备占用时间参与连续生产排程
+        if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
+            for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                ProductionProcesses pp = new ProductionProcesses();
+                pp.setStartTime(equipmentRunTime.getStartRunTime());
+                pp.setEndTime(equipmentRunTime.getEndRunTime());
+                pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
+                pp.setProcessType(equipmentRunTime.getProcessType());
+                pp.setPrepressworkmin(equipmentRunTime.getPrepressworkmin() == null ? 0 : equipmentRunTime.getPrepressworkmin());
+                pp.setCutfinishmin(equipmentRunTime.getCutfinishmin() == null ? 0 : equipmentRunTime.getCutfinishmin());
+                pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
+                hasStartTimeProcess.add(pp);
+            }
+        }
+        // 按照开始时间排序
+        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+        // 获取设备已排程好的最后一个作业,计算连续加工
+        if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
+            ProductionProcesses pp = new ProductionProcesses();
+            pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
+            pp.setProcessType(equipment.getLastProcessType());
+            pp.setCutfinishmin(equipment.getLastProcessCutfinishmin() == null ? 0 : equipment.getLastProcessCutfinishmin());
+            pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
+            pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
+            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())){
+                    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("^_^");
+                        // 换辊时长(分钟)
+                        int jgtime = hasStartTimeProcess.get(i).getCutfinishmin() + hasStartTimeProcess.get(i+1).getPrepressworkmin();
+                        // 立板时长(分钟)
+                        int standingtime = hasStartTimeProcess.get(i).getApsOverallConfig().getStandingtime()*60;
+                        // 取最大值
+                        int maxTime = jgtime;
+                        if(standingtime>jgtime){
+                            maxTime = standingtime;
+                        }
+                        if(serspre.length == 3 && sersafter.length == 3){
+                            // 合金不同则需要换辊和立板
+                            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){
+                                    b++;
                                 }
-                            } 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){
-                                    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){
+                            }else{
+                                // 合金相同情况下后面的宽度大于前面的宽度需要换辊和立板
+                                // 合金相同情况下后面的宽度小于前面的宽度需要立板
+                                // 合金相同情况下后面的宽度等于前面的宽度换辊和立板都不需要
+                                String s1 = serspre[2];
+                                String s2 = sersafter[2];
+                                try{
+                                    Integer i1 = Integer.parseInt(s1);
+                                    Integer i2 = Integer.parseInt(s2);
+                                    if(i1<i2){
+                                        if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(maxTime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
                                             b++;
                                         }
-                                    }else{
-                                        String s1 = serspre[2];
-                                        String s2 = sersafter[2];
-                                        try{
-                                            Integer i1 = Integer.parseInt(s1);
-                                            Integer i2 = Integer.parseInt(s2);
-                                            if(i1<i2 || (i1-i2)>30){
-                                                if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
-                                                        .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
-                                                    b++;
-                                                }
-                                            }
-                                        }catch (Exception e){
-                                            e.printStackTrace();
+                                    }else if(i1>i2){
+                                        if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(standingtime).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                                            b++;
                                         }
                                     }
+                                }catch (Exception e){
+                                    e.printStackTrace();
                                 }
                             }
                         }
                     }
-                    /*if("0001be252874536843730b100020".equals(equipmentId)){
-                        System.out.println("******得分:"+b);
-                    }*/
-                    if(b>0){
-                        return b*10;
+                } 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){
+                        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){
+                                b++;
+                            }
+                        }else{
+                            String s1 = serspre[2];
+                            String s2 = sersafter[2];
+                            try{
+                                Integer i1 = Integer.parseInt(s1);
+                                Integer i2 = Integer.parseInt(s2);
+                                if(i1<i2){
+                                    if(hasStartTimeProcess.get(i).getEndTime().plusMinutes(hasStartTimeProcess.get(i).getCutfinishmin())
+                                            .plusMinutes(hasStartTimeProcess.get(i+1).getPrepressworkmin()).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                                        b++;
+                                    }
+                                }
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
                     }
-                    return 10;
-                })
-                .asConstraint("seriesProduceTimeWait");
+                }
+            }
+        }
+        return b;
     }
 
     /**
@@ -669,8 +707,6 @@ public class ApsConstraintProvider implements ConstraintProvider {
         return constraintFactory.forEach(ProductionProcesses.class)
                 .join(ProductionProcesses.class,Joiners.equal(ProductionProcesses::getEquipmentId))
                 .filter((proc1,proc2)->{
-//                    System.out.println("proc1-EquipmentId:"+proc1.getEquipmentId());
-//                    System.out.println("proc2-EquipmentId:"+proc2.getEquipmentId());
                     if(proc1.getId() == proc2.getId() ||
                             (StrUtil.isNotBlank(proc1.getMergeProcessMark()) && StrUtil.isNotBlank(proc2.getMergeProcessMark()) && proc1.getMergeProcessMark().equals(proc2.getMergeProcessMark()))){
                         return false;
@@ -698,6 +734,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                         获取最后一步工步的结束时间(最后一步工步的结束时间即此产品生产的实际结束时间)
                         并且获取结束时间大于生产订单的交货日期
                      */
+                    if(productionProcesses.getEndTime() == null || productionProcesses.getNextProcesses() == null){
+                        return false;
+                    }
                     // 取最小订单交货日期
                     Date deliveryMinDate = null;
                     for (ProduceOrder produceOrder : productionProcesses.getProduceOrder()) {
@@ -709,9 +748,6 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             }
                         }
                     }
-                    if(productionProcesses.getEndTime() == null){
-                        return false;
-                    }
                     Boolean bol = productionProcesses.getNextProcesses() == null &&
                             productionProcesses.getEndTime().atZone(zoneId).toInstant().toEpochMilli()>deliveryMinDate.getTime();
                     return bol;
@@ -814,32 +850,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
         return balanceNum;
     }
 
-    /**
-     * 合并生产工序,订单合并、尽量保证单次生产设备最大量
-     * @param constraintFactory
-     * @return
-     */
-    /*private Constraint mergeProcess(ConstraintFactory constraintFactory){
-        return constraintFactory.forEach(ProductionProcesses.class)
-                .join(ProductionProcesses.class,Joiners.equal(ProductionProcesses::getEquipmentId))
-                .filter((proc1,proc2)->{
-                    if(proc1.getId() != proc2.getId() &&
-                            (StrUtil.isNotBlank(proc1.getMergeProcessMark()) && StrUtil.isNotBlank(proc2.getMergeProcessMark()) && proc1.getMergeProcessMark().equals(proc2.getMergeProcessMark()))){
-                        if(proc1.getStartTime().compareTo(proc2.getStartTime()) == 0 && proc1.getEndTime().compareTo(proc2.getEndTime()) == 0){
-                            return false;
-                        }else{
-                            return true;
-                        }
-                    }else{
-                        return false;
-                    }
-                })
-                .penalize(HardSoftScore.ONE_SOFT,(proc1,proc2)->50)
-                .asConstraint("mergeProcess");
-    }*/
-
     /**
      * 连续生产约束条件,同一设备的连续生产标识一样的工序、尽量排在一起
+     * 铸轧考虑换辊和立板
      * @param constraintFactory
      * @return
      */
@@ -847,138 +860,193 @@ public class ApsConstraintProvider implements ConstraintProvider {
         return constraintFactory.forEach(ProductionProcesses.class)
                 .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
                 .filter((equipmentId,processes) -> {
-                    Equipment equipment = null;
                     if(processes != null && processes.size()>0){
-                        equipment = processes.get(0).getEquipment();
                         if(!processes.get(0).getProcessType().equals("铸轧") && !processes.get(0).getProcessType().equals("冷轧")){
                             return false;
                         }
                     }
-                    List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
-                    // 设备占用时间参与连续生产排程
-                    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);
-                        }
+                    int countNum = seriesProduceCount(processes);
+                    if(countNum>0){
+                        return true;
                     }
+                    return false;
+                })
+                .penalize(HardSoftScore.ONE_SOFT,(equipmentId,processes)->{
+                    int countNum = seriesProduceCount(processes);
+                    return countNum*10000;
+                })
+                .asConstraint("seriesProduce");
 
-                    if(hasStartTimeProcess != null && hasStartTimeProcess.size()>1){
-                        // 安装开始时间排序
-                        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
-                        // 获取设备已排程好的最后一个作业,计算连续加工
-                        if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
-                            ProductionProcesses pp = new ProductionProcesses();
-                            pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
-                            pp.setProcessType(equipment.getLastProcessType());
-                            hasStartTimeProcess.add(0,pp);
+    }
+
+    private int seriesProduceCount(List<ProductionProcesses> processes){
+        int b = 0;
+        Equipment equipment = null;
+        if(processes != null && processes.size()>0){
+            equipment = processes.get(0).getEquipment();
+        }
+        List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
+        // 设备占用时间参与连续生产排程
+        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);
+            }
+        }
+        // 按照开始时间排序
+        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+        // 获取设备已排程好的最后一个作业,计算连续加工
+        if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
+            ProductionProcesses pp = new ProductionProcesses();
+            pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
+            pp.setProcessType(equipment.getLastProcessType());
+            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){
+                        // 合金不同或者产品类型不同则需要换辊和立板
+                        if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
+                            b = b+2;
+                        }else{
+                            // 合金相同情况下后面的宽度大于前面的宽度需要换辊和立板
+                            // 合金相同情况下后面的宽度小于前面的宽度需要立板
+                            // 合金相同情况下后面的宽度等于前面的宽度换辊和立板都不需要
+                            String s1 = serspre[2];
+                            String s2 = sersafter[2];
+                            try{
+                                Integer i1 = Integer.parseInt(s1);
+                                Integer i2 = Integer.parseInt(s2);
+                                if(i1<i2){
+                                    b = b+2;
+                                }else if(i1>i2){
+                                    b++;
+                                }
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
                         }
-                        // 临时标记
-                        Boolean a = false;
-                        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()) && "铸轧".equals(hasStartTimeProcess.get(i+1).getProcessType())){
-                                    if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
-                                        a = true;
-                                        break;
-                                    }
-                                } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType()) && "冷轧".equals(hasStartTimeProcess.get(i+1).getProcessType())) {
-                                    String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("^_^");
-                                    String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("^_^");
-                                    if(serspre.length == 3 && sersafter.length == 3){
-                                        if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
-                                            a = true;
-                                            break;
-                                        }else{
-                                            String s1 = serspre[2];
-                                            String s2 = sersafter[2];
-                                            try{
-                                                Integer i1 = Integer.parseInt(s1);
-                                                Integer i2 = Integer.parseInt(s2);
-                                                if(i1<i2){
-                                                    a = true;
-                                                    break;
-                                                }
-                                            }catch (Exception e){
-                                                e.printStackTrace();
-                                            }
-                                        }
-                                    }
+                    }
+                } 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){
+                        if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
+                            b++;
+                        }else{
+                            String s1 = serspre[2];
+                            String s2 = sersafter[2];
+                            try{
+                                Integer i1 = Integer.parseInt(s1);
+                                Integer i2 = Integer.parseInt(s2);
+                                if(i1<i2){
+                                    b++;
                                 }
+                            }catch (Exception e){
+                                e.printStackTrace();
                             }
                         }
-                        return a;
-                    }else{
-                        return false;
                     }
+                }
+            }
+        }
+        return b;
+    }
+
+    /**
+     * 铸轧连续生产洗炉约束
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint seriesProduceWashingFurnace(ConstraintFactory constraintFactory){
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter((process)->{
+                    return StrUtil.isNotBlank(process.getEquipmentEquassociated());
                 })
-                .penalize(HardSoftScore.ONE_SOFT,(equipmentId,processes)->{
-                    int b = 0;
-                    Equipment equipment = null;
+                .groupBy(ProductionProcesses::getEquipmentEquassociated,ConstraintCollectors.toList())
+                .filter((equipmentEquassociated,processes) -> {
                     if(processes != null && processes.size()>0){
-                        equipment = processes.get(0).getEquipment();
+                        if(!processes.get(0).getProcessType().equals("铸轧")){
+                            return false;
+                        }
+                    }
+                    int washingFurnaceCount = seriesProduceWashingFurnaceCount(processes);
+                    if(washingFurnaceCount>0){
+                        return true;
                     }
-                    List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
-                    // 设备占用时间参与连续生产排程
-                    if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
-                        for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                    return false;
+                })
+                .penalize(HardSoftScore.ONE_SOFT,(equipmentEquassociated, processess) -> {
+                    int washingFurnaceCount = seriesProduceWashingFurnaceCount(processess);
+                    return washingFurnaceCount*10000;
+                })
+                .asConstraint("seriesProduceWashingFurnace");
+    }
+
+    /**
+     * 铸轧连续生产洗炉评分计算
+     * @param processes
+     */
+    private int seriesProduceWashingFurnaceCount(List<ProductionProcesses> processes){
+        List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
+        // 获取所有设备,并获取设备的已排程铸轧作业占用时间段
+        List<Equipment> equipments = new ArrayList<>();
+        for (ProductionProcesses startTimeProcess : hasStartTimeProcess) {
+            if(equipments.size() == 0){
+                equipments.add(startTimeProcess.getEquipment());
+            }else{
+                List<Equipment> list = equipments.stream().filter(v -> v.getId().equals(startTimeProcess.getEquipmentId())).collect(Collectors.toList());
+                if(list == null || list.size() == 0){
+                    equipments.add(startTimeProcess.getEquipment());
+                }
+            }
+        }
+        if(equipments != null && equipments.size()>0){
+            for (Equipment equipment : equipments) {
+                if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
+                    for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                        if(equipmentRunTime.getProcessType() != null && equipmentRunTime.getProcessType().equals("铸轧") && equipmentRunTime.getSeriesProduceMark() != null){
                             ProductionProcesses pp = new ProductionProcesses();
                             pp.setStartTime(equipmentRunTime.getStartRunTime());
+                            pp.setEndTime(equipmentRunTime.getEndRunTime());
                             pp.setSeriesProduceMark(equipmentRunTime.getSeriesProduceMark());
+                            // 铸轧工序合金设置
+                            String[] hjs = equipmentRunTime.getSeriesProduceMark().split("^_^");
+                            if(hjs.length>0){
+                                pp.setVolumeMetal(hjs[0]);
+                            }
                             pp.setProcessType(equipmentRunTime.getProcessType());
+                            pp.setApsOverallConfig(hasStartTimeProcess.get(0).getApsOverallConfig());
                             hasStartTimeProcess.add(pp);
                         }
                     }
-                    // 按照开始时间排序
-                    Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
-                    // 获取设备已排程好的最后一个作业,计算连续加工
-                    if(equipment.getLastProcessType() != null && equipment.getLastSeriesProduceMark() != null){
-                        ProductionProcesses pp = new ProductionProcesses();
-                        pp.setSeriesProduceMark(equipment.getLastSeriesProduceMark());
-                        pp.setProcessType(equipment.getLastProcessType());
-                        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())){
-                                if(!hasStartTimeProcess.get(i).getSeriesProduceMark().equals(hasStartTimeProcess.get(i+1).getSeriesProduceMark())){
-                                    b++;
-                                }
-                            } 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){
-                                    if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
-                                        b++;
-                                    }else{
-                                        String s1 = serspre[2];
-                                        String s2 = sersafter[2];
-                                        try{
-                                            Integer i1 = Integer.parseInt(s1);
-                                            Integer i2 = Integer.parseInt(s2);
-                                            if(i1<i2){
-                                                b++;
-                                            }
-                                        }catch (Exception e){
-                                            e.printStackTrace();
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    /*if("0001be252874536843730b100020".equals(equipmentId)){
-                        System.out.println("******得分:"+b);
-                    }*/
-                    if(b>0){
-                        return b;
+                }
+            }
+        }
+        // 根据开始时间排序
+        Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+        int notSeriesNum = 0;
+        // 评分计算
+        for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+            List<WashingMetal> closealloynames = hasStartTimeProcess.get(i).getApsOverallConfig().getClosealloynames();
+            if(closealloynames != null && closealloynames.size()>0){
+                for (WashingMetal closealloyname : closealloynames) {
+                    // 当前合金和下道合金都在洗炉配置中则需要洗炉
+                    if(closealloyname.getProcessmetals().contains(hasStartTimeProcess.get(i).getVolumeMetal())
+                            && closealloyname.getNextprocessmetals().contains(hasStartTimeProcess.get(i+1).getVolumeMetal())){
+                        notSeriesNum++;
+                        break;
                     }
-                    return 1;
-                })
-                .asConstraint("seriesProduce");
+                }
+            }
+        }
 
+        return notSeriesNum;
     }
 }

+ 5 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/service/impl/ProductionScheduleServiceImpl.java

@@ -183,6 +183,9 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         apsOverallConfig.setStartTime(startTime);
         // 排程全局配置
         apsOverallConfig.setRoamTime(productionScheduleVo.getRoamTime());
+        apsOverallConfig.setWashingtime(productionScheduleVo.getWashingtime());
+        apsOverallConfig.setStandingtime(productionScheduleVo.getStandingtime());
+        apsOverallConfig.setClosealloynames(productionScheduleVo.getClosealloynames());
         unsolvedCloudBalance.setStartTime(startTime);
 
         // 根据前道、后道工序ID,转换为前道、后道工序对象
@@ -259,8 +262,10 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
             }
             // 锁定工序处理
             if(process.getIfLock()){
+                process.setIfLock(false);
                 // 锁定工序的设备即可选设备
                 process.setEquipment(process.getOptionalProviderEquipments().get(0));
+                process.setIfLock(true);
             }
         }
         // 设备列表初始化

+ 15 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/vo/ProductionScheduleVo.java

@@ -3,6 +3,7 @@ package com.rongwei.rwapsserver.aps.vo;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.rongwei.rwapsserver.aps.domain.Equipment;
 import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
+import com.rongwei.rwapsserver.aps.domain.WashingMetal;
 import lombok.Data;
 import java.util.Date;
 import java.util.List;
@@ -43,4 +44,18 @@ public class ProductionScheduleVo {
 
     private Integer environmentMode;
 
+    /**
+     * 洗炉合金
+     */
+    private List<WashingMetal> closealloynames;
+
+    /**
+     * 洗炉时间(小时)
+     */
+    private Integer washingtime;
+    /**
+     * 立板时间(小时)
+     */
+    private Integer standingtime;
+
 }