Bladeren bron

退火炉合并排程算法优化

fangpy 11 maanden geleden
bovenliggende
commit
9085c9b349

+ 8 - 2
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/ApsBalancingApplication.java

@@ -143,7 +143,7 @@ public class ApsBalancingApplication {
         System.out.println(a.intValue());*/
 
 //        System.out.println(new BigDecimal(40).divide(new BigDecimal(10.9), 2, RoundingMode.HALF_UP).intValue());
-        Integer a1 = 1;
+        /*Integer a1 = 1;
         Integer a2 = 2;
         List<Integer> list = new ArrayList<>();
         list.add(a1);list.add(a2);
@@ -154,7 +154,13 @@ public class ApsBalancingApplication {
         Collections.sort(list,(v1,v2)->{
             return v2.compareTo(v1);
         });
-        System.out.println(list);
+        System.out.println(list);*/
+
+        /*String a = null;
+        System.out.println("123"+a);*/
+        List<String> a = new ArrayList<>();
+        a.add("1");a.add("2");a.add("3");
+        System.out.println(a.indexOf("2"));
     }
 
 

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

@@ -213,7 +213,10 @@ public class ProductionProcesses implements Serializable {
      * 上一个工步ID
      */
     private List<String> previousProcessesIds;
-
+    /**
+     * 合并退火前上一个工步ID
+     */
+    private List<String> oldPreviousProcessesIds;
     /**
      * 下一个工步
      */
@@ -222,7 +225,10 @@ public class ProductionProcesses implements Serializable {
      * 下一个工步ID
      */
     private List<String> nextProcessesIds;
-
+    /**
+     * 合并退火前下一个工步ID
+     */
+    private List<String> oldNextProcessesIds;
     /**
      * APS排程全局配置
      */
@@ -307,6 +313,16 @@ public class ProductionProcesses implements Serializable {
      */
     private BigDecimal lastSerialLbWeight;
 
+    /**
+     * 合并退火的主ID
+     */
+    private String mergeThMainId;
+
+    /**
+     * 根结点
+     */
+    private ProductionProcesses rooprocess;
+
     private Map<String, String> conflictRoptions;
 
     public String getEquipmentType() {
@@ -817,6 +833,38 @@ public class ProductionProcesses implements Serializable {
         this.opeProducePcNum = opeProducePcNum;
     }
 
+    public ProductionProcesses getRooprocess() {
+        return rooprocess;
+    }
+
+    public void setRooprocess(ProductionProcesses rooprocess) {
+        this.rooprocess = rooprocess;
+    }
+
+    public String getMergeThMainId() {
+        return mergeThMainId;
+    }
+
+    public void setMergeThMainId(String mergeThMainId) {
+        this.mergeThMainId = mergeThMainId;
+    }
+
+    public List<String> getOldPreviousProcessesIds() {
+        return oldPreviousProcessesIds;
+    }
+
+    public void setOldPreviousProcessesIds(List<String> oldPreviousProcessesIds) {
+        this.oldPreviousProcessesIds = oldPreviousProcessesIds;
+    }
+
+    public List<String> getOldNextProcessesIds() {
+        return oldNextProcessesIds;
+    }
+
+    public void setOldNextProcessesIds(List<String> oldNextProcessesIds) {
+        this.oldNextProcessesIds = oldNextProcessesIds;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

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

@@ -510,11 +510,11 @@ public class TaskStartTimeListener implements VariableListener<ApsSolution, Prod
                     lzTimes = process.getApsOverallConfig().getRoamTime().get("WORKSHOP_CROSS");
                 }
                 // 松散度
-                if(preProcess.getApsOverallConfig().getLooseness() != null){
+                /*if(preProcess.getApsOverallConfig().getLooseness() != null){
                     BigDecimal lostime = preProcess.getApsOverallConfig().getLooseness().multiply(new BigDecimal(preProcess.getProduceTime())).divide(new BigDecimal("100"));
                     Integer losinttime = lostime.setScale(0, RoundingMode.CEILING).intValue();
                     lzTimes = lzTimes + losinttime;
-                }
+                }*/
                 // 最小等待时间对比流转时间
                 if(preProcess.getMinWaitTime() != null && lzTimes<preProcess.getMinWaitTime()){
                     lzTimes = preProcess.getMinWaitTime();

+ 14 - 4
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -1282,6 +1282,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
             }
             // 重量、宽度、厚度要满足一定规则
             else{
+                if(processTypeSet.contains("小卷成退")){
+                    continue;
+                }
                 String processType = v.get(0).getProcessType();
                 BigDecimal btVolumeWidth = null;
                 BigDecimal btVolumeThickness = null;
@@ -1821,7 +1824,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             return false;
                         }
                     }else{
-                        ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
+                        /*ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
                         // 流转时间
                         Integer lzTimes = 0;
                         if(preProcess != null && preProcess.getEquipment() != null){
@@ -1839,12 +1842,19 @@ public class ApsConstraintProvider implements ConstraintProvider {
                                 return true;
                             }
                         }
-                        return false;
+                        return false;*/
+                        if(process.getStartTime() != null){
+                            return true;
+                        }else{
+                            return false;
+                        }
                     }
                 })
                 .penalize(HardMediumSoftScore.ONE_SOFT,(process) -> {
                     int processNearNum = 0;
-                    if(process.getPreviousProcesses() == null || process.getPreviousProcesses().size() == 0){
+                    processNearNum = (int)ChronoUnit.MINUTES.between(process.getApsOverallConfig().getStartTime(), process.getStartTime());
+
+                    /*if(process.getPreviousProcesses() == null || process.getPreviousProcesses().size() == 0){
                         processNearNum = (int)ChronoUnit.MINUTES.between(process.getApsOverallConfig().getStartTime(), process.getStartTime());
                     }else{
                         ProductionProcesses preProcess = process.getPreviousProcesses().get(0);
@@ -1863,7 +1873,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                         }
                         LocalDateTime minStartTime = preProcess.getEndTime().plusMinutes(lzTimes);
                         processNearNum = (int)ChronoUnit.MINUTES.between(minStartTime, process.getStartTime());
-                    }
+                    }*/
                     return processNearNum;
                 })
                 .asConstraint("processNear");

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

@@ -14,7 +14,7 @@ public interface ApsService {
 
     SolverFactory<ApsSolution> solverInit(ProductionScheduleVo productionScheduleVo);
 
-    List<ProductionProcesses> thProcessMerge(ProductionScheduleVo productionScheduleVo,List<ProductionProcesses> otherThproces);
+    List<ProductionProcesses> thProcessMerge(ProductionScheduleVo productionScheduleVo,ApsSolution apsSolution,List<ProductionProcesses> otherThproces);
 
     List<ProductionProcesses> zzProcessAps(ProductionScheduleVo productionScheduleVo,ApsSolution apsSolution);
 

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

@@ -172,15 +172,17 @@ public class ApsServiceImpl implements ApsService {
      * @return
      */
     @Override
-    public List<ProductionProcesses> thProcessMerge(ProductionScheduleVo productionScheduleVo,List<ProductionProcesses> otherThproces){
-        List<ProductionProcesses> processes = productionScheduleVo.getProcesses();
+    public List<ProductionProcesses> thProcessMerge(ProductionScheduleVo productionScheduleVo,ApsSolution apsSolution,List<ProductionProcesses> otherThproces){
+        List<ProductionProcesses> processes = apsSolution.getProcessesList();
         // 设备集合
-        List<Equipment> equipmentList = productionScheduleVo.getEquipmentList();
+        List<Equipment> equipmentList = apsSolution.getEquipmentList();
         List<ProductionProcesses> mergeprocesses = new ArrayList<>();
         // 所有作业集合
         Map<String,ProductionProcesses> allProMap = new HashMap<>();
         // 退火作业集合
         Map<String,List<ProductionProcesses>> thproMap = new HashMap<>();
+        // 其它作业集合
+        Map<String,List<ProductionProcesses>> notthproMap = new HashMap<>();
         for (ProductionProcesses process : processes) {
             if("成退".equals(process.getProcessType()) || "中退".equals(process.getProcessType()) || "小卷成退".equals(process.getProcessType())){
                 String bsproid = process.getBsProcessesId().get(0);
@@ -192,6 +194,14 @@ public class ApsServiceImpl implements ApsService {
                 thproMap.put(bsproid,bsprocess);
             }else{
                 mergeprocesses.add(process);
+
+                String bsproid = process.getBsProcessesId().get(0);
+                List<ProductionProcesses> bsprocess = thproMap.get(bsproid);
+                if(bsprocess == null){
+                    bsprocess = new ArrayList<>();
+                }
+                bsprocess.add(process);
+                notthproMap.put(bsproid,bsprocess);
             }
             allProMap.put(process.getId(),process);
         }
@@ -219,6 +229,12 @@ 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());
+                            });
+                        }
+
                         List<List<ProductionProcesses>> chunks = new ArrayList<>();
                         int listSize = v.size();
                         for (int i = 0; i < listSize; i += a) {
@@ -228,22 +244,67 @@ public class ApsServiceImpl implements ApsService {
                         for (List<ProductionProcesses> thps : chunks) {
                             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));
                                     // 退火前一道作业设置下一作业ID
                                     ProductionProcesses prepro = allProMap.get(thps.get(i).getPreviousProcessesIds().get(0));
-                                    List<String> nextids = new ArrayList<>();
-                                    nextids.add(thps.get(0).getId());
-                                    prepro.setNextProcessesIds(nextids);
-                                    thps.get(0).getPreviousProcessesIds().add(prepro.getId());
+                                    // 历史关联关系备份
+                                    List<String> oldNextProcessesIds = new ArrayList<>();
+                                    oldNextProcessesIds.addAll(prepro.getNextProcessesIds());
+                                    prepro.setOldNextProcessesIds(oldNextProcessesIds);
+                                    // 合并后关联关系重置
+                                    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> oldpreids = new ArrayList<>();
+                                            oldpreids.addAll(nextpro.getPreviousProcessesIds());
+                                            nextpro.setOldPreviousProcessesIds(oldpreids);
+                                            // 合并后关联关系重置
                                             List<String> preids = new ArrayList<>();
                                             preids.add(thps.get(0).getId());
                                             nextpro.setPreviousProcessesIds(preids);
+
+                                            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("小卷退火")){

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

@@ -122,7 +122,9 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         /*if(1 == 1){
             return null;
         }*/
-
+        // 退火合并
+        List<ProductionProcesses> thList = apsService.thProcessMerge(productionScheduleVo,apsSolution,otherThproces);
+        apsSolution.setProcessesList(thList);
         // 去掉锁定工序
         List<ProductionProcesses> notLocks = new ArrayList<>();
         List<ProductionProcesses> hasLocks = new ArrayList<>();
@@ -139,6 +141,8 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
             throw new ApsException("没有可排程的工序");
         }
         apsSolution.setProcessesList(notLocks);
+
+        sortProcess(apsSolution.getProcessesList());
         ApsSolution solvedBalance = solver.solve(apsSolution);
         log.info("**************排程评分分析***************");
         SolutionManager<ApsSolution, HardSoftScore> scoreManager = SolutionManager.create(solverFactory);
@@ -191,34 +195,45 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
 //        solvedBalance.getProcessesList().addAll(solvedBalance1.getProcessesList());
         if(otherThproces != null && otherThproces.size()>0){
             for (ProductionProcesses otherThproce : otherThproces) {
-                String preid = otherThproce.getPreviousProcessesIds().get(0);
-                ProductionProcesses pres = null;
-                for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
-                    if(productionProcesses.getId().equals(preid)){
-                        pres = productionProcesses;
-                        break;
+                if(StrUtil.isNotBlank(otherThproce.getMergeThMainId())){
+                    ProductionProcesses thpro = null;
+                    for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
+                        if(productionProcesses.getId().equals(otherThproce.getMergeThMainId())){
+                            thpro = productionProcesses;
+                            break;
+                        }
                     }
-                }
-                if(pres.getNextProcesses() != null && pres.getNextProcesses().size()>0){
-                    ProductionProcesses thpro = pres.getNextProcesses().get(0);
-                    otherThproce.setStartTime(thpro.getStartTime());
-                    otherThproce.setEndTime(thpro.getEndTime());
-                    otherThproce.setEquipmentId(thpro.getEquipmentId());
-                    otherThproce.setEquipment(thpro.getEquipment());
-                    otherThproce.setConflictRoptions(thpro.getConflictRoptions());
+                    if(thpro != null){
+                        otherThproce.setStartTime(thpro.getStartTime());
+                        otherThproce.setEndTime(thpro.getEndTime());
+                        otherThproce.setEquipmentId(thpro.getEquipmentId());
+                        otherThproce.setEquipment(thpro.getEquipment());
+                        otherThproce.setConflictRoptions(thpro.getConflictRoptions());
 
-                    thpro.setOpeProducePcNum(1);
-                    List<String> preids = new ArrayList<>();
-                    preids.add(thpro.getPreviousProcessesIds().get(0));
-                    thpro.setPreviousProcessesIds(preids);
-                    if(thpro.getNextProcessesIds() != null && thpro.getNextProcessesIds().size()>0){
-                        List<String> nextids = new ArrayList<>();
-                        nextids.add(thpro.getNextProcessesIds().get(0));
-                        thpro.setNextProcessesIds(nextids);
-                    }
-                    if(thpro.getProcessType().equals("小卷成退")){
-                        thpro.setMinThPcNum(thpro.getMinThPcNum()-otherThproce.getMinThPcNum());
+                        thpro.setOpeProducePcNum(1);
+                        List<String> preids = new ArrayList<>();
+                        preids.add(thpro.getPreviousProcessesIds().get(0));
+                        thpro.setPreviousProcessesIds(preids);
+                        if(thpro.getNextProcessesIds() != null && thpro.getNextProcessesIds().size()>0){
+                            for (String nextProcessesId : otherThproce.getNextProcessesIds()) {
+                                int i = thpro.getNextProcessesIds().indexOf(nextProcessesId);
+                                if(i>=0){
+                                    thpro.getNextProcessesIds().remove(i);
+                                }
+                            }
+                        }
+                        /*if(otherThproce.getPreviousProcesses() != null && otherThproce.getPreviousProcesses().size()>0){
+                            for (ProductionProcesses previousProcess : otherThproce.getPreviousProcesses()) {
+                                List<String> nextids = new ArrayList<>();
+                                nextids.add(otherThproce.getId());
+                                previousProcess.setNextProcessesIds(nextids);
+                            }
+                        }*/
+                        if(thpro.getProcessType().equals("小卷成退")){
+                            thpro.setMinThPcNum(thpro.getMinThPcNum()-otherThproce.getMinThPcNum());
+                        }
                     }
+
                 }
             }
         }
@@ -226,6 +241,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         solvedBalance.getProcessesList().addAll(otherThproces);
         for (ProductionProcesses productionProcesses : solvedBalance.getProcessesList()) {
             productionProcesses.setPreviousProcesses(null);
+            productionProcesses.setRooprocess(null);
             productionProcesses.setNextProcesses(null);
             productionProcesses.getEquipment().setProcessesList(null);
             productionProcesses.getEquipment().setEquipmentRunTimes(null);
@@ -235,6 +251,12 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 productionProcesses.getApsOverallConfig().setFurnaceInstallations(null);
                 productionProcesses.getApsOverallConfig().setMergeFurnaces(null);
             }
+            if(productionProcesses.getOldNextProcessesIds() != null){
+                productionProcesses.setNextProcessesIds(productionProcesses.getOldNextProcessesIds());
+            }
+            if(productionProcesses.getOldPreviousProcessesIds() != null){
+                productionProcesses.setPreviousProcessesIds(productionProcesses.getOldPreviousProcessesIds());
+            }
             // 冲突约束补充处理
             if(productionProcesses.getConflictRoptions() != null && productionProcesses.getConflictRoptions().size()>0){
                 productionProcesses.getConflictRoptions().forEach((k,v)->{
@@ -683,8 +705,8 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         for (ProductionProcesses process : productionScheduleVo.getProcesses()) {
             idMaps.put(String.join(",",process.getId()),process);
         }
-        List<ProductionProcesses> thList = apsService.thProcessMerge(productionScheduleVo,otherThproces);
-        productionScheduleVo.setProcesses(thList);
+        /*List<ProductionProcesses> thList = apsService.thProcessMerge(productionScheduleVo,otherThproces);
+        productionScheduleVo.setProcesses(thList);*/
         for (ProductionProcesses process : productionScheduleVo.getProcesses()) {
             // 全局配置设置
             if(process.getApsOverallConfig() == null){
@@ -914,6 +936,10 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                     }
                 }
                 if(roots != null && roots.size()>0){
+                    //设置下一节点的根目录
+                    for (ProductionProcesses root : roots) {
+                        setNextProRoot(root,root);
+                    }
                     ProductionProcesses rootPro = roots.get(0);
                     nextProSort(sortMap,bsMap,rootPro.getUniqueBsProcessesId());
                 }
@@ -938,6 +964,18 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         return processes;
     }
 
+    /**
+     * 递归设置下一道工序的根节点
+     */
+    private void setNextProRoot(ProductionProcesses root,ProductionProcesses nowpro){
+        if(nowpro.getNextProcesses() != null && nowpro.getNextProcesses().size()>0){
+            for (ProductionProcesses nextProcess : nowpro.getNextProcesses()) {
+                nextProcess.setRooprocess(root);
+                setNextProRoot(root,nextProcess);
+            }
+        }
+    }
+
     private void nextProSort(Map<String,Integer> sortMap,Map<String,List<ProductionProcesses>> bsMap,String uniqueBsProcessesId){
         List<ProductionProcesses> processesList1 = bsMap.get(uniqueBsProcessesId);
         if(processesList1 != null && processesList1.size()>0){