瀏覽代碼

排程优化

fangpy 10 月之前
父節點
當前提交
0f3fee8f20

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

@@ -410,9 +410,9 @@ public class ProductionProcesses implements Serializable {
         Integer maxDelay = 1;
         if(!this.ifLock){
             if(this.processType.equals("成退") || this.processType.equals("中退") || this.processType.equals("小卷成退")){
-                maxDelay = 200;
+                maxDelay = 300;
             }else if(this.processType.equals("铸轧")){
-                maxDelay = 500;
+                maxDelay = 2000;
             } else if (this.processType.equals("冷轧")) {
                 maxDelay = 2000;
             } else{

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

@@ -520,6 +520,9 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                 if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
                     lzTimes = preProcess.getMinWaitTime();
                 }
+                /*if(process.getMinWaitTime() != null && lzTimes<process.getMinWaitTime()){
+                    lzTimes = process.getMinWaitTime();
+                }*/
             }
 
             // 当前工序最小开始时间、结束时间

+ 47 - 31
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -33,6 +33,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 equipmentRunTime(constraintFactory),
                 eqTimeCrossTuihuo(constraintFactory),
                 eqTimeCrossMinTuihuo(constraintFactory),
+                nextLockPro(constraintFactory),
 //                twoLineZz(constraintFactory),
                 // MEDIUM
                 deliveryDate(constraintFactory),
@@ -151,42 +152,57 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             }
                         }
                     }
-                    /*if(productionProcesses.getMaxWaitTime() != null && productionProcesses.getMaxWaitTime()>0
-                            && (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){
-                                    // 流转时间(最小等待时间)
-                                    Integer lzTimes = 0;
-                                    if(productionProcesses.getEquipment().getWorkshopid() != null && productionProcesses.getEquipment().getWorkshopid().equals(nextProcess.getEquipment().getWorkshopid())){
-                                        lzTimes = nextProcess.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
-                                    }else{
-                                        lzTimes = nextProcess.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
-                                    }
-                                    // 最小等待时间对比流转时间
-                                    if(productionProcesses.getMinWaitTime() != null && lzTimes<productionProcesses.getMinWaitTime()){
-                                        lzTimes = productionProcesses.getMinWaitTime();
-                                    }
-                                    // 最大等待时间
-                                    Integer maxWaitTime = productionProcesses.getMaxWaitTime();
-                                    if(nextProcess.getStartTime().compareTo(productionProcesses.getEndTime().plusMinutes(lzTimes))<0){
-                                        bln = true;
-                                    }
-                                    if(maxWaitTime != null && maxWaitTime>0){
-                                        if(nextProcess.getStartTime().compareTo(productionProcesses.getEndTime().plusMinutes(maxWaitTime))>0){
-                                            bln = true;
-                                        }
-                                    }
+                    return bln;
+                })
+                .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 40)
+                .asConstraint("hasOnePreGbAfterNow");
+    }
+
+    /**
+     * 下道工序如果是锁定工序则判断是否下道工序时间在当前工序之后
+     * @param constraintFactory
+     * @return
+     */
+    private Constraint nextLockPro(ConstraintFactory constraintFactory) {
+        return constraintFactory.forEach(ProductionProcesses.class)
+                .filter(productionProcesses -> {
+                    boolean bln = false;
+                    List<ProductionProcesses> nextProcesses = productionProcesses.getNextProcesses();
+                    if(nextProcesses != null && nextProcesses.size()>0){
+                        if(nextProcesses.get(0).getIfLock()){
+                            // 当前工序结束时间
+                            LocalDateTime preEndTime = productionProcesses.getEndTime();
+                            // 获取下道工序最早开始时间
+                            LocalDateTime earlyStartTime = null;
+                            for (ProductionProcesses nextProcess : nextProcesses) {
+                                // 下道工序开始时间
+                                LocalDateTime startTime = nextProcess.getStartTime();
+                                // 流转时间(最小等待时间)
+                                Integer lzTimes = 0;
+                                if(productionProcesses.getEquipment().getWorkshopid() != null && productionProcesses.getEquipment().getWorkshopid().equals(nextProcess.getEquipment().getWorkshopid())){
+                                    lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_IN");
+                                }else{
+                                    lzTimes = productionProcesses.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
+                                }
+                                // 最小等待时间对比流转时间
+                                if(productionProcesses.getMinWaitTime() != null && lzTimes<productionProcesses.getMinWaitTime()){
+                                    lzTimes = productionProcesses.getMinWaitTime();
+                                }
+                                if(preEndTime.plusMinutes(lzTimes).compareTo(startTime)>0){
+                                    bln = true;
+                                }
+                                // 最大等待时间
+                                Integer maxWaitTime = productionProcesses.getMaxWaitTime();
+                                if(maxWaitTime != null && maxWaitTime>0 && preEndTime.plusMinutes(maxWaitTime).compareTo(startTime)<0){
+                                    bln = true;
                                 }
                             }
                         }
-                    }*/
+                    }
                     return bln;
                 })
-                .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 40)
-                .asConstraint("hasOnePreGbAfterNow");
+                .penalize(HardMediumSoftScore.ONE_HARD,(productionProcesses) -> 30)
+                .asConstraint("nextLockPro");
     }
 
     /**

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

@@ -28,6 +28,7 @@ import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.Duration;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -248,9 +249,32 @@ public class ApsServiceImpl implements ApsService {
                             }
 
                             List<List<ProductionProcesses>> chunks = new ArrayList<>();
-                            int listSize = v.size();
-                            for (int i = 0; i < listSize; i += a) {
-                                chunks.add(v.subList(i, Math.min(i + a, listSize)));
+                            if(v.get(0).getIfLock()){
+                                Collections.sort(v,(p1,p2)->{
+                                    return p1.getStartTime().compareTo(p2.getStartTime());
+                                });
+                                Map<String, List<ProductionProcesses>> map = new TreeMap<>();
+                                for (ProductionProcesses productionProcesses : v) {
+                                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                                    String startStr = productionProcesses.getStartTime().format(formatter);
+                                    if(map.containsKey(startStr)){
+                                        map.get(startStr).add(productionProcesses);
+                                    }else{
+                                        List<ProductionProcesses> b = new ArrayList<>();
+                                        b.add(productionProcesses);
+                                        map.put(startStr,b);
+                                    }
+                                }
+                                if(map != null && map.size()>0){
+                                    for (Map.Entry<String, List<ProductionProcesses>> entry : map.entrySet()) {
+                                        chunks.add(entry.getValue());
+                                    }
+                                }
+                            }else {
+                                int listSize = v.size();
+                                for (int i = 0; i < listSize; i += a) {
+                                    chunks.add(v.subList(i, Math.min(i + a, listSize)));
+                                }
                             }
                             // 合并退火作业
                             for(int j = 0;j < chunks.size();j++){
@@ -456,8 +480,13 @@ public class ApsServiceImpl implements ApsService {
                                 }
                                 // 合并退火作业
                                 for (List<ProductionProcesses> thps : chunks) {
+                                    ProductionProcesses mergePro = thps.get(0);
+                                    List<String> mergeProOrders = new ArrayList<>();
+                                    mergeProOrders.add(mergePro.getId());
+                                    mergePro.setMergeProOrders(mergeProOrders);
                                     for (int i = 0; i < thps.size(); i++) {
                                         if(i>0){
+                                            mergePro.getMergeProOrders().add(thps.get(i).getId());
                                             // 设置待合并退火的主ID
                                             thps.get(i).setMergeThMainId(thps.get(0).getId());
                                             notMergeProces.add(thps.get(i));
@@ -519,7 +548,6 @@ public class ApsServiceImpl implements ApsService {
                                         }
                                     }
                                     // 取第一个作业作为合并作业
-                                    ProductionProcesses mergePro = thps.get(0);
                                     mergePro.setOpeProducePcNum(thps.size());
                                     mergePro.setProduceTime(mergePro.getProduceTime()*thps.size());
                                     othermergeprocesses.add(mergePro);

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

@@ -226,11 +226,35 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         }
 
         solvedBalance.getProcessesList().addAll(hasLocks);
-        log.info("**************排程最终评分分析***************");
+        /*log.info("**************排程最终评分分析***************");
+        if(notLocks != null && notLocks.size()>0){
+            for (ProductionProcesses notLock : notLocks) {
+                for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
+                    if(notLock.getId().equals(productionProcesses.getId())){
+                        notLock.setEquipment(productionProcesses.getEquipment());
+                        notLock.setEquipmentId(productionProcesses.getEquipmentId());
+                        notLock.setDelay(productionProcesses.getDelay());
+                        notLock.setStartTime(productionProcesses.getStartTime());
+                        notLock.setEndTime(productionProcesses.getEndTime());
+                    }
+                }
+            }
+        }
+        for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
+            if(productionProcesses.getDelay() == null){
+                if(productionProcesses.getIfLock()){
+                    productionProcesses.setIfLock(false);
+                    productionProcesses.setDelay(0);
+                    productionProcesses.setIfLock(true);
+                }else{
+                    productionProcesses.setDelay(0);
+                }
+            }
+        }
         ScoreExplanation<ApsSolution, HardSoftScore> explain2 = scoreManager.explain(solvedBalance);
         log.info(explain2.toString());
-        log.info("**************排程最终评分分析***************");
-        softExplain(explain2,solvedBalance.getProcessesList());
+        log.info("**************排程最终评分分析***************");*/
+        softExplain(explain,solvedBalance.getProcessesList());
 
         productionScheduleRetVo.setProcesses(solvedBalance.getProcessesList());
         // 循环引用ProductionProcesses置空
@@ -913,69 +937,80 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
             List<EquipmentRunTime> equipmentRunTimesMerge = new ArrayList<>();
             List<EquipmentRunTime> equipmentRunTimes = equipment.getEquipmentRunTimes();
             if(equipmentRunTimes != null && equipmentRunTimes.size()>0){
-                if("成退,中退,小卷成退".contains(equipmentRunTimes.get(0).getProcessType())){
+                boolean hasMerge = false;
+                for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
+                    if("maintenance".equals(equipmentRunTime.getOccupyType())){
+                        equipmentRunTimesMerge.add(equipmentRunTime);
+                    }else{
+                        if("成退,中退,小卷成退".contains(equipmentRunTime.getProcessType())){
+                            hasMerge = true;
+                            break;
+                        }
+                    }
+                }
+                if(hasMerge) {
                     for (EquipmentRunTime equipmentRunTime : equipmentRunTimes) {
-                        if("maintenance".equals(equipmentRunTime.getOccupyType())){
+                        if ("maintenance".equals(equipmentRunTime.getOccupyType())) {
                             equipmentRunTimesMerge.add(equipmentRunTime);
-                        }else{
+                        } else {
                             boolean isMerged = false;
                             String groupname = null;
                             for (ApsFurnaceInstallationDo furnaceInstallation : productionScheduleVo.getFurnaceInstallations()) {
-                                if(equipmentRunTime.getVolumeMetal().equals(furnaceInstallation.getAlloy())){
+                                if (equipmentRunTime.getVolumeMetal().equals(furnaceInstallation.getAlloy())) {
                                     boolean a = true;
-                                    if((furnaceInstallation.getAlloystatus() != null && equipmentRunTime.getVolumeMetalstate() != null && furnaceInstallation.getAlloystatus().contains(equipmentRunTime.getVolumeMetalstate()))
-                                            || (furnaceInstallation.getAlloystatus() == null && equipmentRunTime.getVolumeMetalstate() == null)){
+                                    if ((furnaceInstallation.getAlloystatus() != null && equipmentRunTime.getVolumeMetalstate() != null && furnaceInstallation.getAlloystatus().contains(equipmentRunTime.getVolumeMetalstate()))
+                                            || (furnaceInstallation.getAlloystatus() == null && equipmentRunTime.getVolumeMetalstate() == null)) {
                                         a = true;
-                                    }else{
+                                    } else {
                                         a = false;
                                     }
-                                    if(furnaceInstallation.getStartthickness() != null && furnaceInstallation.getStartthickness().compareTo(equipmentRunTime.getTotalThickness())>0){
+                                    if (furnaceInstallation.getStartthickness() != null && furnaceInstallation.getStartthickness().compareTo(equipmentRunTime.getTotalThickness()) > 0) {
                                         a = false;
                                     }
-                                    if(furnaceInstallation.getEndthickness() != null && furnaceInstallation.getEndthickness().compareTo(equipmentRunTime.getTotalThickness())<0){
+                                    if (furnaceInstallation.getEndthickness() != null && furnaceInstallation.getEndthickness().compareTo(equipmentRunTime.getTotalThickness()) < 0) {
                                         a = false;
                                     }
-                                    if(furnaceInstallation.getStartwidth() != null && new BigDecimal(furnaceInstallation.getStartwidth()).compareTo(equipmentRunTime.getTotalVolumeWidth())>0){
+                                    if (furnaceInstallation.getStartwidth() != null && new BigDecimal(furnaceInstallation.getStartwidth()).compareTo(equipmentRunTime.getTotalVolumeWidth()) > 0) {
                                         a = false;
                                     }
-                                    if(furnaceInstallation.getEndwidth() != null && new BigDecimal(furnaceInstallation.getEndwidth()).compareTo(equipmentRunTime.getTotalVolumeWidth())<0){
+                                    if (furnaceInstallation.getEndwidth() != null && new BigDecimal(furnaceInstallation.getEndwidth()).compareTo(equipmentRunTime.getTotalVolumeWidth()) < 0) {
                                         a = false;
                                     }
-                                    if(a){
+                                    if (a) {
                                         groupname = furnaceInstallation.getId();
                                         break;
                                     }
                                 }
                             }
-                            if(groupname == null){
+                            if (groupname == null) {
                                 groupname = "group-self-" + equipmentRunTime.getVolumeMetal() + equipmentRunTime.getVolumeMetalstate() + equipmentRunTime.getProducttype() + equipmentRunTime.getTotalVolumeWidth() + equipmentRunTime.getTotalThickness();
                             }
                             Set<String> minThGroupNames = new HashSet<>();
                             minThGroupNames.add(groupname);
                             for (EquipmentRunTime runTime : equipmentRunTimesMerge) {
                                 // 时间相等
-                                if(runTime.getStartRunTime().compareTo(equipmentRunTime.getStartRunTime())==0){
+                                if (runTime.getStartRunTime().compareTo(equipmentRunTime.getStartRunTime()) == 0) {
                                     runTime.setTotalVolumeWidth(runTime.getTotalVolumeWidth().add(equipmentRunTime.getTotalVolumeWidth()));
                                     runTime.setTotalSinglerollweight(runTime.getTotalSinglerollweight().add(equipmentRunTime.getTotalSinglerollweight()));
                                     // 最大、最小宽度
-                                    if(equipmentRunTime.getTotalVolumeWidth().compareTo(runTime.getMinVolumeWidth())<0){
+                                    if (equipmentRunTime.getTotalVolumeWidth().compareTo(runTime.getMinVolumeWidth()) < 0) {
                                         runTime.setMinVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
                                     }
-                                    if(equipmentRunTime.getTotalVolumeWidth().compareTo(runTime.getMaxVolumeWidth())>0){
+                                    if (equipmentRunTime.getTotalVolumeWidth().compareTo(runTime.getMaxVolumeWidth()) > 0) {
                                         runTime.setMaxVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
                                     }
                                     // 最大、最小厚度
-                                    if(equipmentRunTime.getTotalThickness().compareTo(runTime.getMinThickness())<0){
+                                    if (equipmentRunTime.getTotalThickness().compareTo(runTime.getMinThickness()) < 0) {
                                         runTime.setMinThickness(equipmentRunTime.getTotalThickness());
                                     }
-                                    if(equipmentRunTime.getTotalThickness().compareTo(runTime.getMaxThickness())>0){
+                                    if (equipmentRunTime.getTotalThickness().compareTo(runTime.getMaxThickness()) > 0) {
                                         runTime.setMaxThickness(equipmentRunTime.getTotalThickness());
                                     }
                                     // 最大、最小重量
-                                    if(equipmentRunTime.getTotalSinglerollweight().compareTo(runTime.getMinSinglerollweight())<0){
+                                    if (equipmentRunTime.getTotalSinglerollweight().compareTo(runTime.getMinSinglerollweight()) < 0) {
                                         runTime.setMinSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
                                     }
-                                    if(equipmentRunTime.getTotalSinglerollweight().compareTo(runTime.getMaxSinglerollweight())>0){
+                                    if (equipmentRunTime.getTotalSinglerollweight().compareTo(runTime.getMaxSinglerollweight()) > 0) {
                                         runTime.setMaxSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
                                     }
                                     runTime.getMinThGroupNames().addAll(minThGroupNames);
@@ -983,7 +1018,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                                     break;
                                 }
                             }
-                            if(!isMerged){
+                            if (!isMerged) {
                                 equipmentRunTime.setMinVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
                                 equipmentRunTime.setMaxVolumeWidth(equipmentRunTime.getTotalVolumeWidth());
                                 equipmentRunTime.setMinThickness(equipmentRunTime.getTotalThickness());

+ 2 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/util/ApsConstants.java

@@ -20,6 +20,7 @@ public class ApsConstants {
         constraintDesc.put("equipmentRunTime","加工设备该加工时间段不可用");
         constraintDesc.put("lzTimeLessMaxWait","作业流转时间超出上道工序作业最大等待时间限制");
         constraintDesc.put("eqTimeCross","与加工设备其他作业加工时间重叠");
+        constraintDesc.put("nextLockPro","与下道工序开始时间不符合规则");
 //        constraintDesc.put("seriesProduceTimeWait","没有预留足够的上机准备时间和下机收尾时间");
         constraintDesc.put("deliveryDate","不满足订单交货期");
 //        constraintDesc.put("seriesProduce","与上道工序作业不能连续生产");
@@ -30,6 +31,7 @@ public class ApsConstants {
         hardConstraint.add("equipmentRunTime");
         hardConstraint.add("lzTimeLessMaxWait");
         hardConstraint.add("eqTimeCross");
+        hardConstraint.add("nextLockPro");
         hardConstraint.add("seriesProduceTimeWait");
     }