فهرست منبع

排程算法优化

fangpy 1 سال پیش
والد
کامیت
9dfad1e097

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

@@ -142,9 +142,7 @@ public class ApsBalancingApplication {
         /*BigDecimal a = new BigDecimal("516.78");
         System.out.println(a.intValue());*/
 
-        System.out.println( 5 % 3);
-        System.out.println( 5 / 3);
-        System.out.println( 5 * 3);
+        System.out.println(new BigDecimal(40).divide(new BigDecimal(10.9), 2, RoundingMode.HALF_UP).intValue());
     }
 
     public static void constraintTest(){

+ 13 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/domain/ProductionProcesses.java

@@ -54,6 +54,11 @@ public class ProductionProcesses implements Serializable {
         this.produceTime = produceTime;
     }
 
+    /**
+     * 排程状态:CH:初始化阶段,LS:localSearch阶段
+     */
+    private String apsStatus;
+
     private String orderId;
 
     /**
@@ -791,6 +796,14 @@ public class ProductionProcesses implements Serializable {
         this.producttype = producttype;
     }
 
+    public String getApsStatus() {
+        return apsStatus;
+    }
+
+    public void setApsStatus(String apsStatus) {
+        this.apsStatus = apsStatus;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

+ 218 - 137
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -25,10 +25,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
     @Override
     public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
         return new Constraint[]{
-//                eqTypeSame(constraintFactory),
-//                noPreGbAfterNow(constraintFactory),
-//                lzTimeLessMaxWait(constraintFactory),
-
+                // HARD
                 hasOnePreGbAfterNow(constraintFactory),
                 eqTimeCross(constraintFactory),
                 seriesProduceTimeWait(constraintFactory),
@@ -36,7 +33,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 equipmentRunTime(constraintFactory),
                 eqTimeCrossTuihuo(constraintFactory),
                 eqTimeCrossMinTuihuo(constraintFactory),
-
+                // MEDIUM
                 deliveryDate(constraintFactory),
                 seriesProduce(constraintFactory),
                 seriesProduceWashingFurnace(constraintFactory),
@@ -47,11 +44,10 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 processBtNear(constraintFactory),
                 seriesZzLb(constraintFactory),
 
-
-//                sameProcessSeries(constraintFactory),
+                beforeThClose(constraintFactory),
+                // SOFT
                 processNear(constraintFactory),
                 eqTimeCrossMinTuihuoSoft(constraintFactory),
-                //                balancedEqUse(constraintFactory),
         };
     }
 
@@ -151,7 +147,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                         }
                     }
                     if(productionProcesses.getMaxWaitTime() != null && productionProcesses.getMaxWaitTime()>0
-                            || (productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().size()>0 && "成退,中退,小卷成退".contains(productionProcesses.getNextProcesses().get(0).getProcessType()))){
+                            && (productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().get(0).getIfLock() && productionProcesses.getNextProcesses().size()>0 && "成退,中退,小卷成退".contains(productionProcesses.getNextProcesses().get(0).getProcessType()))){
                         if(productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().size()>0){
                             for (ProductionProcesses nextProcess : productionProcesses.getNextProcesses()) {
                                 if(nextProcess.getEquipment() != null && nextProcess.getStartTime() != null){
@@ -567,6 +563,55 @@ public class ApsConstraintProvider implements ConstraintProvider {
         return b;
     }
 
+    /**
+     * 退火前一道工序尽量靠近
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint beforeThClose(ConstraintFactory constraintFactory) {
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter((processe) -> {
+                    boolean a = false;
+                    if(processe.getStartTime() != null){
+                        List<ProductionProcesses> nextProcesses = processe.getNextProcesses();
+                        if(nextProcesses != null && nextProcesses.size()>0){
+                            for (ProductionProcesses nextProcess : nextProcesses) {
+                                if("成退".equals(nextProcess.getProcessType()) || "中退".equals(nextProcess.getProcessType()) || "小卷成退".equals(nextProcess.getProcessType())){
+                                    a = true;
+                                }
+                            }
+                        }
+                    }
+                    return a;
+                })
+                .groupBy(ProductionProcesses::getUniqueBsProcessesId, ConstraintCollectors.toList())
+                .filter((bsProcessesId,processes) -> {
+                    if(processes != null && processes.size()>1){
+                        return true;
+                    }
+                    return false;
+                })
+                .penalize(HardMediumSoftScore.ONE_MEDIUM,(bsProcessesId,processes)->{
+                    long counNum = 0;
+                    List<ProductionProcesses> hasStartTimeProcess = processes.stream().filter(v -> v.getStartTime() != null).collect(Collectors.toList());
+                    // 按照开始时间排序
+                    Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+                    if(hasStartTimeProcess.size()>1){
+                        for (int i = 0; i < hasStartTimeProcess.size()-1; i++) {
+                            ProductionProcesses processes1 = hasStartTimeProcess.get(i);
+                            ProductionProcesses processes2 = hasStartTimeProcess.get(i+1);
+                            long minutesDiff = ChronoUnit.MINUTES.between(processes1.getStartTime(), processes2.getStartTime());
+                            if(minutesDiff<0){
+                                int a = 1;
+                            }
+                            counNum = counNum + minutesDiff;
+                        }
+                    }
+                    return (int)counNum;
+                })
+                .asConstraint("beforeThClose");
+    }
+
     /**
      * 换辊和立板时间约束
      * @param processes
@@ -1119,6 +1164,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
             if(v.size()>3){
                 int a = 1;
             }
+            if(v.size()>2){
+                int a = 1;
+            }
             BigDecimal totalWidth = new BigDecimal("0");
             BigDecimal totalWeight = new BigDecimal("0");
             Set<String> metalSet = new HashSet<>();
@@ -1412,160 +1460,165 @@ public class ApsConstraintProvider implements ConstraintProvider {
             int abc = 1;
         }*/
         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()) {
-                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"}));
-                    pp.setConflictRoptions(new HashMap<>());
-                    hasStartTimeProcess.add(pp);
+        if(hasStartTimeProcess != null && hasStartTimeProcess.size()>0){
+            if(hasStartTimeProcess.get(0).getApsStatus().equals("CH") && hasStartTimeProcess.get(0).getProcessType().equals("冷轧")){
+                return b;
+            }
+            // 设备占用时间参与连续生产排程
+            if(equipment != null && equipment.getEquipmentRunTimes() != null && equipment.getEquipmentRunTimes().size()>0){
+                for (EquipmentRunTime equipmentRunTime : equipment.getEquipmentRunTimes()) {
+                    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"}));
+                        pp.setConflictRoptions(new HashMap<>());
+                        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.setBsProcessesId(Arrays.asList(new String[]{"lastprocess"}));
-            pp.setConflictRoptions(new HashMap<>());
-            hasStartTimeProcess.add(0,pp);
-        }else{
-            b = b+2;
-        }
-        for(int i=0;i<hasStartTimeProcess.size()-1;i++){
-            if(hasStartTimeProcess.get(i).getId() == null && hasStartTimeProcess.get(i+1).getId() == null){
-                continue;
+            // 按照开始时间排序
+            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.setBsProcessesId(Arrays.asList(new String[]{"lastprocess"}));
+                pp.setConflictRoptions(new HashMap<>());
+                hasStartTimeProcess.add(0,pp);
+            }else{
+                b = b+2;
             }
-            if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
-                Map<String, String> conflictRoptions1 = hasStartTimeProcess.get(i).getConflictRoptions();
-                Map<String, String> conflictRoptions2 = hasStartTimeProcess.get(i+1).getConflictRoptions();
-                if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
+            for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+                if(hasStartTimeProcess.get(i).getId() == null && hasStartTimeProcess.get(i+1).getId() == null){
+                    continue;
+                }
+                if(hasStartTimeProcess.get(i).getSeriesProduceMark() != null && hasStartTimeProcess.get(i+1).getSeriesProduceMark() != null){
+                    Map<String, String> conflictRoptions1 = hasStartTimeProcess.get(i).getConflictRoptions();
+                    Map<String, String> conflictRoptions2 = hasStartTimeProcess.get(i+1).getConflictRoptions();
+                    if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
                     /*if(conflictRoptions1.containsKey("soft-seriesProduceZz")){
                         conflictRoptions1.remove("soft-seriesProduceZz");
                     }
                     if(conflictRoptions2.containsKey("soft-seriesProduceZz")){
                         conflictRoptions2.remove("soft-seriesProduceZz");
                     }*/
-                    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+15;
-                            if(hasStartTimeProcess.get(i).getId() != null){
-                                conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反换辊和立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反换辊和立板的连续约束");
+                        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+15;
+                                if(hasStartTimeProcess.get(i).getId() != null){
+                                    conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反换辊和立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反换辊和立板的连续约束");
+                                }else{
+                                    conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
+                                }
                             }else{
-                                conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
-                            }
-                        }else{
-                            // 合金相同情况下后面的宽度大于前面的宽度需要换辊和立板
-                            // 合金相同情况下后面的宽度小于前面的宽度需要立板
-                            // 合金相同情况下后面的宽度等于前面的宽度换辊和立板都不需要
-                            String s1 = serspre[2];
-                            String s2 = sersafter[2];
-                            try{
-                                BigDecimal i1 = new BigDecimal(s1);
-                                BigDecimal i2 = new BigDecimal(s2);
-                                if(i1.compareTo(i2)<0){
-                                    b = b+15;
-                                    if(hasStartTimeProcess.get(i).getId() != null){
-                                        conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反换辊和立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反换辊和立板的连续约束");
-                                    }else{
-                                        conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
-                                    }
-                                }else if(i1.compareTo(i2)>0){
-                                    b = b+8;
-                                    if(hasStartTimeProcess.get(i).getId() != null){
-                                        conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反立板的连续约束");
-                                    }else{
-                                        conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反立板的连续约束");
+                                // 合金相同情况下后面的宽度大于前面的宽度需要换辊和立板
+                                // 合金相同情况下后面的宽度小于前面的宽度需要立板
+                                // 合金相同情况下后面的宽度等于前面的宽度换辊和立板都不需要
+                                String s1 = serspre[2];
+                                String s2 = sersafter[2];
+                                try{
+                                    BigDecimal i1 = new BigDecimal(s1);
+                                    BigDecimal i2 = new BigDecimal(s2);
+                                    if(i1.compareTo(i2)<0){
+                                        b = b+15;
+                                        if(hasStartTimeProcess.get(i).getId() != null){
+                                            conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反换辊和立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反换辊和立板的连续约束");
+                                        }else{
+                                            conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反换辊和立板的连续约束");
+                                        }
+                                    }else if(i1.compareTo(i2)>0){
+                                        b = b+8;
+                                        if(hasStartTimeProcess.get(i).getId() != null){
+                                            conflictRoptions1.put("soft-seriesProduceZz",conflictRoptions1.get("soft-seriesProduceZz") == null ? "和后一道工序违反立板的连续约束" : conflictRoptions1.get("soft-seriesProduceZz")+";和后一道工序违反立板的连续约束");
+                                        }else{
+                                            conflictRoptions2.put("soft-seriesProduceZz","和前一道工序违反立板的连续约束");
+                                        }
                                     }
+                                }catch (Exception e){
+                                    e.printStackTrace();
                                 }
-                            }catch (Exception e){
-                                e.printStackTrace();
                             }
                         }
-                    }
-                } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
+                    } else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
                     /*if(conflictRoptions1.containsKey("soft-seriesProduceLz")){
                         conflictRoptions1.remove("soft-seriesProduceLz");
                     }
                     if(conflictRoptions2.containsKey("soft-seriesProduceLz")){
                         conflictRoptions2.remove("soft-seriesProduceLz");
                     }*/
-                    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+10;
-                            if(hasStartTimeProcess.get(i).getId() != null){
-                                conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
+                        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+10;
+                                if(hasStartTimeProcess.get(i).getId() != null){
+                                    conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
+                                }else{
+                                    conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
+                                }
                             }else{
-                                conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
-                            }
-                        }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{
-                                BigDecimal i1 = new BigDecimal(s1);
-                                BigDecimal i2 = new BigDecimal(s2);
-                                // 后端工序大于前道工序,并且大于30mm
-                                if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
-                                    b = b+7;
-                                    if(hasStartTimeProcess.get(i).getId() != null){
-                                        conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
-                                    }else{
-                                        conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
+                                // 前道工序宽度、输入物料厚度、输出物料厚度
+                                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{
+                                    BigDecimal i1 = new BigDecimal(s1);
+                                    BigDecimal i2 = new BigDecimal(s2);
+                                    // 后端工序大于前道工序,并且大于30mm
+                                    if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
+                                        b = b+7;
+                                        if(hasStartTimeProcess.get(i).getId() != null){
+                                            conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
+                                        }else{
+                                            conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
+                                        }
                                     }
-                                }
-                                // 后端工序大于前道工序,并且小于30mm
-                                else if(i1.compareTo(i2)<0 && (i1.add(new BigDecimal("30"))).compareTo(i2)>=0){
-                                    b = b+6;
-                                    if(hasStartTimeProcess.get(i).getId() != null){
-                                        conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
-                                    }else{
-                                        conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
+                                    // 后端工序大于前道工序,并且小于30mm
+                                    else if(i1.compareTo(i2)<0 && (i1.add(new BigDecimal("30"))).compareTo(i2)>=0){
+                                        b = b+6;
+                                        if(hasStartTimeProcess.get(i).getId() != null){
+                                            conflictRoptions1.put("soft-seriesProduceLz",conflictRoptions1.get("soft-seriesProduceLz") == null ? "和后一道工序违反换辊的连续约束" : conflictRoptions1.get("soft-seriesProduceLz")+";和后一道工序违反换辊的连续约束");
+                                        }else{
+                                            conflictRoptions2.put("soft-seriesProduceLz","和前一道工序违反换辊的连续约束");
+                                        }
                                     }
-                                }
-                                // 后端工序小于前道工序
-                                else if(i1.compareTo(i2)>0){
-                                    b = b+5;
-                                }
-                                // 宽度相等的情况下
-                                else{
-                                    // 输入厚度不同
-                                    if(t1.compareTo(t2) != 0){
-                                        b = b+4;
-                                    }else{
-                                        // 输出厚度不同
-                                        if(to1.compareTo(to2) != 0){
-                                            b = b+3;
+                                    // 后端工序小于前道工序
+                                    else if(i1.compareTo(i2)>0){
+                                        b = b+5;
+                                    }
+                                    // 宽度相等的情况下
+                                    else{
+                                        // 输入厚度不同
+                                        if(t1.compareTo(t2) != 0){
+                                            b = b+4;
                                         }else{
-                                            // 不属于同一作业
-                                            if(!processId1.equals(processId2)){
-                                                b = b+1;
+                                            // 输出厚度不同
+                                            if(to1.compareTo(to2) != 0){
+                                                b = b+3;
+                                            }else{
+                                                // 不属于同一作业
+                                                if(!processId1.equals(processId2)){
+                                                    b = b+1;
+                                                }
                                             }
                                         }
                                     }
+                                }catch (Exception e){
+                                    e.printStackTrace();
                                 }
-                            }catch (Exception e){
-                                e.printStackTrace();
                             }
                         }
                     }
@@ -1910,6 +1963,8 @@ public class ApsConstraintProvider implements ConstraintProvider {
                     }
                 })
                 .penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentId,processes)->{
+                    // 已占用的
+                    List<EquipmentRunTime> equipmentRunTimes = processes.get(0).getEquipment().getEquipmentRunTimes();
                     // 同一工序的优先组炉
                     List<ProductionProcesses> ths = new ArrayList<>();
                     processes.forEach(v->{
@@ -1933,6 +1988,32 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             }
                         }
                     }
+                    if(processes.get(0).getEquipment().getId().equals("7b2ffd8c722d4d5a85b55fc32de99366")){
+                        int a = 1;
+                        /*if(processes.get(0).getStartTime().){
+
+                        }*/
+                    }
+                    List<String> hasMergeOldKeys = new ArrayList<>();
+                    ppMap.forEach((k,v)->{
+                        if(v.size() == 1){
+                            if(v.get(0).getProducePcNum() == 1){
+                                if(equipmentRunTimes != null && equipmentRunTimes.size()>0){
+                                    for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
+                                        if(equipmentRunTime.getStartRunTime().compareTo(v.get(0).getStartTime()) == 0){
+                                            hasMergeOldKeys.add(k);
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    });
+                    if(hasMergeOldKeys != null && hasMergeOldKeys.size()>0){
+                        for (String hasMergeOldKey : hasMergeOldKeys) {
+                            ppMap.remove(hasMergeOldKey);
+                        }
+                    }
                     return ppMap.size()*10000;
                 })
                 .asConstraint("mergeTuihuo");
@@ -1945,9 +2026,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
      */
     private Constraint sameEquipment(ConstraintFactory constraintFactory){
         return constraintFactory.forEach(ProductionProcesses.class)
-                .filter(pro->{
+                /*.filter(pro->{
                     return pro.getProcessType().equals("铸轧") || pro.getProcessType().equals("冷轧");
-                })
+                })*/
                 .groupBy(ProductionProcesses::getUniqueBsProcessesId,ConstraintCollectors.toList())
                 .filter((equipmentEquassociated,processes) -> {
                     if(processes != null && processes.size()>0){

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

@@ -104,6 +104,8 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                             newPro.setVolumeWidth(productionProcesses.getVolumeWidth());
                             newPro.setSinglerollweight(productionProcesses.getSinglerollweight());
                             processesList.add(newPro);
+
+                            productionProcesses.setApsStatus("LS");
                         }
                         event.getNewBestSolution().setStepBestProcessesList(processesList);
                     }
@@ -140,7 +142,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         // 得分分析
         softExplain(explain,solvedBalance.getProcessesList());
         // 最大等待时间冲突手动解决
-        /*List<ProductionProcesses> maxSetPros = new ArrayList<>();
+        List<ProductionProcesses> maxSetPros = new ArrayList<>();
         for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
             if(productionProcesses.getConflictDes() != null && "开工时间超出上道工序作业最大等待时间限制".equals(productionProcesses.getConflictDes())){
                 ProductionProcesses newPre = maxWaitTimeCheck(productionProcesses, maxSetPros,solvedBalance.getProcessesList(),solvedBalance.getEquipmentList());
@@ -150,6 +152,11 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                     if(StrUtil.isBlank(productionProcesses.getConflictDes()) && StrUtil.isBlank(productionProcesses.getSoftconflictdes())){
                         productionProcesses.setHasConflict(null);
                     }
+
+                    productionProcesses.getPreviousProcesses().get(0).setConflictDes(productionProcesses.getConflictDes().replaceAll("开工时间超出上道工序作业最大等待时间限制",""));
+                    if(StrUtil.isBlank(productionProcesses.getPreviousProcesses().get(0).getConflictDes()) && StrUtil.isBlank(productionProcesses.getPreviousProcesses().get(0).getSoftconflictdes())){
+                        productionProcesses.getPreviousProcesses().get(0).setHasConflict(null);
+                    }
                 }
             }
             productionProcesses.setIfLock(true);
@@ -163,7 +170,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                     }
                 }
             }
-        }*/
+        }
 
         solvedBalance.getProcessesList().addAll(hasLocks);
         log.info("**************排程最终评分分析***************");
@@ -638,6 +645,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
             if(StrUtil.isBlank(process.getTaskType())){
                 process.setTaskType("processes");
             }
+            process.setApsStatus("CH");
             process.setOrderId(process.getProduceOrder().get(0).getId());
             // 前道工序
             if(process.getPreviousProcessesIds() != null && process.getPreviousProcessesIds().size()>0){
@@ -732,7 +740,10 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                             for (ApsFurnaceInstallationDo furnaceInstallation : productionScheduleVo.getFurnaceInstallations()) {
                                 if(equipmentRunTime.getVolumeMetal().equals(furnaceInstallation.getAlloy())){
                                     boolean a = true;
-                                    if(furnaceInstallation.getAlloystatus() != null && !furnaceInstallation.getAlloystatus().contains(equipmentRunTime.getVolumeMetalstate())){
+                                    if((furnaceInstallation.getAlloystatus() != null && equipmentRunTime.getVolumeMetalstate() != null && furnaceInstallation.getAlloystatus().contains(equipmentRunTime.getVolumeMetalstate()))
+                                            || (furnaceInstallation.getAlloystatus() == null && equipmentRunTime.getVolumeMetalstate() == null)){
+                                        a = true;
+                                    }else{
                                         a = false;
                                     }
                                     if(furnaceInstallation.getStartthickness() != null && furnaceInstallation.getStartthickness().compareTo(equipmentRunTime.getTotalThickness())>0){
@@ -879,9 +890,10 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         List<ProductionProcesses> processesList1 = bsMap.get(uniqueBsProcessesId);
         if(processesList1 != null && processesList1.size()>0){
             if(processesList1.get(0).getProcessType().equals("成退") || processesList1.get(0).getProcessType().equals("中退") || processesList1.get(0).getProcessType().equals("小卷成退")
-//                    || processesList1.get(0).getProcessType().equals("冷轧") || processesList1.get(0).getProcessType().equals("铸轧")
+//            if(processesList1.get(0).getNextProcesses() != null && (processesList1.get(0).getNextProcesses().get(0).getProcessType().equals("成退")
+//                    || processesList1.get(0).getNextProcesses().get(0).getProcessType().equals("中退")
+//                    || processesList1.get(0).getNextProcesses().get(0).getProcessType().equals("小卷成退"))
             ){
-//                List<ProductionProcesses> pres = bsMap.get(processesList1.get(0).getPreviousProcesses().get(0).getUniqueBsProcessesId());
                 if(processesList1.get(0).getPreviousProcesses() != null && processesList1.get(0).getPreviousProcesses().size()>0){
                     for (ProductionProcesses productionProcesses : processesList1) {
                         productionProcesses.setOrderMark(productionProcesses.getPreviousProcesses().get(0).getOrderMark());