Browse Source

排程模式配置

fangpy 6 tháng trước cách đây
mục cha
commit
38c7a59f72

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

@@ -130,6 +130,11 @@ public class Equipment implements Serializable {
      */
     private BigDecimal lastSinglerollweight;
 
+    /**
+     * 当前设备最早工序的连续冷轧的开始时间
+     */
+    private Date lxzTime;
+
     /**
      * 关联设备,铸轧机关联的熔炼炉
      */

+ 181 - 1
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -46,7 +46,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 tuihuoSp(constraintFactory),
                 sameEquipment(constraintFactory),
                 seriesZzLb(constraintFactory),
-
+                seriesLzHg(constraintFactory),
                 preNextProcessSameWorkShop(constraintFactory),
                 // SOFT
                 processNear(constraintFactory),
@@ -611,6 +611,186 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .asConstraint("seriesProduceTimeWait");
     }
 
+    /**
+     * 冷轧换辊预留周期
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint seriesLzHg(ConstraintFactory constraintFactory){
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter((processe) -> {
+                    return "冷轧".equals(processe.getProcessType()) || "箔轧".equals(processe.getProcessType());
+                })
+                .groupBy(ProductionProcesses::getEquipmentId, ConstraintCollectors.toList())
+                .filter((equipmentId,processes) -> {
+                    if(processes != null && processes.size()>0){
+                        for (ProductionProcesses process : processes) {
+                            if(process.getConflictRoptions().containsKey("soft-seriesZzLb")){
+                                process.getConflictRoptions().remove("soft-seriesZzLb");
+                            }
+                        }
+                        return true;
+                    }
+                    return false;
+                })
+                .penalize(HardMediumSoftScore.ONE_MEDIUM,(equipmentId,processes)->{
+                    int counNum = seriesLzHgCount(processes);
+                    return counNum*30;
+                })
+                .asConstraint("seriesLzHg");
+    }
+
+    private int seriesLzHgCount(List<ProductionProcesses> processes){
+        int b = 0;
+        Equipment equipment = null;
+        if(processes != null && processes.size()>0){
+            equipment = processes.get(0).getEquipment();
+        }else{
+            return b;
+        }
+        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());
+                pp.setConflictRoptions(new HashMap<>());
+                pp.setProduceTime(equipmentRunTime.getOnceprocessmin());
+                pp.setSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
+                pp.setLastSerialLbWeight(equipmentRunTime.getLastSerialLbWeight());
+                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());
+            pp.setProduceTime(equipment.getOnceprocessmin());
+            pp.setConflictRoptions(new HashMap<>());
+            pp.setSinglerollweight(equipment.getLastSinglerollweight());
+            pp.setLastSerialLbWeight(equipment.getLastSerialLbWeight());
+            hasStartTimeProcess.add(0,pp);
+        }
+
+        // 周期立板已连续生产吨数
+        LocalDateTime lzlxstarttime = null;
+        if(equipment.getLxzTime() != null){
+            lzlxstarttime = equipment.getLxzTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        }else{
+            lzlxstarttime = hasStartTimeProcess.get(0).getStartTime();
+        }
+        int huzq = 60*8;
+        for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+            ProductionProcesses prePro = hasStartTimeProcess.get(i);
+            ProductionProcesses nextPro = hasStartTimeProcess.get(i+1);
+            Map<String, String> conflictRoptions1 = prePro.getConflictRoptions();
+            Map<String, String> conflictRoptions2 = nextPro.getConflictRoptions();
+
+            ProductionProcesses prepro = hasStartTimeProcess.get(i);
+            ProductionProcesses nextpro = hasStartTimeProcess.get(i+1);
+            String[] serspre = hasStartTimeProcess.get(i).getSeriesProduceMark().split("\\^_\\^");
+            String[] sersafter = hasStartTimeProcess.get(i+1).getSeriesProduceMark().split("\\^_\\^");
+            // 前道工序宽度、输入物料厚度、输出物料厚度
+            String s1 = serspre[2];
+            // 后道工序宽度、输入物料厚度、输出物料厚度
+            String s2 = sersafter[2];
+            BigDecimal i1 = new BigDecimal(s1);
+            BigDecimal i2 = new BigDecimal(s2);
+            // 判断原有前后两道历史工序是否连续
+            /*boolean ispreafterLx = false;
+            if(prepro.getId() == null && nextpro.getId() != null && hasStartTimeProcess.size()>i+2
+                    && hasStartTimeProcess.get(i+2).getId() == null){
+                ProductionProcesses nextnextpro = hasStartTimeProcess.get(i + 2);
+                if(StrUtil.isNotBlank(prepro.getProZg()) && StrUtil.isNotBlank(nextnextpro.getProZg())){
+                    if(prepro.getProZg().equals(nextnextpro.getProZg())){
+                        String[] sersafterafter = nextnextpro.getSeriesProduceMark().split("\\^_\\^");
+                        BigDecimal i3 = new BigDecimal(sersafterafter[2]);
+                        if(i1.compareTo(i3)>=0){
+                            ispreafterLx = true;
+                        }
+                    }
+                }
+            } else if (prepro.getId() != null && nextpro.getId() == null && i>0
+                    && hasStartTimeProcess.get(i-1).getId() == null) {
+                ProductionProcesses preprepro = hasStartTimeProcess.get(i-1);
+                if(StrUtil.isNotBlank(preprepro.getProZg()) && StrUtil.isNotBlank(nextpro.getProZg())){
+                    if(preprepro.getProZg().equals(nextpro.getProZg())){
+                        String[] sersprepre = preprepro.getSeriesProduceMark().split("\\^_\\^");
+                        BigDecimal i0 = new BigDecimal(sersprepre[2]);
+                        if(i0.compareTo(i2)>=0){
+                            ispreafterLx = true;
+                        }
+                    }
+                }
+            }*/
+
+            if(StrUtil.isNotBlank(prepro.getProZg()) && StrUtil.isNotBlank(nextpro.getProZg())){
+                String preZg = prepro.getProZg();
+                String nextZg = nextpro.getProZg();
+                if(!preZg.equals(nextZg)){
+                    if(lzlxstarttime.plusMinutes(huzq).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                        // 只有存在当前排程的作业才会记录扣分数
+                        if(nextPro.getId() != null){
+                            b = b+8;
+                            conflictRoptions2.put("soft-seriesZzLb","和上道工序没有预留足够的周期换辊时间");
+                        }else{
+                            if(prePro.getId() != null){
+                                b = b+8;
+                                conflictRoptions1.put("soft-seriesZzLb","和下道工序没有预留足够的周期换辊时间");
+                            }
+                        }
+                    }
+                    lzlxstarttime = hasStartTimeProcess.get(i+1).getStartTime();
+                }else{
+                    if((i1.add(new BigDecimal("30"))).compareTo(i2)<0){
+                        if(lzlxstarttime.plusMinutes(huzq).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                            // 只有存在当前排程的作业才会记录扣分数
+                            if(nextPro.getId() != null){
+                                b = b+8;
+                                conflictRoptions2.put("soft-seriesZzLb","和上道工序没有预留足够的周期换辊时间");
+                            }else{
+                                if(prePro.getId() != null){
+                                    b = b+8;
+                                    conflictRoptions1.put("soft-seriesZzLb","和下道工序没有预留足够的周期换辊时间");
+                                }
+                            }
+                        }
+                        lzlxstarttime = hasStartTimeProcess.get(i+1).getStartTime();
+                    }else if(i1.compareTo(i2)>0){
+                        int ii = ((i1.subtract(i2)).divideToIntegralValue(new BigDecimal("100"))).intValue();
+                        int it = ii*60;
+                        if(it>huzq){
+                            it = huzq;
+                        }
+                        if(lzlxstarttime.plusMinutes(it).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
+                            // 只有存在当前排程的作业才会记录扣分数
+                            if(nextPro.getId() != null){
+                                b = b+1;
+                            }else{
+                                if(prePro.getId() != null){
+                                    b = b+1;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return b;
+    }
+
     /**
      * 铸轧预留连续排产时间
      * @param constraintFactory