瀏覽代碼

排程优化-退火合并优化

fangpy 9 月之前
父節點
當前提交
dbbea4c311

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

@@ -376,6 +376,12 @@ public class ProductionProcesses implements Serializable {
      */
     private Integer maxheatroll;
 
+    /**
+     * 最大排程开始时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime maxStartTime;
+
 
     public String getEquipmentType() {
         return equipmentType;
@@ -1023,6 +1029,14 @@ public class ProductionProcesses implements Serializable {
         this.mergeRooprocess = mergeRooprocess;
     }
 
+    public LocalDateTime getMaxStartTime() {
+        return maxStartTime;
+    }
+
+    public void setMaxStartTime(LocalDateTime maxStartTime) {
+        this.maxStartTime = maxStartTime;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

+ 8 - 40
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -28,15 +28,13 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 // HARD
                 hasOnePreGbAfterNowNew(constraintFactory),
                 nextLockProNew(constraintFactory),
-//                hasOnePreGbAfterNow(constraintFactory),
-//                nextLockPro(constraintFactory),
                 eqTimeCross(constraintFactory),
                 seriesProduceTimeWait(constraintFactory),
                 seriesProduceWashTimeWait(constraintFactory),
                 equipmentRunTime(constraintFactory),
                 eqTimeCrossTuihuo(constraintFactory),
                 eqTimeCrossMinTuihuo(constraintFactory),
-//                twoLineZz(constraintFactory),
+                maxStartTime(constraintFactory),
                 // MEDIUM
                 deliveryDate(constraintFactory),
                 expecteddays(constraintFactory),
@@ -44,16 +42,10 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 seriesProduceWashingFurnace(constraintFactory),
                 mergeTuihuo(constraintFactory),
                 sameEquipment(constraintFactory),
-
-//                processLzNear(constraintFactory),
-//                processBtNear(constraintFactory),
                 seriesZzLb(constraintFactory),
-
-//                beforeThClose(constraintFactory),
                 // SOFT
                 processNear(constraintFactory),
                 eqTimeCrossMinTuihuoSoft(constraintFactory),
-//                sameBsLzClose(constraintFactory),
                 preNextProcessSameEq(constraintFactory),
         };
     }
@@ -115,47 +107,23 @@ public class ApsConstraintProvider implements ConstraintProvider {
     }
 
     /**
-     * 单卷模式下前后道工序时间约束
+     * 不能超过最大开始时间
      * @param constraintFactory
      * @return
      */
-    private Constraint hasOnePreGbAfterNow(ConstraintFactory constraintFactory) {
+    private Constraint maxStartTime(ConstraintFactory constraintFactory) {
         return constraintFactory.forEach(ProductionProcesses.class)
                 .filter(productionProcesses -> {
                     boolean bln = false;
-                    if(productionProcesses.getPreviousProcesses() != null && productionProcesses.getPreviousProcesses().size()>0){
-                        // 此种情况简化为前道工序只有一个
-                        for (ProductionProcesses previousProcess : productionProcesses.getPreviousProcesses()) {
-                            ProductionProcesses preProcess = previousProcess;
-                            // 流转时间(最小等待时间)
-                            Integer lzTimes = 0;
-                            if(preProcess.getEquipment() != null){
-                                if(preProcess.getEquipment().getWorkshopid() != null && preProcess.getEquipment().getWorkshopid().equals(productionProcesses.getEquipment().getWorkshopid())){
-                                    lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
-                                }else{
-                                    lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
-                                }
-                                // 最小等待时间对比流转时间
-                                if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
-                                    lzTimes = preProcess.getMinWaitTime();
-                                }
-                                // 最大等待时间
-                                Integer maxWaitTime = preProcess.getMaxWaitTime();
-                                if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(lzTimes))<0){
-                                    bln = true;
-                                }
-                                if(maxWaitTime != null && maxWaitTime>0){
-                                    if(productionProcesses.getStartTime().compareTo(preProcess.getEndTime().plusMinutes(maxWaitTime))>0){
-                                        bln = true;
-                                    }
-                                }
-                            }
+                    if(productionProcesses.getMaxStartTime() != null && productionProcesses.getStartTime() != null){
+                        if(productionProcesses.getStartTime().compareTo(productionProcesses.getMaxStartTime())>0){
+                            bln = true;
                         }
                     }
                     return bln;
                 })
-                .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 40)
-                .asConstraint("hasOnePreGbAfterNow");
+                .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 20)
+                .asConstraint("maxStartTime");
     }
 
     /**

+ 2 - 1
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/service/ApsService.java

@@ -7,10 +7,11 @@ import org.optaplanner.core.api.solver.Solver;
 import org.optaplanner.core.api.solver.SolverFactory;
 
 import java.util.List;
+import java.util.Map;
 
 public interface ApsService {
 
-    ApsSolution tuihuoAps(ApsSolution apsSolution);
+    ApsSolution tuihuoAps(ApsSolution apsSolution,Map<String, Map<String,List<ProductionProcesses>>> relPros);
 
     void tuihuoApsSch(ApsSolution apsSolution,List<ProductionProcesses> otherThproces,List<ProductionProcesses> otherNotZzFirstProces,ProductionScheduleVo productionScheduleVo);
 

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

@@ -44,24 +44,26 @@ public class ApsServiceImpl implements ApsService {
      * @return
      */
     @Override
-    public ApsSolution tuihuoAps(ApsSolution apsSolution) {
+    public ApsSolution tuihuoAps(ApsSolution apsSolution,Map<String,Map<String,List<ProductionProcesses>>> relPros) {
         ApsSolution apsSolutionTuihuo = new ApsSolution();
         List<ProductionProcesses> tuihuos = new ArrayList<>();
         for (ProductionProcesses process : apsSolution.getProcessesList()) {
             if((process.getProcessType().equals("成退") || process.getProcessType().equals("中退") || process.getProcessType().equals("小卷成退")) && !process.getIfLock()){
                 List<Integer> preTimes = new ArrayList<>();
-                getAllPreTime(process,preTimes);
+                List<Integer> preMaxTimes = new ArrayList<>();
+                List<Boolean> hasMaxTimes = new ArrayList<>();
+                getAllPreTime(process,preTimes,preMaxTimes,hasMaxTimes);
                 if(preTimes != null && preTimes.size()>0){
                     Integer totaltime = 0;
                     for (Integer preTime : preTimes) {
                         totaltime = totaltime + preTime;
                     }
                     // 松散度
-                    if(process.getApsOverallConfig().getLooseness() != null){
+                    /*if(process.getApsOverallConfig().getLooseness() != null){
                         BigDecimal lostime = process.getApsOverallConfig().getLooseness().multiply(new BigDecimal(totaltime)).divide(new BigDecimal("100"));
                         Integer losinttime = lostime.setScale(0, RoundingMode.CEILING).intValue();
                         totaltime = totaltime + losinttime;
-                    }
+                    }*/
                     totaltime = totaltime + 60*6;
                     // 全局配置
                     ApsOverallConfig apsOverallConfig = new ApsOverallConfig();
@@ -71,10 +73,10 @@ public class ApsServiceImpl implements ApsService {
                         for (ProductionProcesses mergeRooprocess : process.getMergeRooprocess()) {
                             if(mergeRooprocess.getStartTime() != null){
                                 if(startTime == null){
-                                    startTime = mergeRooprocess.getStartTime();
+                                    startTime = mergeRooprocess.getEndTime();
                                 }else{
-                                    if(mergeRooprocess.getStartTime().compareTo(startTime)>0){
-                                        startTime = mergeRooprocess.getStartTime();
+                                    if(mergeRooprocess.getEndTime().compareTo(startTime)>0){
+                                        startTime = mergeRooprocess.getEndTime();
                                     }
                                 }
                             }
@@ -87,6 +89,23 @@ public class ApsServiceImpl implements ApsService {
                     }
                     // 开始时间设置
                     process.setApsOverallConfig(apsOverallConfig);
+                    // 最大开始时间设置
+                    if(hasMaxTimes != null && hasMaxTimes.size()>0 && !hasMaxTimes.contains(false) && process.getMaxWaitTime() != null && process.getMaxWaitTime()>0){
+                        Integer totalMaxtime = 0;
+                        for (Integer preTime : preMaxTimes) {
+                            totalMaxtime = totalMaxtime + preTime;
+                        }
+                        // 松散度
+                        /*if(process.getApsOverallConfig().getLooseness() != null){
+                            BigDecimal lostime = process.getApsOverallConfig().getLooseness().multiply(new BigDecimal(totalMaxtime)).divide(new BigDecimal("100"));
+                            Integer losinttime = lostime.setScale(0, RoundingMode.CEILING).intValue();
+                            totalMaxtime = totalMaxtime + losinttime;
+                        }*/
+                        totalMaxtime = totalMaxtime + 60*6 + process.getMaxWaitTime();
+                        if(startTime != null){
+                            process.setMaxStartTime(startTime.plusMinutes(totalMaxtime));
+                        }
+                    }
                 }
                 tuihuos.add(process);
             }
@@ -94,6 +113,14 @@ public class ApsServiceImpl implements ApsService {
         Collections.sort(tuihuos, (p1,p2)->p2.getApsOverallConfig().getStartTime().compareTo(p1.getApsOverallConfig().getStartTime()));
         // 前后道工序置空
         for (ProductionProcesses tuihuo : tuihuos) {
+            Map<String,List<ProductionProcesses>> a = new HashMap<>();
+            if(tuihuo.getPreviousProcesses() != null && tuihuo.getPreviousProcesses().size()>0){
+                a.put("pres",tuihuo.getPreviousProcesses());
+            }
+            if(tuihuo.getNextProcesses() != null && tuihuo.getNextProcesses().size()>0){
+                a.put("nexts",tuihuo.getNextProcesses());
+            }
+            relPros.put(tuihuo.getId(),a);
             // 前后道工序置空
             tuihuo.setPreviousProcesses(null);
             tuihuo.setNextProcesses(null);
@@ -103,6 +130,44 @@ public class ApsServiceImpl implements ApsService {
         return apsSolutionTuihuo;
     }
 
+    /**
+     * 获取所有前道工序的时间总和
+     * @param process
+     * @param preTimes
+     */
+    private void getAllPreTime(ProductionProcesses process,List<Integer> preTimes,List<Integer> preMaxTimes,List<Boolean> hasMaxTimes){
+        if(process.getPreviousProcesses() != null && process.getPreviousProcesses().size()>0 && !"铸轧".equals(process.getPreviousProcesses().get(0).getProcessType())){
+            Integer lzTime = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
+            if(process.getPreviousProcesses().get(0).getMinWaitTime() != null){
+                if(process.getPreviousProcesses().get(0).getMinWaitTime()>lzTime){
+                    lzTime = process.getPreviousProcesses().get(0).getMinWaitTime();
+                }
+            }
+
+            int pretime = 0;
+            if(process.getPreviousProcesses().get(0).getProcessType().equals("退火")){
+                pretime = process.getPreviousProcesses().get(0).getProduceTime() + lzTime;
+            }else{
+                pretime = process.getPreviousProcesses().get(0).getProduceTime() * process.getPreviousProcesses().size() + lzTime;
+            }
+            preTimes.add(pretime);
+            // 最大等待时间
+            if(process.getPreviousProcesses().get(0).getMaxWaitTime() != null && process.getPreviousProcesses().get(0).getMaxWaitTime()>0){
+                hasMaxTimes.add(true);
+                int preMaxtime = 0;
+                if(process.getPreviousProcesses().get(0).getProcessType().equals("退火")){
+                    preMaxtime = process.getPreviousProcesses().get(0).getProduceTime() + process.getPreviousProcesses().get(0).getMaxWaitTime();
+                }else{
+                    preMaxtime = process.getPreviousProcesses().get(0).getProduceTime() * process.getPreviousProcesses().size() + process.getPreviousProcesses().get(0).getMaxWaitTime();
+                }
+                preMaxTimes.add(preMaxtime);
+            }else{
+                hasMaxTimes.add(false);
+            }
+            getAllPreTime(process.getPreviousProcesses().get(0),preTimes,preMaxTimes,hasMaxTimes);
+        }
+    }
+
     /**
      * 退火
      * @param apsSolution
@@ -124,7 +189,8 @@ public class ApsServiceImpl implements ApsService {
                 }
             }
         }
-        ApsSolution apsSolutionTh = tuihuoAps(apsSolution);
+        Map<String,Map<String,List<ProductionProcesses>>> relPros = new HashMap<>();
+        ApsSolution apsSolutionTh = tuihuoAps(apsSolution,relPros);
         if(otherNotZzFirstProces != null && otherNotZzFirstProces.size()>0){
             // 取消第一道工序非铸轧提前排程的锁定状态
             if(otherNotZzFirstProces != null && otherNotZzFirstProces.size()>0){
@@ -189,19 +255,59 @@ public class ApsServiceImpl implements ApsService {
         log.info(explain1.toString());
         log.info("**************退火排程评分分析***************");
 
-        // 锁定退火工序
-        for (ProductionProcesses process : apsSolution.getProcessesList()) {
-            List<ProductionProcesses> collect = solvedBalance1.getProcessesList().stream().filter(v -> v.getId().equals(process.getId())).collect(Collectors.toList());
-            if(collect != null && collect.size()>0){
-                process.setStartTime(collect.get(0).getStartTime());
-                process.setEndTime(collect.get(0).getEndTime());
-                process.setEquipmentId(collect.get(0).getEquipmentId());
-                process.setEquipment(collect.get(0).getEquipment());
-                process.setDelay(collect.get(0).getDelay());
-                process.setIfLock(true);
+        // 锁定退火工序(根据开始时间分组,多个坯料计划一炉的则锁定,单个坯料计划一炉的总体一起排程)
+        Map<String,List<ProductionProcesses>> thGroup = new HashMap<>();
+        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        for (ProductionProcesses process : solvedBalance1.getProcessesList()) {
+            String thkey = process.getEquipment().getId() + format.format(process.getStartTime());
+            if(thGroup.containsKey(thkey)){
+                thGroup.get(thkey).add(process);
+            }else{
+                List<ProductionProcesses> thpros = new ArrayList<>();
+                thpros.add(process);
+                thGroup.put(thkey,thpros);
             }
         }
 
+        thGroup.forEach((k,v)->{
+            Set<String> orderids = new HashSet<>();
+            for (ProductionProcesses productionProcesses : v) {
+                for (ProduceOrder produceOrder : productionProcesses.getProduceOrder()) {
+                    orderids.add(produceOrder.getId());
+                }
+            }
+            if(orderids.size()>1){
+                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) {
+                            productionProcesses.setStartTime(process.getStartTime());
+                            productionProcesses.setEndTime(process.getEndTime());
+                            productionProcesses.setEquipmentId(process.getEquipmentId());
+                            productionProcesses.setEquipment(process.getEquipment());
+                            productionProcesses.setDelay(process.getDelay());
+                            productionProcesses.setIfLock(true);
+                        }
+                    }
+                }
+            }else{
+                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) {
+                            productionProcesses.getApsOverallConfig().setStartTime(productionProcesses.getRooprocess().getApsOverallConfig().getStartTime());
+                            if(relPros.containsKey(productionProcesses.getId())){
+                                Map<String, List<ProductionProcesses>> stringListMap = relPros.get(productionProcesses.getId());
+                                productionProcesses.setPreviousProcesses(stringListMap.get("pres"));
+                                productionProcesses.setNextProcesses(stringListMap.get("nexts"));
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
+
         // 退火合并工序
         /*if(solvedBalance1.getProcessesList() != null && solvedBalance1.getProcessesList().size()>0){
             Map<String, List<ProductionProcesses>> starttimeProcess = solvedBalance1.getProcessesList().stream()
@@ -364,30 +470,6 @@ public class ApsServiceImpl implements ApsService {
         }
     }
 
-    /**
-     * 获取所有前道工序的时间总和
-     * @param process
-     * @param preTimes
-     */
-    private void getAllPreTime(ProductionProcesses process,List<Integer> preTimes){
-        if(process.getPreviousProcesses() != null && process.getPreviousProcesses().size()>0 && !"铸轧".equals(process.getPreviousProcesses().get(0).getProcessType())){
-            Integer lzTime = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
-            if(process.getPreviousProcesses().get(0).getMinWaitTime() != null){
-                if(process.getPreviousProcesses().get(0).getMinWaitTime()>lzTime){
-                    lzTime = process.getPreviousProcesses().get(0).getMinWaitTime();
-                }
-            }
-            int pretime = 0;
-            if(process.getPreviousProcesses().get(0).getProcessType().equals("退火")){
-                pretime = process.getPreviousProcesses().get(0).getProduceTime() + lzTime;
-            }else{
-                pretime = process.getPreviousProcesses().get(0).getProduceTime() * process.getPreviousProcesses().size() + lzTime;
-            }
-            preTimes.add(pretime);
-            getAllPreTime(process.getPreviousProcesses().get(0),preTimes);
-        }
-    }
-
     /**
      * 求解器初始化
      * @param productionScheduleVo

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

@@ -1388,7 +1388,8 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         List<ProductionProcesses> otherThproces = new ArrayList<>();
 //        ApsSolution apsSolution = getPreApsSolution(productionScheduleVo,otherThproces);
         // 退火提前排序
-        ApsSolution apsSolutionTh = apsService.tuihuoAps(apsSolution);
+        Map<String,Map<String,List<ProductionProcesses>>> relPros = new HashMap<>();
+        ApsSolution apsSolutionTh = apsService.tuihuoAps(apsSolution,relPros);
         if(apsSolutionTh.getProcessesList() != null && apsSolutionTh.getProcessesList().size()>0){
             // 退火工序求解器运行
             int processNum1 = apsSolutionTh.getProcessesList().size();