Procházet zdrojové kódy

排程优化-退火合并优化

fangpy před 7 měsíci
rodič
revize
e5df7c6151

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

@@ -215,9 +215,6 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
     }
 
     private LocalDateTime startTimeNewSet(ProductionProcesses process,ScoreDirector<ApsSolution> scoreDirector){
-        if(process.getId().equals("39224859c48946c8a8984380120caa65")){
-            int a = 0;
-        }
         // 获取所有规划实体对象数据
         ApsSolution workingSolution = scoreDirector.getWorkingSolution();
         // 时间设定
@@ -398,6 +395,9 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
             if(process.getEquipmentId().equals("0001be252874536843730b100163")){
                 int a = 0;
             }
+            if(process.getId().equals("b48d04239ebe4b7f95e18ded92c25249")){
+                int a = 0;
+            }
             Integer delay = process.getDelay();
             // 有交叉的时间直接跳过,退火工序特殊处理
             if(equipmentRunTimes.size()>0){
@@ -525,6 +525,9 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
 
             toUpdateStartTime = proStartTime;
         }
+        if(process.getId().equals("f5228d1b1ffa4c22a54ebb811a8a7950")){
+            int a = 0;
+        }
         return toUpdateStartTime;
     }
 

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

@@ -33,6 +33,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 seriesProduceWashTimeWait(constraintFactory),
                 equipmentRunTime(constraintFactory),
                 eqTimeCrossTuihuo(constraintFactory),
+                eqTimeCrossTuihuoType(constraintFactory),
                 eqTimeCrossMinTuihuo(constraintFactory),
                 maxStartTime(constraintFactory),
                 // MEDIUM
@@ -262,6 +263,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                                 }
                             }
                         }
+                        if(productionProcesses.getId().equals("b48d04239ebe4b7f95e18ded92c25249")){
+                            int a = 1111;
+                        }
                         List<LocalDateTime> nextStartTimes = new ArrayList<>();
                         getAllNextProTime(productionProcesses,nextStartTimes,0);
                         if(nextStartTimes != null && nextStartTimes.size()>0){
@@ -1351,6 +1355,55 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .asConstraint("eqTimeCrossTuihuo");
     }
 
+    private Constraint eqTimeCrossTuihuoType(ConstraintFactory constraintFactory) {
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter(pro->{
+                    return pro.getProcessType().equals("成退") || pro.getProcessType().equals("中退") || pro.getProcessType().equals("小卷成退");
+                })
+                .groupBy(ProductionProcesses::getEquipmentId,ConstraintCollectors.toList())
+                .filter((equipmentId,processes) -> {
+                    if(processes != null && processes.size()>0){
+                        for (ProductionProcesses process : processes) {
+                            if(process.getConflictRoptions().containsKey("hard-eqTimeCrossTuihuoType")){
+                                process.getConflictRoptions().remove("hard-eqTimeCrossTuihuoType");
+                            }
+                        }
+                        return true;
+                    }else{
+                        return false;
+                    }
+                })
+                .penalize(HardMediumSoftScore.ONE_HARD,(equipmentId,processes)->{
+                    Integer num = 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());
+                    // 按照开始时间排序
+                    Collections.sort(hasStartTimeProcess, Comparator.comparing(ProductionProcesses::getSeriSort));
+                    Map<String,List<ProductionProcesses>> ppMap = new HashMap<>();
+                    for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+                        ProductionProcesses prePro = hasStartTimeProcess.get(i);
+                        ProductionProcesses nextPro = hasStartTimeProcess.get(i+1);
+                        // 开始时间相等为合并工序
+                        if (prePro.getStartTime().compareTo(nextPro.getStartTime()) == 0){
+                            /*DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                            String startTimeKey = prePro.getStartTime().format(formatter);
+                            if(!ppMap.containsKey(startTimeKey)){
+                                List<ProductionProcesses> pps = new ArrayList<>();
+                                ppMap.put(startTimeKey,pps);
+                            }*/
+                            if(!prePro.getProcessType().equals(nextPro.getProcessType())){
+                                num++;
+                            }
+                        }
+                    }
+                    return num*100;
+                })
+                .asConstraint("eqTimeCrossTuihuoType");
+    }
+
     /**
      * 退火工序冲突计算
      * @param processes
@@ -1606,9 +1659,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
             }
             // 重量、宽度、厚度要满足一定规则
             else{
-                if(processTypeSet.contains("小卷成退")){
+                /*if(processTypeSet.contains("小卷成退")){
                     continue;
-                }
+                }*/
                 String processType = v.get(0).getProcessType();
                 BigDecimal btVolumeWidth = null;
                 BigDecimal btVolumeThickness = null;

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

@@ -367,6 +367,11 @@ public class ApsServiceImpl implements ApsService {
         log.info(explain1.toString());
         log.info("**************退火排程评分分析***************");
 
+        // 全部待排程作业
+        Map<String,ProductionProcesses> allProMap = new HashMap<>();
+        for (ProductionProcesses productionProcesses : apsSolution.getProcessesList()) {
+            allProMap.put(productionProcesses.getId(),productionProcesses);
+        }
         // 锁定退火工序(根据开始时间分组,多个坯料计划一炉的则锁定,单个坯料计划一炉的总体一起排程)
         Map<String,List<ProductionProcesses>> thGroup = new HashMap<>();
         DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -389,7 +394,7 @@ public class ApsServiceImpl implements ApsService {
                 }
             }
             if(orderids.size()>1){
-                List<EquipmentRunTime> equipmentRunTimes = new ArrayList<>();
+                /*List<EquipmentRunTime> equipmentRunTimes = new ArrayList<>();
                 for (ProductionProcesses process : v) {
                     List<ProductionProcesses> collect = apsSolution.getProcessesList().stream().filter(vp -> vp.getId().equals(process.getId())).collect(Collectors.toList());
                     if(collect != null && collect.size()>0){
@@ -434,7 +439,28 @@ public class ApsServiceImpl implements ApsService {
                         v.get(0).getEquipment().getEquipmentRunTimes().addAll(equipmentRunTimes);
                     }
                     equipmentRunTimeMerge(v.get(0).getEquipment(),v.get(0).getApsOverallConfig().getFurnaceInstallations());
+                }*/
+
+                for (ProductionProcesses process : v) {
+                    List<ProductionProcesses> collect = apsSolution.getProcessesList().stream().filter(vp -> vp.getId().equals(process.getId())).collect(Collectors.toList());
+                    if(collect != null && collect.size()>0){
+                        for (ProductionProcesses productionProcesses : collect) {
+                            // 前后道工序设置
+                            if(relPros.containsKey(productionProcesses.getId())){
+                                Map<String, List<ProductionProcesses>> stringListMap = relPros.get(productionProcesses.getId());
+                                productionProcesses.setPreviousProcesses(stringListMap.get("pres"));
+                                productionProcesses.setNextProcesses(stringListMap.get("nexts"));
+                            }
+                            // 递归推理前道工序
+                            proMaxTimeSet(productionProcesses,productionProcesses,0);
+                        }
+                    }
                 }
+                // 合并不同订单退火
+                List<String> hbThIds = v.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                List<ProductionProcesses> hbThPros = apsSolution.getProcessesList().stream().filter(vp -> hbThIds.contains(vp.getId())).collect(Collectors.toList());
+                ProductionProcesses mainTh = thOrdersMerge(hbThPros, otherThproces, allProMap,apsSolution);
+                apsSolution.getProcessesList().sort(Comparator.comparing(ProductionProcesses::getOrderMark));
             }else{
                 for (ProductionProcesses process : v) {
                     List<ProductionProcesses> collect = apsSolution.getProcessesList().stream().filter(vp -> vp.getId().equals(process.getId())).collect(Collectors.toList());
@@ -453,7 +479,105 @@ public class ApsServiceImpl implements ApsService {
                 }
             }
         });
+    }
+
+    private ProductionProcesses thOrdersMerge(List<ProductionProcesses> thps,List<ProductionProcesses> otherThproces
+            ,Map<String,ProductionProcesses> allProMap,ApsSolution apsSolution){
+        ProductionProcesses mergePro = null;
+        if(thps != null && thps.size()>0){
+            // 根据排程时间从大到小排序
+            Collections.sort(thps,(v1,v2)->v2.getProduceTime().compareTo(v1.getProduceTime()));
+            for (int i = 0; i < thps.size(); i++) {
+                if(i>0){
+                    // 设置待合并退火的主ID
+                    thps.get(i).setMergeThMainId(thps.get(0).getId());
+                    otherThproces.add(thps.get(i));
+                    for (String previousProcessesId : thps.get(i).getPreviousProcessesIds()) {
+                        // 退火前一道作业设置下一作业ID
+                        ProductionProcesses prepro = allProMap.get(previousProcessesId);
+                        // 合并后关联关系重置
+                        if(!prepro.getNextProcessesIds().contains(thps.get(0).getId())){
+                            int i1 = prepro.getNextProcessesIds().indexOf(thps.get(i).getId());
+                            prepro.getNextProcessesIds().set(i1,thps.get(0).getId());
+                        }
+                        List<String> list = new ArrayList<>();
+                        Set<String> set = new LinkedHashSet<>();
+                        for (String nextProcessesId : prepro.getNextProcessesIds()) {
+                            set.add(nextProcessesId);
+                        }
+                        list.addAll(set);
+                        prepro.setNextProcessesIds(list);
+                        List<ProductionProcesses> nextpros = new ArrayList<>();
+                        for (String nextProcessesId : prepro.getNextProcessesIds()) {
+                            nextpros.add(allProMap.get(nextProcessesId));
+                        }
+                        prepro.setNextProcesses(nextpros);
+
+                        // 当前合并退火作业设置前一道作业
+                        if(!thps.get(0).getPreviousProcessesIds().contains(prepro.getId())){
+                            thps.get(0).getPreviousProcessesIds().add(prepro.getId());
+                        }
+                        List<ProductionProcesses> previousProces = new ArrayList<>();
+                        for (String pid : thps.get(0).getPreviousProcessesIds()) {
+                            previousProces.add(allProMap.get(pid));
+                        }
+                        thps.get(0).setPreviousProcesses(previousProces);
+                    }
+
+                    // 退火后一道作业设置上一道作业ID
+                    if(thps.get(i).getNextProcessesIds() != null && thps.get(i).getNextProcessesIds().size()>0){
+                        for (String nextProcessesId : thps.get(i).getNextProcessesIds()) {
+                            ProductionProcesses nextpro = allProMap.get(nextProcessesId);
+                            // 合并后关联关系重置
+                            List<String> preids = new ArrayList<>();
+                            preids.add(thps.get(0).getId());
+                            nextpro.setPreviousProcessesIds(preids);
+                            if(!nextpro.getPreviousProcessesIds().contains(thps.get(0).getId())){
+                                int i1 = nextpro.getPreviousProcessesIds().indexOf(thps.get(i).getId());
+                                nextpro.getPreviousProcessesIds().set(i1,thps.get(0).getId());
+                            }
+
+                            List<ProductionProcesses> nextprepros = new ArrayList<>();
+                            for (String pid : nextpro.getPreviousProcessesIds()) {
+                                nextprepros.add(allProMap.get(pid));
+                            }
+                            nextpro.setPreviousProcesses(nextprepros);
+
+                            // 设置合并退火作业下一道工序
+                            thps.get(0).getNextProcessesIds().addAll(thps.get(i).getNextProcessesIds());
+                            List<ProductionProcesses> thnexts = new ArrayList<>();
+                            for (String pid : thps.get(0).getNextProcessesIds()) {
+                                thnexts.add(allProMap.get(pid));
+                            }
+                            thps.get(0).setNextProcesses(thnexts);
+                        }
+                    }
+                    // 小卷退火卷数合并
+                    if(thps.get(i).getProcessType().equals("小卷成退")){
+                        thps.get(0).setMinThPcNum(thps.get(0).getMinThPcNum()+thps.get(i).getMinThPcNum());
+                    }
+                    // 排程排序字段重新设置,取最小的排序字段值
+                    if(thps.get(i).getOrderMark()<thps.get(0).getOrderMark()){
+                        thps.get(0).setOrderMark(thps.get(i).getOrderMark());
+                    }
+                    ProductionProcesses thisPro = thps.get(i);
+                    List<ProductionProcesses> collect = apsSolution.getProcessesList().stream().filter(v -> !v.getId().equals(thisPro.getId())).collect(Collectors.toList());
+                    apsSolution.setProcessesList(collect);
+                }
+            }
+            // 取第一个作业作为合并作业
+            mergePro = thps.get(0);
+            mergePro.setVolumeWidth(mergePro.getVolumeWidth().multiply(new BigDecimal(thps.size())));
+            mergePro.setSinglerollweight(mergePro.getSinglerollweight().multiply(new BigDecimal(thps.size())));
+            mergePro.setOpeProducePcNum(thps.size());
+
+            // 重新设置前道工序的排序字段值
+            Map<String,Integer> sortMap = new HashMap<>();
+            sortMap.put("sortInt",mergePro.getOrderMark());
+            setPreOrderMark(mergePro.getPreviousProcesses(),sortMap);
+        }
 
+        return mergePro;
 
         // 退火合并工序
         /*if(solvedBalance1.getProcessesList() != null && solvedBalance1.getProcessesList().size()>0){
@@ -772,7 +896,13 @@ public class ApsServiceImpl implements ApsService {
                             // 作业计划加工卷数是否大于一炉最大卷数
                             if(v.get(0).getRooprocess() != null && v.get(0).getRooprocess().getStartTime() != null){
                                 Collections.sort(v,(p1,p2)->{
-                                    return p1.getRooprocess().getStartTime().compareTo(p2.getRooprocess().getStartTime());
+                                    if(p1.getRooprocess() == null || p1.getRooprocess().getStartTime() == null){
+                                        return 1;
+                                    } else if (p2.getRooprocess() == null || p2.getRooprocess().getStartTime() == null) {
+                                        return -1;
+                                    }else{
+                                        return p1.getRooprocess().getStartTime().compareTo(p2.getRooprocess().getStartTime());
+                                    }
                                 });
                             }
                             if(a == 0){
@@ -1131,13 +1261,15 @@ public class ApsServiceImpl implements ApsService {
                                             // 退火前一道作业设置下一作业ID
                                             ProductionProcesses prepro = thps.get(i).getPreviousProcesses().get(0);
                                             // 合并后关联关系重置
-                                            if(prepro.getNextProcessesIds().contains(thps.get(i).getId())){
+                                            /*if(prepro.getNextProcessesIds().contains(thps.get(i).getId())){
                                                 prepro.getNextProcessesIds().remove(thps.get(i).getId());
                                             }
                                             if(!prepro.getNextProcessesIds().contains(thps.get(0).getId())){
                                                 int i1 = prepro.getNextProcessesIds().indexOf(thps.get(i).getId());
                                                 prepro.getNextProcessesIds().set(i1,thps.get(0).getId());
-                                            }
+                                            }*/
+                                            int i1 = prepro.getNextProcessesIds().indexOf(thps.get(i).getId());
+                                            prepro.getNextProcessesIds().set(i1,thps.get(0).getId());
 
                                             List<String> list = new ArrayList<>();
                                             Set<String> set = new LinkedHashSet<>();
@@ -2127,7 +2259,12 @@ public class ApsServiceImpl implements ApsService {
             List<ProductionProcesses> otherThproces = new ArrayList<>();
             // 铸轧提前排序
             int processNum1 = apsSolutionZz.getProcessesList().size();
-            int runPlanSeconds1 = (processNum1)*120;
+            List<ProductionProcesses> zzs = apsSolutionZz.getProcessesList().stream().filter(v -> v.getProcessType().equals("铸轧")).collect(Collectors.toList());
+            int zzNum = 0;
+            if(zzs != null && zzs.size()>0){
+                zzNum = zzs.size();
+            }
+            int runPlanSeconds1 = (zzNum)*90+((processNum1-zzNum)/productionScheduleVo.getPcspeed() + 1)*60;
             // CPU核数
             String cores = Runtime.getRuntime().availableProcessors() + "";
             SolverFactory<ApsSolution> solverFactory1 = SolverFactory.create(new SolverConfig()

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

@@ -218,7 +218,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());
@@ -239,10 +239,10 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                         }
                     }
 
-                    /*productionProcesses.getPreviousProcesses().get(0).setConflictDes(productionProcesses.getConflictDes().replaceAll("开工时间超出上道工序作业最大等待时间限制",""));
+                    *//*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);
@@ -256,7 +256,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                     }
                 }
             }
-        }
+        }*/
 
         log.info("**************排程最终评分分析***************");
         if(notLocks != null && notLocks.size()>0){
@@ -671,7 +671,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                         LocalDateTime proStartTime1 = proEndTime1.plusMinutes(-preProcess.getProduceTime());
                         if(proStartTime1.compareTo(process.getStartTime().plusMinutes(-process.getMaxWaitTime()))>0){
                             LocalDateTime minproStartTime = proStartTime1;
-                            if(minproStartTime.compareTo(equipmentRunTime.getEndRunTime())>0){
+                            if(equipmentRunTime.getEndRunTime() != null && minproStartTime.compareTo(equipmentRunTime.getEndRunTime())>0){
                                 proStartTime = proStartTime1;
                                 proEndTime = proEndTime1;
                                 hasSet = true;