ソースを参照

APS平台新模型调优

fangpy 1 年間 前
コミット
ea433ddc48

+ 9 - 1
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/ApsBalancingApplication.java

@@ -80,7 +80,15 @@ public class ApsBalancingApplication {
         System.out.println(allRunTimes);
         allRunTimes.sort(Comparator.comparing(EquipmentRunTime::getStartRunTime));
         System.out.println(allRunTimes);*/
-        System.out.println(1280/100);
+//        System.out.println(1280/100);
+
+        ProductionProcesses a = new ProductionProcesses();
+        a.setProduceTime(20);
+        a.setStartTime(LocalDateTime.now());
+        LocalDateTime endTime = a.getStartTime();
+        System.out.println(a.getStartTime());
+        endTime = endTime.plusMinutes(10);
+        System.out.println(a.getStartTime());
     }
 
     public static void testAps(){

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

@@ -6,6 +6,7 @@ import lombok.NoArgsConstructor;
 import org.optaplanner.core.api.domain.entity.PlanningEntity;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -92,6 +93,16 @@ public class Equipment extends Step{
      */
     private String lastProcessType;
 
+    /**
+     * 当前设备最后工序结束时间
+     */
+    private Date lastProcessEndTime;
+
+    /**
+     * 当前设备最后工序的下机收尾时间
+     */
+    private Integer lastProcessCutfinishmin;
+
     /**
      * 设备上排产的工序
      */

+ 9 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/EquipmentRunTime.java

@@ -33,4 +33,13 @@ public class EquipmentRunTime {
      */
     private String processType;
 
+    /**
+     * 上机准备时间(单位:分钟)
+     */
+    private Integer prepressworkmin;
+    /**
+     * 下机收尾时间(单位:分钟)
+     */
+    private Integer cutfinishmin;
+
 }

+ 26 - 1
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ProductionProcesses.java

@@ -231,6 +231,15 @@ public class ProductionProcesses extends Step{
      */
     private String conflictDes;
 
+    /**
+     * 上机准备时间(单位:分钟)
+     */
+    private Integer prepressworkmin;
+    /**
+     * 下机收尾时间(单位:分钟)
+     */
+    private Integer cutfinishmin;
+
     public String getEquipmentType() {
         return equipmentType;
     }
@@ -333,7 +342,7 @@ public class ProductionProcesses extends Step{
     public void setStartTime(LocalDateTime startTime) {
         if(!this.ifLock){
             this.startTime = startTime;
-            if(startTime != null){
+            if(startTime != null && this.getProduceTime() != null){
                 this.endTime = startTime.plusMinutes(produceTime);
             }
             // 零件更换时间,查询设备已运行时间,以及最后一道工序的参数
@@ -604,6 +613,22 @@ public class ProductionProcesses extends Step{
         this.softconflictdes = softconflictdes;
     }
 
+    public Integer getPrepressworkmin() {
+        return prepressworkmin;
+    }
+
+    public void setPrepressworkmin(Integer prepressworkmin) {
+        this.prepressworkmin = prepressworkmin;
+    }
+
+    public Integer getCutfinishmin() {
+        return cutfinishmin;
+    }
+
+    public void setCutfinishmin(Integer cutfinishmin) {
+        this.cutfinishmin = cutfinishmin;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

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

@@ -1,15 +1,20 @@
 package com.rongwei.rwapsserver.aps.listener;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
 import com.rongwei.rwapsserver.aps.domain.ApsSolution;
+import com.rongwei.rwapsserver.aps.domain.Equipment;
 import com.rongwei.rwapsserver.aps.domain.EquipmentRunTime;
 import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
 import lombok.extern.slf4j.Slf4j;
 import org.optaplanner.core.api.domain.variable.VariableListener;
 import org.optaplanner.core.api.score.director.ScoreDirector;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 设备赋值后任务起止时间自动计算
@@ -217,6 +222,8 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                 System.out.println("process.getId():"+process.getId()+";process.getEquipment().getId():"+process.getEquipment().getId()+";process.getDelay():"+process.getDelay());
                 process.getId();
             }*/
+            // 获取所有规划实体对象数据
+            ApsSolution workingSolution = scoreDirector.getWorkingSolution();
             // 最大单批次生产时间
             Integer maxUnitProduceTime = 0;
             // 最大流转时间
@@ -268,7 +275,8 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                         }
                     }
                     // 对比设备已运行时间(包括排程中添加的作业)来修正时间
-                    LocalDateTime proStartTime = lastMaxStartTime;
+                    LocalDateTime proStartTime = seriesWaitTime(workingSolution,process,lastMaxStartTime);
+
                     LocalDateTime proEndTime = proStartTime.plusMinutes(process.getProduceTime());
                     List<EquipmentRunTime> equipmentRunTimes = process.getEquipment().getEquipmentRunTimes();
                     List<EquipmentRunTime> allRunTimes = new ArrayList<>();
@@ -369,7 +377,7 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                             process.setEndTime(endTime.plusMinutes(lzTimes).plusMinutes(process.getUnitProduceTime()));
                         }
                         // 对比设备已运行时间(包括排程中添加的作业)来修正时间
-                        LocalDateTime proStartTime = lastStartTime;
+                        LocalDateTime proStartTime = seriesWaitTime(workingSolution,process,lastStartTime);
                         LocalDateTime proEndTime = process.getEndTime();
                         List<EquipmentRunTime> equipmentRunTimes = process.getEquipment().getEquipmentRunTimes();
                         List<EquipmentRunTime> allRunTimes = new ArrayList<>();
@@ -470,4 +478,99 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
         }
     }
 
+    /**
+     * 检查非连续生产的情况下,是否考虑了换辊时间,并且同步处理一定程度的相同设备不同工序时间交叉问题
+     * @param workingSolution
+     * @param process
+     * @param proStartTime
+     */
+    private LocalDateTime seriesWaitTime(ApsSolution workingSolution,ProductionProcesses process,LocalDateTime proStartTime){
+        LocalDateTime retTime = proStartTime;
+        /*List<ProductionProcesses> allProcessesList = workingSolution.getProcessesList();
+        if(process.getEquipment() != null){
+            Equipment pe = process.getEquipment();
+            // 过滤同一设备存在开始时间不是当前工序的其它所有工序
+            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());
+            }).collect(Collectors.toList());
+            List<ProductionProcesses> testpro = allProcessesList.stream().filter(v -> v.getId().equals("1a6ac824edaa460cab58a02c0fd1375a")).collect(Collectors.toList());
+            if(process.getId().equals("e4bce883655d49488067d78bd27d0e57") && process.getDelay() == 184){
+                System.out.println("*******************************");
+                System.out.println(testpro.get(0).getStartTime());
+            }
+            // 获取当前工序所在设备的上一道最近的工序
+            LocalDateTime lastStartTime = null;
+            ProductionProcesses lastProductProcesses = null;
+            for (ProductionProcesses productionProcesses : filterProcess) {
+                if(productionProcesses.getStartTime().compareTo(proStartTime)<=0){
+                    if(lastStartTime == null){
+                        lastStartTime = productionProcesses.getStartTime();
+                        lastProductProcesses = productionProcesses;
+                    }else{
+                        if(productionProcesses.getStartTime().compareTo(lastStartTime)>0){
+                            lastStartTime = productionProcesses.getStartTime();
+                            lastProductProcesses = productionProcesses;
+                        }
+                    }
+                }
+            }
+            // 前道工序不存在时判断历史最后一道工序
+            if(lastProductProcesses == null){
+                if(StrUtil.isNotBlank(pe.getLastProcessType()) && StrUtil.isNotBlank(pe.getLastSeriesProduceMark()) && pe.getLastProcessEndTime() != null){
+                    ProductionProcesses lp = new ProductionProcesses();
+                    lp.setSeriesProduceMark(pe.getLastSeriesProduceMark());
+                    lp.setEndTime(pe.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
+                    lp.setProcessType(pe.getLastProcessType());
+                    lastProductProcesses = lp;
+                }
+            }
+
+            // 计算换辊时间
+            if(lastProductProcesses != null){
+                // 同设备上道工序的结束时间
+                LocalDateTime endTime = lastProductProcesses.getEndTime();
+                // 判断当前工序和上道工序是否连续
+                Boolean isSeries = true;
+                if("铸轧".equals(process.getProcessType())){
+                    if(!lastProductProcesses.getSeriesProduceMark().equals(process.getSeriesProduceMark())){
+                        isSeries = false;
+                    }
+                } else if ("冷轧".equals(process.getProcessType())) {
+                    String[] serspre = lastProductProcesses.getSeriesProduceMark().split("^_^");
+                    String[] sersafter = process.getSeriesProduceMark().split("^_^");
+                    if(serspre.length == 3 && sersafter.length == 3){
+                        if(!serspre[0].equals(sersafter[0]) || !serspre[1].equals(sersafter[1])){
+                            isSeries = false;
+                        }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){
+                                    isSeries = false;
+                                }
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+                // 非连续加工需要考虑换辊时间
+                if(!isSeries){
+                    endTime = endTime.plusMinutes(lastProductProcesses.getCutfinishmin()).plusMinutes(process.getPrepressworkmin());
+                }
+                // 当前工序开始时间要小于同设备上道工序结束时间
+                if(proStartTime.compareTo(endTime)<0){
+                    retTime = endTime.plusMinutes(1);
+                }
+            }
+            if(process.getId().equals("e4bce883655d49488067d78bd27d0e57") && process.getDelay() == 184){
+                System.out.println(testpro.get(0).getStartTime());
+                System.out.println("*******************************");
+            }
+        }*/
+        return retTime;
+    }
+
 }

+ 171 - 2
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -30,6 +30,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 eqTimeCross(constraintFactory),
                 deliveryDate(constraintFactory),
                 seriesProduce(constraintFactory),
+                seriesProduceTimeWait(constraintFactory),
                 lzTimeLessMaxWait(constraintFactory),
                 equipmentRunTime(constraintFactory),
                 balancedEqUse(constraintFactory),
@@ -493,6 +494,174 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .asConstraint("lzTimeLessMaxWait");
     }
 
+    /**
+     * 连续生产换辊时间考虑
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint seriesProduceTimeWait(ConstraintFactory constraintFactory) {
+        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();
+                    }
+                    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());
+                            pp.setCutfinishmin(equipmentRunTime.getCutfinishmin());
+                            hasStartTimeProcess.add(pp);
+                        }
+                    }
+
+                    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());
+                            pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
+                            hasStartTimeProcess.add(0,pp);
+                        }
+                        // 临时标记
+                        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;
+                    }
+                })
+                .penalize(HardSoftScore.ONE_HARD,(equipmentId,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());
+                            pp.setCutfinishmin(equipmentRunTime.getCutfinishmin());
+                            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());
+                        pp.setEndTime(equipment.getLastProcessEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
+                        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())){
+                                    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 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 || (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();
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    /*if("0001be252874536843730b100020".equals(equipmentId)){
+                        System.out.println("******得分:"+b);
+                    }*/
+                    if(b>0){
+                        return b*10;
+                    }
+                    return 10;
+                })
+                .asConstraint("seriesProduceTimeWait");
+    }
+
     /**
      * 硬约束:同一个设备的不同的工步运行时间不能有交叉
      * @param constraintFactory
@@ -610,7 +779,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                     Equipment equipment = null;
                     if(processes != null && processes.size()>0){
                         equipment = processes.get(0).getEquipment();
-                        List<ProductionProcesses> plist = new ArrayList<>();
+                        /*List<ProductionProcesses> plist = new ArrayList<>();
                         for (ProductionProcesses process : processes) {
                             ProductionProcesses pro = new ProductionProcesses();
                             pro.setId(process.getId());
@@ -620,7 +789,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             pro.setEndTime(process.getEndTime());
                             plist.add(pro);
                         }
-                        equipment.setProcessesList(plist);
+                        equipment.setProcessesList(plist);*/
                     }
                     List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
                     // 设备占用时间参与连续生产排程

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

@@ -243,6 +243,13 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 }
                 process.setOptionalProviderEquipments(providedEq);
             }
+            // 上机时间和下机时间如果为null,设置为0
+            if(process.getPrepressworkmin() == null){
+                process.setPrepressworkmin(0);
+            }
+            if(process.getCutfinishmin() == null){
+                process.setCutfinishmin(0);
+            }
         }
         // 设备列表初始化
         unsolvedCloudBalance.setEquipmentList(productionScheduleVo.getEquipmentList());

+ 2 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/util/ApsConstants.java

@@ -20,6 +20,7 @@ public class ApsConstants {
         constraintDesc.put("equipmentRunTime","设备已排产时间段不可排产其它工序作业");
         constraintDesc.put("lzTimeLessMaxWait","上一工序作业流转时间不能大于上一工序作业最大等待时间");
         constraintDesc.put("eqTimeCross","排程过程中出现相同设备排产时间段有交叉");
+        constraintDesc.put("seriesProduceTimeWait","非连续生产时间差不满足上机准备时间和下机收尾时间");
         constraintDesc.put("deliveryDate","订单交货期不满足");
         constraintDesc.put("seriesProduce","订单的连续生产要求不满足");
 
@@ -29,6 +30,7 @@ public class ApsConstants {
         hardConstraint.add("equipmentRunTime");
         hardConstraint.add("lzTimeLessMaxWait");
         hardConstraint.add("eqTimeCross");
+        hardConstraint.add("seriesProduceTimeWait");
     }
 
 }