Quellcode durchsuchen

排程优化-退火合并优化

fangpy vor 7 Monaten
Ursprung
Commit
3966923d51

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

@@ -523,6 +523,12 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                     // 其它工序
                     else{
                         if(proStartTime.compareTo(equipmentRunTime.getEndRunTime())>=0 || proEndTime.compareTo(equipmentRunTime.getStartRunTime())<=0){
+                            if(process.getId().equals("ffcf3324e3ad4c0abd48831b8d4f8499") && process.getEquipmentId().equals("0001be252874536843730b100191") && process.getDelay() == 0){
+                                int a = 0;
+                                if(i == 160){
+                                    int b = 0;
+                                }
+                            }
                             continue;
                         }else{
                             proStartTime = equipmentRunTime.getEndRunTime().plusMinutes(1);
@@ -534,7 +540,7 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
 
             toUpdateStartTime = proStartTime;
         }
-        if(process.getId().equals("0b55bfc2d80249699d52dc8b4d42113e") && process.getEquipmentId().equals("ea69835012de4f2cb9c52496df8be111") && process.getDelay() == 92){
+        if(process.getId().equals("ffcf3324e3ad4c0abd48831b8d4f8499") && process.getEquipmentId().equals("0001be252874536843730b100191") && process.getDelay() == 0){
             int a = 0;
         }
         if(process.getId().equals("753e5d7bb985465b92f40e24abc6b91c") || process.getId().equals("24a272fad1dd4fe2ac475dac44803bfe") || process.getId().equals("77594aa518a945c6be28c1bbd38d9cd4")){

+ 58 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -49,6 +49,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 preNextProcessSameWorkShop(constraintFactory),
                 // SOFT
                 processNear(constraintFactory),
+                lzbzSp(constraintFactory),
                 eqTimeCrossMinTuihuoSoft(constraintFactory),
                 preNextProcessSameEq(constraintFactory),
         };
@@ -2766,6 +2767,63 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .asConstraint("tuihuoSp");
     }
 
+    /**
+     * 冷轧箔轧工序碎片化时间约束
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint lzbzSp(ConstraintFactory constraintFactory){
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter(pro->{
+                    return pro.getProcessType().equals("冷轧") || pro.getProcessType().equals("箔轧");
+                })
+                .groupBy(ProductionProcesses::getEquipmentId,ConstraintCollectors.toList())
+                .filter((equipmentId,processes) -> {
+                    if(processes != null && processes.size()>0){
+                        return true;
+                    }else{
+                        return false;
+                    }
+                })
+                .penalize(HardMediumSoftScore.ONE_SOFT,(equipmentId,processes)->{
+                    int b = 0;
+                    Equipment equipment = processes.get(0).getEquipment();
+                    List<EquipmentRunTime> equipmentRunTimes = equipment.getEquipmentRunTimes();
+                    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.setEndTime(equipmentRunTime.getEndRunTime());
+                                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(hasStartTimeProcess.size()>1){
+                        for(int i=0;i<hasStartTimeProcess.size()-1;i++){
+                            ProductionProcesses bfpps = hasStartTimeProcess.get(i);
+                            ProductionProcesses afpps = hasStartTimeProcess.get(i+1);
+                            if(bfpps.getId() != null || afpps.getId() != null){
+                                if(bfpps.getEndTime().plusMinutes(11).compareTo(afpps.getStartTime())<0){
+                                    b++;
+                                }
+                            }
+                        }
+                    }
+
+                    return b*1500;
+                })
+                .asConstraint("lzbzSp");
+    }
+
     /**
      * 相同作业放在同一设备上加工
      * @param constraintFactory

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

@@ -24,6 +24,7 @@ import org.optaplanner.core.config.phase.PhaseConfig;
 import org.optaplanner.core.config.phase.custom.CustomPhaseConfig;
 import org.optaplanner.core.config.solver.EnvironmentMode;
 import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.termination.TerminationConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
@@ -828,12 +829,33 @@ public class ApsServiceImpl implements ApsService {
     private void thPreMerge(ProductionProcesses mainTh,ApsSolution apsSolution){
         if(mainTh != null && mainTh.getPreviousProcesses() != null && mainTh.getPreviousProcesses().size()>0){
             List<ProductionProcesses> previousProcesses = mainTh.getPreviousProcesses();
-            if(previousProcesses != null && previousProcesses.size()>1){
-                Map<String, List<ProductionProcesses>> orderProcess = previousProcesses.stream().collect(Collectors.groupingBy(ProductionProcesses::getProcessType));
+            preProMerge(previousProcesses,apsSolution);
+        }
+    }
 
-                Collections.sort(previousProcesses, (pro1, pro2) -> {
-                    return pro2.getVolumeWidth().compareTo(pro1.getVolumeWidth());
-                });
+    /**
+     * 不同坯料计划组炉前一道工序合并
+     * @param previousProcesses
+     */
+    private void preProMerge(List<ProductionProcesses> previousProcesses,ApsSolution apsSolution){
+        if(previousProcesses != null && previousProcesses.size()>1){
+            // 过滤分卷工序
+            List<ProductionProcesses> pres = previousProcesses.stream().filter(v -> "否".equals(v.getIssubsection())).collect(Collectors.toList());
+            Map<String, List<ProductionProcesses>> orderProcess = previousProcesses.stream().collect(Collectors.groupingBy(ProductionProcesses::getProcessType));
+            if(orderProcess != null && orderProcess.size()>0){
+                // 相同类型作业合并生产
+                if(orderProcess.size() == 1){
+                    orderProcess.forEach((k,v)->{
+                        if(v.size()>1){
+                            Map<BigDecimal, List<ProductionProcesses>> widthPros = previousProcesses.stream().collect(Collectors.groupingBy(ProductionProcesses::getVolumeWidth));
+
+                        }
+                    });
+                }
+                // 不相同类型作业不合并生产
+                else{
+
+                }
             }
         }
     }
@@ -2400,7 +2422,8 @@ public class ApsServiceImpl implements ApsService {
                     .withSolutionClass(ApsSolution.class)
                     .withEntityClasses(ProductionProcesses.class)
                     .withConstraintProviderClass(ApsConstraintProvider.class)
-                    .withTerminationSpentLimit(Duration.ofSeconds(runPlanSeconds1))
+//                    .withTerminationSpentLimit(Duration.ofSeconds(runPlanSeconds1))
+                    .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(120L))
                     .withMoveThreadCount(cores)
             );
             Solver<ApsSolution> solver1 = solverFactory1.buildSolver();

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

@@ -21,6 +21,7 @@ import org.optaplanner.core.api.solver.event.BestSolutionChangedEvent;
 import org.optaplanner.core.api.solver.event.SolverEventListener;
 import org.optaplanner.core.config.solver.EnvironmentMode;
 import org.optaplanner.core.config.solver.SolverConfig;
+import org.optaplanner.core.config.solver.termination.TerminationConfig;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
@@ -76,12 +77,12 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         // CPU核数
         String cores = Runtime.getRuntime().availableProcessors() + "";
         // optaplanner 求解器配置实例化
-        SolverFactory<ApsSolution> solverFactory = SolverFactory.create(new SolverConfig()
+        /*SolverFactory<ApsSolution> solverFactory = SolverFactory.create(new SolverConfig()
                 .withEnvironmentMode(mode)
                 .withSolutionClass(ApsSolution.class)
                 .withEntityClasses(ProductionProcesses.class)
                 .withConstraintProviderClass(ApsConstraintProvider.class)
-//                .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(10L))
+//                .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(180L))
                 .withTerminationSpentLimit(Duration.ofSeconds(runPlanSeconds))
                 .withMoveThreadCount(cores)
         );
@@ -120,7 +121,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
 //                    solver.terminateEarly();
                 }
             }
-        });
+        });*/
         // optaplanner 求解器数据装配
         List<ProductionProcesses> otherThproces = new ArrayList<>();
         List<ProductionProcesses> otherNotThproces = new ArrayList<>();
@@ -212,7 +213,6 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
 //        }
         apsSolution.setProcessesList(notLocks);
 
-        SolutionManager<ApsSolution, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
         // 按照退火组炉分批排程
         List<CommonJavaBean> orderMerges = produceOrderMerge(ordergrous,apsSolution);
         Collections.sort(orderMerges, (pro1, pro2) -> {return pro2.getMaxVolumeWidth().compareTo(pro1.getMaxVolumeWidth());});
@@ -227,6 +227,55 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 List<ProductionProcesses> processesList1 = apsSolution.getProcessesList().stream().filter(m -> v.contains(m.getProduceOrder().get(0).getId())).collect(Collectors.toList());
                 apsSolution1.setProcessesList(processesList1);
                 apsSolution1.setEquipmentList(apsSolution.getEquipmentList());
+
+                runPlanSeconds = (apsSolution1.getProcessesList().size()/prospeed + 1)*60;
+                SolverFactory<ApsSolution> solverFactory = SolverFactory.create(new SolverConfig()
+                                .withEnvironmentMode(mode)
+                                .withSolutionClass(ApsSolution.class)
+                                .withEntityClasses(ProductionProcesses.class)
+                                .withConstraintProviderClass(ApsConstraintProvider.class)
+                                .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(120L))
+//                                .withTerminationSpentLimit(Duration.ofSeconds(runPlanSeconds))
+                                .withMoveThreadCount(cores)
+                );
+                Solver<ApsSolution> solver = solverFactory.buildSolver();
+                solver.addEventListener(new SolverEventListener<ApsSolution>() {
+                    public void bestSolutionChanged(BestSolutionChangedEvent<ApsSolution> event) {
+                        if(solver.isEveryProblemChangeProcessed()) {
+                            event.getNewBestSolution().setConstructionHeuristicEnd(true);
+                            if(event.getNewBestSolution().getStepBestProcessesList() == null){
+                                List<ProductionProcesses> processesList = new ArrayList<>();
+//                        List<ProductionProcesses> processesList = ObjectUtil.cloneByStream(event.getNewBestSolution().getProcessesList());
+                                for (ProductionProcesses productionProcesses : event.getNewBestSolution().getProcessesList()) {
+                                    ProductionProcesses newPro = new ProductionProcesses();
+                                    newPro.setId(productionProcesses.getId());
+                                    newPro.setEquipmentId(productionProcesses.getEquipmentId());
+                                    Equipment eq = new Equipment();
+                                    if(productionProcesses.getEquipment() != null){
+                                        eq.setId(productionProcesses.getEquipment().getId());
+                                    }
+                                    newPro.setEquipment(eq);
+                                    newPro.setProduceTime(productionProcesses.getProduceTime());
+                                    newPro.setStartTime(productionProcesses.getStartTime());
+                                    newPro.setEndTime(productionProcesses.getEndTime());
+                                    newPro.setVolumeWidth(productionProcesses.getVolumeWidth());
+                                    newPro.setSinglerollweight(productionProcesses.getSinglerollweight());
+                                    processesList.add(newPro);
+
+                                    productionProcesses.setApsStatus("LS");
+                                }
+                                event.getNewBestSolution().setStepBestProcessesList(processesList);
+                            }
+                            System.out.println("************"+event.getNewBestScore()+"************");
+                            log.info("************"+event.getNewBestScore()+"************");
+
+                            // 终止排程
+//                    solver.terminateEarly();
+                        }
+                    }
+                });
+                SolutionManager<ApsSolution, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
+
                 ApsSolution solvedBalance1 = solver.solve(apsSolution1);
                 log.info("**************排程评分分析***************");
                 ScoreExplanation<ApsSolution, HardSoftScore> explain = scoreManager.explain(solvedBalance1);
@@ -257,11 +306,63 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 }
             }
             if(equass != null && equass.size()>0){
-                equass.forEach((k,processesList1)->{
+                for(Map.Entry<String, List<ProductionProcesses>> entry : equass.entrySet()){
+                    String k = entry.getKey();
+                    List<ProductionProcesses> processesList1 = entry.getValue();
+
                     ApsSolution apsSolution1 = new ApsSolution();
                     apsSolution1.setStartTime(apsSolution.getStartTime());
                     apsSolution1.setProcessesList(processesList1);
                     apsSolution1.setEquipmentList(apsSolution.getEquipmentList());
+
+                    runPlanSeconds = (apsSolution1.getProcessesList().size()/prospeed + 1)*60;
+                    SolverFactory<ApsSolution> solverFactory = SolverFactory.create(new SolverConfig()
+                                    .withEnvironmentMode(mode)
+                                    .withSolutionClass(ApsSolution.class)
+                                    .withEntityClasses(ProductionProcesses.class)
+                                    .withConstraintProviderClass(ApsConstraintProvider.class)
+                                    .withTerminationConfig(new TerminationConfig().withUnimprovedSecondsSpentLimit(120L))
+//                                    .withTerminationSpentLimit(Duration.ofSeconds(runPlanSeconds))
+                                    .withMoveThreadCount(cores)
+                    );
+                    Solver<ApsSolution> solver = solverFactory.buildSolver();
+                    solver.addEventListener(new SolverEventListener<ApsSolution>() {
+                        public void bestSolutionChanged(BestSolutionChangedEvent<ApsSolution> event) {
+                            if(solver.isEveryProblemChangeProcessed()) {
+                                event.getNewBestSolution().setConstructionHeuristicEnd(true);
+                                if(event.getNewBestSolution().getStepBestProcessesList() == null){
+                                    List<ProductionProcesses> processesList = new ArrayList<>();
+//                        List<ProductionProcesses> processesList = ObjectUtil.cloneByStream(event.getNewBestSolution().getProcessesList());
+                                    for (ProductionProcesses productionProcesses : event.getNewBestSolution().getProcessesList()) {
+                                        ProductionProcesses newPro = new ProductionProcesses();
+                                        newPro.setId(productionProcesses.getId());
+                                        newPro.setEquipmentId(productionProcesses.getEquipmentId());
+                                        Equipment eq = new Equipment();
+                                        if(productionProcesses.getEquipment() != null){
+                                            eq.setId(productionProcesses.getEquipment().getId());
+                                        }
+                                        newPro.setEquipment(eq);
+                                        newPro.setProduceTime(productionProcesses.getProduceTime());
+                                        newPro.setStartTime(productionProcesses.getStartTime());
+                                        newPro.setEndTime(productionProcesses.getEndTime());
+                                        newPro.setVolumeWidth(productionProcesses.getVolumeWidth());
+                                        newPro.setSinglerollweight(productionProcesses.getSinglerollweight());
+                                        processesList.add(newPro);
+
+                                        productionProcesses.setApsStatus("LS");
+                                    }
+                                    event.getNewBestSolution().setStepBestProcessesList(processesList);
+                                }
+                                System.out.println("************"+event.getNewBestScore()+"************");
+                                log.info("************"+event.getNewBestScore()+"************");
+
+                                // 终止排程
+//                    solver.terminateEarly();
+                            }
+                        }
+                    });
+                    SolutionManager<ApsSolution, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
+
                     ApsSolution solvedBalance1 = solver.solve(apsSolution1);
                     log.info("**************排程评分分析***************");
                     ScoreExplanation<ApsSolution, HardSoftScore> explain = scoreManager.explain(solvedBalance1);
@@ -275,7 +376,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
 
                     // 排程结束的数据手动添加到设备占用列表中
                     setEqRunTimes(solvedBalance1.getProcessesList());
-                });
+                }
             }
         }