Browse Source

调度排程优化

fangpy 5 months ago
parent
commit
3506578289

+ 1 - 1
pom.xml

@@ -39,7 +39,7 @@
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
-            <version>4.0.1</version>
+            <version>5.8.36</version>
         </dependency>
     </dependencies>
 

+ 7 - 3
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -695,7 +695,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
         if(equipment.getLxzTime() != null){
             lzlxstarttime = equipment.getLxzTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
         }else{
-            lzlxstarttime = hasStartTimeProcess.get(0).getStartTime();
+            lzlxstarttime = hasStartTimeProcess.get(0).getEndTime();
         }
         int huzq = 60*8;
         for(int i=0;i<hasStartTimeProcess.size()-1;i++){
@@ -746,6 +746,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 String preZg = prepro.getProZg();
                 String nextZg = nextpro.getProZg();
                 if(!preZg.equals(nextZg)){
+                    if(lzlxstarttime == null || hasStartTimeProcess.get(i+1) == null || hasStartTimeProcess.get(i+1).getStartTime() == null){
+                        int m = 1;
+                    }
                     if(lzlxstarttime.plusMinutes(huzq).compareTo(hasStartTimeProcess.get(i+1).getStartTime())>0){
                         // 只有存在当前排程的作业才会记录扣分数
                         if(nextPro.getId() != null){
@@ -2225,6 +2228,7 @@ public class ApsConstraintProvider implements ConstraintProvider {
                     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.setSinglerollweight(equipmentRunTime.getTotalSinglerollweight());
@@ -2264,9 +2268,9 @@ public class ApsConstraintProvider implements ConstraintProvider {
                         if("铸轧".equals(hasStartTimeProcess.get(i).getProcessType())){
 //                            b = b+15;
                         }else if ("冷轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
-                            b = b+10;
+//                            b = b+10;
                         }else if ("箔轧".equals(hasStartTimeProcess.get(i).getProcessType())) {
-                            b = b+5;
+//                            b = b+5;
                         }
 
                     }

+ 11 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/service/DdApsService.java

@@ -0,0 +1,11 @@
+package com.rongwei.rwapsserver.aps.service;
+
+import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
+
+import java.util.List;
+
+public interface DdApsService {
+    List<ProductionProcesses> thOtherMerge(List<ProductionProcesses> mergeprocesses, List<ProductionProcesses> otherThproces);
+
+    List<ProductionProcesses> seriesLzBzMerge(List<ProductionProcesses> mergeprocesses, List<ProductionProcesses> otherSerProces);
+}

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

@@ -1064,9 +1064,9 @@ public class ApsServiceImpl implements ApsService {
             for (ProductionProcesses process : orderpss) {
                 if("成退".equals(process.getProcessType()) || "中退".equals(process.getProcessType()) || "小卷成退".equals(process.getProcessType())){
                     // 锁定的不参与合并
-                    if(process.getIfLock()){
+                    /*if(process.getIfLock()){
                         mergeprocesses.add(process);
-                    }else{
+                    }else{*/
                         String bsproid = process.getBsProcessesId().get(0);
                         List<ProductionProcesses> bsprocess = thproMap.get(bsproid);
                         if(bsprocess == null){
@@ -1074,7 +1074,7 @@ public class ApsServiceImpl implements ApsService {
                         }
                         bsprocess.add(process);
                         thproMap.put(bsproid,bsprocess);
-                    }
+//                    }
                 }else{
                     mergeprocesses.add(process);
 

+ 633 - 0
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/service/impl/DdApsServiceImpl.java

@@ -0,0 +1,633 @@
+package com.rongwei.rwapsserver.aps.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.rongwei.rwapsserver.aps.domain.Equipment;
+import com.rongwei.rwapsserver.aps.domain.ProductionProcesses;
+import com.rongwei.rwapsserver.aps.service.DdApsService;
+import org.springframework.stereotype.Service;
+
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class DdApsServiceImpl implements DdApsService {
+
+    /**
+     * 冷轧同一道工序分组提前合并
+     * @param mergeprocesses
+     * @param otherThproces
+     * @return
+     */
+    @Override
+    public List<ProductionProcesses> thOtherMerge(List<ProductionProcesses> mergeprocesses, List<ProductionProcesses> otherThproces){
+        List<ProductionProcesses> lzmergeprocesses = new ArrayList<>();
+        // 根据订单分组
+        Map<String, List<ProductionProcesses>> orderProcess = mergeprocesses.stream().collect(Collectors.groupingBy(ProductionProcesses::getOrderId));
+        orderProcess.forEach((k,processes)->{
+            // 退火工序过滤
+            List<ProductionProcesses> thpros = new ArrayList<>();
+            // 所有单卷作业集合
+            Map<String,ProductionProcesses> allProMap = new HashMap<>();
+            // 按作业分组
+            Map<String,List<ProductionProcesses>> bsProceses = new HashMap<>();
+            // 合并后的作业集合
+            List<ProductionProcesses> othermergeprocesses = new ArrayList<>();
+            // 未合并的作业集合
+            List<ProductionProcesses> notMergeProces = new ArrayList<>();
+            // 根节点集合
+            List<ProductionProcesses> rootProces = new ArrayList<>();
+            // 已分组合并作业
+            List<String> hasMerge = new ArrayList<>();
+            for (ProductionProcesses mergeprocess : processes) {
+                if(mergeprocess.getProcessType().equals("成退") || mergeprocess.getProcessType().equals("中退") || mergeprocess.getProcessType().equals("小卷成退")){
+                    thpros.add(mergeprocess);
+                    othermergeprocesses.add(mergeprocess);
+                }else{
+                    if(mergeprocess.getIfLock()){
+                        othermergeprocesses.add(mergeprocess);
+                    }
+                }
+
+                // 根据作业ID缓存数据
+                if(bsProceses.containsKey(mergeprocess.getUniqueBsProcessesId())){
+                    bsProceses.get(mergeprocess.getUniqueBsProcessesId()).add(mergeprocess);
+                }else{
+                    List<ProductionProcesses> bsProcese = new ArrayList<>();
+                    bsProcese.add(mergeprocess);
+                    bsProceses.put(mergeprocess.getUniqueBsProcessesId(),bsProcese);
+                }
+                // 根据作业明细ID缓存数据
+                allProMap.put(mergeprocess.getId(),mergeprocess);
+                // 根节点缓存
+                if(mergeprocess.getPreviousProcesses() == null || mergeprocess.getPreviousProcesses().size() == 0){
+                    rootProces.add(mergeprocess);
+                }
+            }
+            // 退火后道未锁定工序合并
+            if(thpros != null && thpros.size()>0){
+                for (ProductionProcesses thpro : thpros) {
+                    thNextHb(thpro,notMergeProces,othermergeprocesses,bsProceses,hasMerge,allProMap);
+                }
+            }
+            // 剩下的数据从根据节点开始如果上道工序有锁定的按照锁定合并、没有锁定的按照4卷合并
+            if(rootProces != null && rootProces.size()>0){
+                // 首先递归到存在未合并的作业
+                List<ProductionProcesses> notLockProces = new ArrayList<>();
+                hasNotLockHb(rootProces,notLockProces,bsProceses);
+                if(notLockProces != null && notLockProces.size()>0){
+                    // 作业合并
+                    notThHb(notLockProces,notMergeProces,othermergeprocesses,bsProceses,hasMerge,allProMap);
+                }
+            }
+
+            // 最终数据汇总
+            otherThproces.addAll(notMergeProces);
+            lzmergeprocesses.addAll(othermergeprocesses);
+        });
+        return lzmergeprocesses;
+    }
+
+    private void notThHb(List<ProductionProcesses> notLockProces,List<ProductionProcesses> notMergeProces,List<ProductionProcesses> mergeprocesses
+            ,Map<String,List<ProductionProcesses>> bsProceses,List<String> hasMerge,Map<String,ProductionProcesses> allProMap){
+        // 未锁定的作业
+        List<ProductionProcesses> notLocks = notLockProces.stream().filter(v -> !v.getIfLock()).collect(Collectors.toList());
+        // 锁定的作业
+        List<ProductionProcesses> locks = notLockProces.stream().filter(v -> v.getIfLock()).collect(Collectors.toList());
+        // 锁定的作业合并
+        if(locks != null && locks.size()>0){
+            Map<String, List<ProductionProcesses>> equass = locks.stream().collect(Collectors.groupingBy(ProductionProcesses::getEquipmentId));
+            equass.forEach((k,vps)->{
+                // 按照开始时间排序
+                Collections.sort(vps,Comparator.comparing(pro -> pro.getStartTime()));
+                List<List<ProductionProcesses>> lockgroups = new ArrayList<>();
+                for (ProductionProcesses lock : vps) {
+                    if(lockgroups.size() == 0){
+                        List<ProductionProcesses> pps = new ArrayList<>();
+                        pps.add(lock);
+                        lockgroups.add(pps);
+                    }else{
+                        // 前一道锁定工序和后一道锁定工序如果相隔时间小于11分钟则认为是可以合并的
+                        if(lockgroups.get(lockgroups.size()-1).get(lockgroups.get(lockgroups.size()-1).size()-1).getEndTime().plusMinutes(11).compareTo(lock.getStartTime())>0){
+                            lockgroups.get(lockgroups.size()-1).add(lock);
+                        }else{
+                            List<ProductionProcesses> pps = new ArrayList<>();
+                            pps.add(lock);
+                            lockgroups.add(pps);
+                        }
+                    }
+                }
+                for (List<ProductionProcesses> lockgroup : lockgroups) {
+                    lockNextHb(lockgroup,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+                }
+            });
+        }
+        // 未锁定的作业合并
+        if(notLocks != null && notLocks.size()>0 && !hasMerge.contains(notLocks.get(0).getId())){
+            if(notLocks.get(0).getRooprocess() != null && notLocks.get(0).getRooprocess().getStartTime() != null){
+                boolean ifnull = false;
+                for (ProductionProcesses notLock : notLocks) {
+                    if(notLock.getRooprocess() == null || notLock.getRooprocess().getStartTime() == null){
+                        ifnull = true;
+                    }
+                }
+                // 根据根节点开始时间排序
+                if(!ifnull){
+                    Collections.sort(notLocks,Comparator.comparing(pro -> pro.getRooprocess().getStartTime()));
+                }
+                if(notLocks.size()>0){
+                    // 根据承重计算最大几卷
+                    int a = 4;
+                    List<List<ProductionProcesses>> chunks = new ArrayList<>();
+                    int listSize = notLocks.size();
+                    for (int i = 0; i < listSize; i += a) {
+                        chunks.add(notLocks.subList(i, Math.min(i + a, listSize)));
+                    }
+                    // 合并作业
+                    for (List<ProductionProcesses> mergePres : chunks) {
+                        Map<String,ProductionProcesses> mergeProNexts = new HashMap<>();
+                        ProductionProcesses mergePro = mergePres.get(0);
+                        List<String> mergeProOrders = new ArrayList<>();
+                        mergeProOrders.add(mergePro.getId());
+                        mergePro.setMergeProOrders(mergeProOrders);
+                        for (int i = 0; i < mergePres.size(); i++) {
+                            if(i>0){
+                                // 设置待合并退火的主ID
+                                mergePres.get(i).setMergeThMainId(mergePres.get(0).getId());
+                                mergePro.getMergeProOrders().add(mergePres.get(i).getId());
+                                notMergeProces.add(mergePres.get(i));
+                                if(mergePres.get(i).getNextProcesses() != null && mergePres.get(i).getNextProcesses().size()>0){
+                                    for (ProductionProcesses nextProcess : mergePres.get(i).getNextProcesses()) {
+                                        mergeProNexts.put(nextProcess.getId(),nextProcess);
+                                    }
+                                }
+                                if(mergePro.getPreviousProcesses() != null && mergePro.getPreviousProcesses().size()>0){
+                                    // 合并作业的上一道工序
+                                    mergePro.getPreviousProcesses().addAll(mergePres.get(i).getPreviousProcesses());
+                                    mergePro.getPreviousProcessesIds().addAll(mergePres.get(i).getPreviousProcessesIds());
+                                    // 合并作业上一道工序的下一道工序设置为当前合并作业
+                                    for (ProductionProcesses previousProcess : mergePres.get(i).getPreviousProcesses()) {
+                                        previousProcess.getNextProcesses().clear();
+                                        previousProcess.getNextProcesses().add(mergePro);
+                                        previousProcess.getNextProcessesIds().clear();
+                                        previousProcess.getNextProcessesIds().add(mergePro.getId());
+                                    }
+                                }
+                            }
+                        }
+                        // 取第一个作业作为合并作业
+                        mergePro.setProduceTime(mergePro.getProduceTime()*mergePres.size());
+                        mergePro.setOpeProducePcNum(mergePres.size());
+                        // 合并作业的上一道工序
+                        if(mergeProNexts.size()>0){
+                            for (String proid:mergeProNexts.keySet()){
+                                if(!mergePro.getNextProcessesIds().contains(proid)){
+                                    ProductionProcesses propro = mergeProNexts.get(proid);
+                                    mergePro.getNextProcessesIds().add(proid);
+                                    mergePro.getNextProcesses().add(propro);
+                                }
+                            }
+                        }
+                        mergeprocesses.add(mergePro);
+
+                        // 记录已合并的作业
+                        if(!hasMerge.contains(mergePres.get(0).getId())){
+                            List<String> proids = mergePres.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                            hasMerge.addAll(proids);
+                        }
+                        // 递归按照退火合并
+                        nextLockHb(mergePro,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+                    }
+                }else{
+                    mergeprocesses.addAll(notLocks);
+                }
+            }
+        }
+    }
+
+    /**
+     * 锁定作业下道工序递归合并
+     * @param lockgroup
+     * @param notMergeProces
+     * @param mergeprocesses
+     * @param bsProceses
+     * @param hasMerge
+     * @param allProMap
+     */
+    private void lockNextHb(List<ProductionProcesses> lockgroup,List<ProductionProcesses> notMergeProces,List<ProductionProcesses> mergeprocesses
+            ,Map<String,List<ProductionProcesses>> bsProceses,List<String> hasMerge,Map<String,ProductionProcesses> allProMap){
+        if(!lockgroup.get(0).getIfLock() && !hasMerge.contains(lockgroup.get(0).getId())){
+            // 合并
+            List<ProductionProcesses> mergePres = new ArrayList<>();
+            mergePres.addAll(lockgroup);
+            // 按照铸轧时间排序
+            if(mergePres.get(0).getRooprocess() != null && mergePres.get(0).getRooprocess().getStartTime() != null){
+                Collections.sort(mergePres,Comparator.comparing(pro -> pro.getRooprocess().getStartTime()));
+            }
+            ProductionProcesses mergePro = mergePres.get(0);
+            Map<String,ProductionProcesses> mergeProNexts = new HashMap<>();
+            if(mergePres.size()>1){
+                List<String> mergeProOrders = new ArrayList<>();
+                mergeProOrders.add(mergePro.getId());
+                mergePro.setMergeProOrders(mergeProOrders);
+                for (int i = 0; i < mergePres.size(); i++) {
+                    if(i>0){
+                        // 设置待合并退火的主ID
+                        mergePres.get(i).setMergeThMainId(mergePres.get(0).getId());
+                        mergePro.getMergeProOrders().add(mergePres.get(i).getId());
+                        notMergeProces.add(mergePres.get(i));
+                        if(mergePres.get(i).getNextProcesses() != null && mergePres.get(i).getNextProcesses().size()>0){
+                            for (ProductionProcesses nextProcess : mergePres.get(i).getNextProcesses()) {
+                                mergeProNexts.put(nextProcess.getId(),nextProcess);
+                            }
+                        }
+                        if(mergePro.getPreviousProcesses() != null && mergePro.getPreviousProcesses().size()>0){
+                            // 合并作业的上一道工序
+                            mergePro.getPreviousProcesses().addAll(mergePres.get(i).getPreviousProcesses());
+                            mergePro.getPreviousProcessesIds().addAll(mergePres.get(i).getPreviousProcessesIds());
+                            // 合并作业上一道工序的下一道工序设置为当前合并作业
+                            for (ProductionProcesses previousProcess : mergePres.get(i).getPreviousProcesses()) {
+                                previousProcess.getNextProcesses().clear();
+                                previousProcess.getNextProcesses().add(mergePro);
+                                previousProcess.getNextProcessesIds().clear();
+                                previousProcess.getNextProcessesIds().add(mergePro.getId());
+                            }
+                        }
+                    }
+                }
+                // 取第一个作业作为合并作业
+                mergePro.setProduceTime(mergePro.getProduceTime()*mergePres.size());
+                mergePro.setOpeProducePcNum(mergePres.size());
+                // 合并作业的上一道工序
+                if(mergeProNexts.size()>0){
+                    for (String proid:mergeProNexts.keySet()){
+                        if(!mergePro.getNextProcessesIds().contains(proid)){
+                            ProductionProcesses propro = mergeProNexts.get(proid);
+                            mergePro.getNextProcessesIds().add(proid);
+                            mergePro.getNextProcesses().add(propro);
+                        }
+                    }
+                }
+                mergeprocesses.add(mergePro);
+            }else{
+                mergeprocesses.addAll(mergePres);
+            }
+            // 记录已合并的作业
+            if(!hasMerge.contains(mergePres.get(0).getId())){
+                List<String> proids = mergePres.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                hasMerge.addAll(proids);
+            }
+            // 递归按照退火合并
+            nextLockHb(mergePro,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+        }else{
+            List<ProductionProcesses> nexts = new ArrayList<>();
+            for (ProductionProcesses productionProcesses : lockgroup) {
+                if(productionProcesses.getNextProcesses() != null && productionProcesses.getNextProcesses().size()>0){
+                    nexts.addAll(productionProcesses.getNextProcesses());
+                }
+            }
+            if(nexts != null && nexts.size()>0){
+                lockNextHb(nexts,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+            }
+        }
+    }
+
+    /**
+     * 递归下一道工序合并
+     * @param thps
+     * @param notMergeProces
+     * @param mergeprocesses
+     * @param bsProceses
+     * @param hasMerge
+     * @param allProMap
+     */
+    private void nextLockHb(ProductionProcesses thps,List<ProductionProcesses> notMergeProces,List<ProductionProcesses> mergeprocesses
+            ,Map<String,List<ProductionProcesses>> bsProceses,List<String> hasMerge,Map<String,ProductionProcesses> allProMap){
+        List<ProductionProcesses> nextProcesses = thps.getNextProcesses();
+        if(nextProcesses != null && nextProcesses.size()>0){
+            List<ProductionProcesses> mergePres = new ArrayList<>();
+            mergePres.addAll(nextProcesses);
+            // 按照铸轧时间排序
+            if(mergePres.get(0).getRooprocess() != null && mergePres.get(0).getRooprocess().getStartTime() != null){
+                Collections.sort(mergePres,Comparator.comparing(pro -> pro.getRooprocess().getStartTime()));
+            }
+            if(!hasMerge.contains(mergePres.get(0).getId())){
+                ProductionProcesses mergePro = mergePres.get(0);
+                Map<String,ProductionProcesses> mergeProNexts = new HashMap<>();
+                if(mergePres.size()>1){
+                    List<String> mergeProOrders = new ArrayList<>();
+                    mergeProOrders.add(mergePro.getId());
+                    mergePro.setMergeProOrders(mergeProOrders);
+                    for (int i = 0; i < mergePres.size(); i++) {
+                        if(i>0){
+                            // 设置待合并退火的主ID
+                            mergePres.get(i).setMergeThMainId(mergePres.get(0).getId());
+                            mergePro.getMergeProOrders().add(mergePres.get(i).getId());
+                            notMergeProces.add(mergePres.get(i));
+                            if(mergePres.get(i).getNextProcesses() != null && mergePres.get(i).getNextProcesses().size()>0){
+                                for (ProductionProcesses nextProcess : mergePres.get(i).getNextProcesses()) {
+                                    mergeProNexts.put(nextProcess.getId(),nextProcess);
+                                }
+                            }
+                        }
+                    }
+                    // 取第一个作业作为合并作业
+                    mergePro.setProduceTime(mergePro.getProduceTime()*mergePres.size());
+                    mergePro.setOpeProducePcNum(mergePres.size());
+                    List<String> nextids = new ArrayList<>();
+                    List<String> preids = new ArrayList<>();
+                    List<ProductionProcesses> nextpss = new ArrayList<>();
+                    List<ProductionProcesses> prepss = new ArrayList<>();
+                    nextpss.add(thps);
+                    nextids.add(thps.getId());
+                    mergePro.setPreviousProcesses(nextpss);
+                    mergePro.setPreviousProcessesIds(nextids);
+                    preids.add(mergePro.getId());
+                    prepss.add(mergePro);
+                    thps.setNextProcessesIds(preids);
+                    thps.setNextProcesses(prepss);
+                    // 合并作业的上一道工序
+                    if(mergeProNexts.size()>0){
+                        for (String proid:mergeProNexts.keySet()){
+                            if(!mergePro.getNextProcessesIds().contains(proid)){
+                                ProductionProcesses propro = mergeProNexts.get(proid);
+                                mergePro.getNextProcessesIds().add(proid);
+                                mergePro.getNextProcesses().add(propro);
+                            }
+                        }
+                    }
+
+                    mergeprocesses.add(mergePro);
+                }else{
+                    mergeprocesses.addAll(mergePres);
+                }
+                // 记录已合并的作业
+                if(!hasMerge.contains(mergePres.get(0).getId())){
+                    List<String> proids = mergePres.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                    hasMerge.addAll(proids);
+                }
+                // 递归下一道工序合并
+                nextLockHb(mergePro,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+            }
+        }
+    }
+
+    /**
+     * 首先递归到存在未合并的作业
+     * @param rootProces
+     * @param notLockProces
+     * @param bsProceses
+     */
+    private void hasNotLockHb(List<ProductionProcesses> rootProces,List<ProductionProcesses> notLockProces,Map<String,List<ProductionProcesses>> bsProceses){
+        // 未锁定的作业
+        List<ProductionProcesses> notLocks = rootProces.stream().filter(v -> !v.getIfLock()).collect(Collectors.toList());
+        // 存在未锁定的作业时从这道工序开始合并下道工序
+        if(notLocks.size()>0){
+            notLockProces.addAll(bsProceses.get(notLocks.get(0).getUniqueBsProcessesId()));
+        }else{
+            List<ProductionProcesses> nextProces = new ArrayList<>();
+            for (ProductionProcesses rootProce : rootProces) {
+                if(rootProce.getNextProcesses() != null && rootProce.getNextProcesses().size()>0){
+                    nextProces.addAll(rootProce.getNextProcesses());
+                }
+            }
+            if(nextProces != null && nextProces.size()>0){
+                hasNotLockHb(nextProces,notLockProces,bsProceses);
+            }
+        }
+    }
+
+    /**
+     * 退火后道工序合并处理
+     * @param prePro
+     */
+    private void thNextHb(ProductionProcesses prePro,List<ProductionProcesses> notMergeProces,List<ProductionProcesses> mergeprocesses
+            ,Map<String,List<ProductionProcesses>> bsProceses,List<String> hasMerge,Map<String,ProductionProcesses> allProMap){
+        List<ProductionProcesses> nextProcesses = prePro.getNextProcesses();
+        if(nextProcesses != null && nextProcesses.size()>0){
+            // 没有锁定的就需要合并
+            if(!nextProcesses.get(0).getIfLock()){
+                List<ProductionProcesses> mergePres = new ArrayList<>();
+                mergePres.addAll(nextProcesses);
+                // 按照铸轧时间排序
+                if(mergePres.get(0).getRooprocess() != null && mergePres.get(0).getRooprocess().getStartTime() != null){
+                    Collections.sort(mergePres,Comparator.comparing(pro -> pro.getRooprocess().getStartTime()));
+                }
+                ProductionProcesses mergePro = mergePres.get(0);
+                Map<String,ProductionProcesses> mergeProNexts = new HashMap<>();
+                if(mergePres.size()>1){
+                    List<String> mergeProOrders = new ArrayList<>();
+                    mergeProOrders.add(mergePro.getId());
+                    mergePro.setMergeProOrders(mergeProOrders);
+                    for (int i = 0; i < mergePres.size(); i++) {
+                        if(i>0){
+                            // 设置待合并退火的主ID
+                            mergePres.get(i).setMergeThMainId(mergePres.get(0).getId());
+                            mergePro.getMergeProOrders().add(mergePres.get(i).getId());
+                            notMergeProces.add(mergePres.get(i));
+                            if(mergePres.get(i).getNextProcesses() != null && mergePres.get(i).getNextProcesses().size()>0){
+                                for (ProductionProcesses nextProcess : mergePres.get(i).getNextProcesses()) {
+                                    mergeProNexts.put(nextProcess.getId(),nextProcess);
+                                }
+                            }
+                        }
+                    }
+                    // 取第一个作业作为合并作业
+                    mergePro.setProduceTime(mergePro.getProduceTime()*mergePres.size());
+                    mergePro.setOpeProducePcNum(mergePres.size());
+                    List<String> nextids = new ArrayList<>();
+                    List<String> preids = new ArrayList<>();
+                    List<ProductionProcesses> nextpss = new ArrayList<>();
+                    List<ProductionProcesses> prepss = new ArrayList<>();
+                    nextpss.add(prePro);
+                    nextids.add(prePro.getId());
+                    mergePro.setPreviousProcesses(nextpss);
+                    mergePro.setPreviousProcessesIds(nextids);
+                    preids.add(mergePro.getId());
+                    prepss.add(mergePro);
+                    prePro.setNextProcessesIds(preids);
+                    prePro.setNextProcesses(prepss);
+                    // 合并作业的上一道工序
+                    if(mergeProNexts.size()>0){
+                        for (String proid:mergeProNexts.keySet()){
+                            if(!mergePro.getNextProcessesIds().contains(proid)){
+                                ProductionProcesses propro = mergeProNexts.get(proid);
+                                mergePro.getNextProcessesIds().add(proid);
+                                mergePro.getNextProcesses().add(propro);
+                            }
+                        }
+                    }
+
+                    mergeprocesses.add(mergePro);
+                }else{
+                    mergeprocesses.addAll(mergePres);
+                }
+                // 记录已合并的作业
+                if(!hasMerge.contains(mergePres.get(0).getId())){
+                    List<String> proids = mergePres.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                    hasMerge.addAll(proids);
+                }
+                // 递归按照退火合并
+                thNextHb(mergePro,notMergeProces,mergeprocesses,bsProceses,hasMerge,allProMap);
+            }
+        }
+    }
+
+    /**
+     * 连续冷轧箔轧作业合并
+     * @param mergeprocesses
+     * @param otherSerProces
+     */
+    @Override
+    public List<ProductionProcesses> seriesLzBzMerge(List<ProductionProcesses> mergeprocesses,List<ProductionProcesses> otherSerProces){
+        List<ProductionProcesses> retPros = new ArrayList<>();
+        if(mergeprocesses != null && mergeprocesses.size()>0){
+            // 获取所有根节点
+            List<ProductionProcesses> rootPros = new ArrayList<>();
+            for (ProductionProcesses mergeprocess : mergeprocesses) {
+                if(mergeprocess.getPreviousProcesses() == null || mergeprocess.getPreviousProcesses().size() == 0){
+                    rootPros.add(mergeprocess);
+                }
+            }
+            // 被合并的作业
+            List<ProductionProcesses> lzbzMergeOthers = new ArrayList<>();
+            // 根据根节点逐级查询是否可合并的作业
+            if(rootPros != null && rootPros.size()>0){
+                Map<String,List<ProductionProcesses>> lzbzMerges = new HashMap<>();
+                // 已合并处理过作业ID
+                List<String> hasMid = new ArrayList<>();
+                for (ProductionProcesses rootPro : rootPros) {
+                    getNotLockLzBzSeries(rootPro,lzbzMerges,hasMid);
+                }
+                if(lzbzMerges != null && lzbzMerges.size()>0){
+                    for (String k:lzbzMerges.keySet()){
+                        List<ProductionProcesses> serPros = lzbzMerges.get(k);
+                        // 连续冷轧或箔轧超过1个,则合并
+                        if(serPros != null && serPros.size()>1){
+                            ProductionProcesses fMergePro = serPros.get(0);
+                            if(fMergePro.getMergeProOrders() == null){
+                                fMergePro.setMergeProOrders(new ArrayList<>());
+                                fMergePro.getMergeProOrders().add(fMergePro.getId());
+                            }
+                            // 按顺序依次合并
+                            for (int i = 0; i < serPros.size(); i++) {
+                                if(i>0){
+                                    serPros.get(i).setMergeThMainId(fMergePro.getId());
+                                    if(serPros.get(i).getMergeProOrders() == null){
+                                        fMergePro.getMergeProOrders().add(serPros.get(i).getId());
+                                    }else{
+                                        fMergePro.getMergeProOrders().addAll(serPros.get(i).getMergeProOrders());
+                                    }
+                                    fMergePro.setProduceTime(fMergePro.getProduceTime()+serPros.get(i).getProduceTime());
+                                    // 连续生产合并作业设置下道工序,以及合并后下道作业的上道工序
+                                    if(i == serPros.size()-1){
+                                        fMergePro.setNextProcesses(serPros.get(i).getNextProcesses());
+                                        fMergePro.setNextProcessesIds(serPros.get(i).getNextProcessesIds());
+                                        if(fMergePro.getNextProcesses() != null && fMergePro.getNextProcesses().size()>0){
+                                            for (ProductionProcesses nextProcess : fMergePro.getNextProcesses()) {
+                                                List<ProductionProcesses> pres = new ArrayList<>();
+                                                List<String> preids = new ArrayList<>();
+                                                pres.add(fMergePro);
+                                                preids.add(fMergePro.getId());
+                                                nextProcess.setPreviousProcesses(pres);
+                                                nextProcess.setPreviousProcessesIds(preids);
+                                            }
+                                        }
+                                    }
+                                    lzbzMergeOthers.add(serPros.get(i));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            // 除去被合并的作业
+            if(lzbzMergeOthers != null && lzbzMergeOthers.size()>0){
+                List<String> lzbzMergeOtherIds = lzbzMergeOthers.stream().map(ProductionProcesses::getId).collect(Collectors.toList());
+                for (ProductionProcesses mergeprocess : mergeprocesses) {
+                    if(!lzbzMergeOtherIds.contains(mergeprocess.getId())){
+                        retPros.add(mergeprocess);
+                    }
+                }
+            }else{
+                retPros.addAll(mergeprocesses);
+            }
+        }
+        return retPros;
+    }
+
+    private void getNotLockLzBzSeries(ProductionProcesses rootPro,Map<String,List<ProductionProcesses>> lzbzMerges,List<String> hasMid){
+        if(rootPro.getIfLock()){
+            if(rootPro.getNextProcesses() != null && rootPro.getNextProcesses().size()>0){
+                for (ProductionProcesses nextProcess : rootPro.getNextProcesses()) {
+                    getNotLockLzBzSeries(nextProcess,lzbzMerges,hasMid);
+                }
+            }
+        }else{
+            getLzBzSeries(rootPro,lzbzMerges,null,null,null,hasMid);
+        }
+    }
+
+    private void getLzBzSeries(ProductionProcesses rootPro,Map<String,List<ProductionProcesses>> lzbzMerges
+            ,String seriesKey,String protype,List<String> commonEqus,List<String> hasMid){
+        if(!hasMid.contains(rootPro.getId())){
+            hasMid.add(rootPro.getId());
+            List<ProductionProcesses> nextProcesses = rootPro.getNextProcesses();
+            // 冷轧或箔轧前后辊不一样不能合并
+            boolean issameg = true;
+            if(nextProcesses != null && nextProcesses.size()>0){
+                if(rootPro.getProZg() != null && nextProcesses.get(0).getProZg() != null){
+                    if(rootPro.getProZg().equals(nextProcesses.get(0).getProZg())){
+                        issameg = false;
+                    }
+                }
+            }
+            if("否".equals(rootPro.getIssubsection()) && ("冷轧".equals(rootPro.getProcessType()) || "箔轧".equals(rootPro.getProcessType()))
+                    && !rootPro.getIfLock() && issameg){
+                // 是否连续冷轧、箔轧
+                boolean hasSeries = false;
+                if(StrUtil.isNotBlank(seriesKey) && StrUtil.isNotBlank(protype) && protype.equals(rootPro.getProcessType())
+                        && (rootPro.getMinWaitTime() == null || rootPro.getMinWaitTime()<=0)){
+                    if(commonEqus != null && commonEqus.size()>0){
+                        List<String> commonEqusNext = new ArrayList<>();
+                        for (String optionalEquipment : rootPro.getOptionalEquipments()) {
+                            if(commonEqus.contains(optionalEquipment)){
+                                commonEqusNext.add(optionalEquipment);
+                            }
+                        }
+                        if(commonEqusNext != null && commonEqusNext.size()>0){
+                            hasSeries = true;
+                            lzbzMerges.get(seriesKey).add(rootPro);
+                            commonEqus = commonEqusNext;
+                        }
+                    }
+                }
+                if(nextProcesses != null && nextProcesses.size()>0){
+                    // 不能和上一道工序连续,则作为第一道连续工序
+                    if(!hasSeries){
+                        List<ProductionProcesses> serPros = new ArrayList<>();
+                        serPros.add(rootPro);
+                        lzbzMerges.put(rootPro.getId(),serPros);
+                        // 上下道工序共用的可选设备
+                        commonEqus = new ArrayList<>();
+                        commonEqus.addAll(rootPro.getOptionalEquipments());
+                    }
+                    for (ProductionProcesses nextProcess : nextProcesses) {
+                        if(hasSeries){
+                            getLzBzSeries(nextProcess,lzbzMerges,seriesKey,rootPro.getProcessType(),commonEqus,hasMid);
+                        }else{
+                            getLzBzSeries(nextProcess,lzbzMerges,rootPro.getId(),rootPro.getProcessType(),commonEqus,hasMid);
+                        }
+                    }
+                }
+            }else{
+                if(nextProcesses != null && nextProcesses.size()>0){
+                    for (ProductionProcesses nextProcess : nextProcesses) {
+                        getLzBzSeries(nextProcess,lzbzMerges,null,null,null,hasMid);
+                    }
+                }
+            }
+        }
+    }
+
+}

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

@@ -6,6 +6,7 @@ import cn.hutool.json.JSONUtil;
 import com.rongwei.rwapsserver.aps.domain.*;
 import com.rongwei.rwapsserver.aps.score.ApsConstraintProvider;
 import com.rongwei.rwapsserver.aps.service.ApsService;
+import com.rongwei.rwapsserver.aps.service.DdApsService;
 import com.rongwei.rwapsserver.aps.service.ProductionScheduleService;
 import com.rongwei.rwapsserver.aps.util.ApsConstants;
 import com.rongwei.rwapsserver.aps.util.ApsException;
@@ -39,6 +40,8 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
 
     @Autowired
     private ApsService apsService;
+    @Autowired
+    private DdApsService ddsService;
 
     /**
      * APS生产计划排程
@@ -47,8 +50,9 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
      */
     @Override
     public ProductionScheduleRetVo productionSchedule(ProductionScheduleVo productionScheduleVo) throws Exception{
-        /*List<ProductionProcesses> collect = productionScheduleVo.getProcesses().stream().filter(v -> "567919265a804029bd32bcb4e2f2c19e".equals(v.getProduceOrder().get(0).getId())).collect(Collectors.toList());
-        productionScheduleVo.setProcesses(collect);*/
+        List<ProductionProcesses> collect = productionScheduleVo.getProcesses().stream().filter(v -> !"73319cb938da46feb9989e1ff29766c1".equals(v.getProduceOrder().get(0).getId())).collect(Collectors.toList());
+        productionScheduleVo.setProcesses(collect);
+
         log.info("*************** 排程开始:"+productionScheduleVo.getProductionScheduleId()+" *******************");
         if(productionScheduleVo.getScheduleType().getScheduleType() == null){
             productionScheduleVo.getScheduleType().setScheduleType("default");
@@ -127,11 +131,22 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         // 退火合并
         List<ProductionProcesses> thList = apsService.thProcessMerge(productionScheduleVo,apsSolution,otherThproces);
         apsSolution.setProcessesList(thList);
-        List<ProductionProcesses> processesList = apsService.thOtherMerge(thList, otherNotThproces);
+
+        List<ProductionProcesses> processesList = null;
+        if("dd".equals(productionScheduleVo.getScheduleType().getScheduleType())){
+            processesList = ddsService.thOtherMerge(thList, otherNotThproces);
+        }else{
+            processesList = apsService.thOtherMerge(thList, otherNotThproces);
+        }
         apsSolution.setProcessesList(processesList);
 
         List<ProductionProcesses> otherSerProces = new ArrayList<>();
-        List<ProductionProcesses> otherSerProcesMerges = apsService.seriesLzBzMerge(processesList, otherSerProces);
+        List<ProductionProcesses> otherSerProcesMerges = null;
+        if("dd".equals(productionScheduleVo.getScheduleType().getScheduleType())){
+            otherSerProcesMerges = ddsService.seriesLzBzMerge(processesList, otherSerProces);
+        }else{
+            otherSerProcesMerges = apsService.seriesLzBzMerge(processesList, otherSerProces);
+        }
         apsSolution.setProcessesList(otherSerProcesMerges);
         // 排程作业排序
         sortProcess(apsSolution.getProcessesList(),1);
@@ -859,6 +874,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 pper.setProducttype(productionProcesses.getProducttype());
                 pper.setOnceprocessmin(productionProcesses.getProduceTime());
                 pper.setPcNum(productionProcesses.getOpeProducePcNum());
+                pper.setZjgid(productionProcesses.getProZg());
                 pper.setOccupyType("process");
                 equipmentRunTimes.add(pper);
 

+ 15 - 1
rw-aps-server/src/test/java/com/rongwei/rwapsserver/RwApsServerApplicationTests.java

@@ -5,6 +5,8 @@ import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.rongwei.rwapsserver.aps.domain.ApsOverallConfig;
 import com.rongwei.rwapsserver.aps.domain.ApsSolution;
@@ -45,7 +47,19 @@ class RwApsServerApplicationTests {
 
 //        test1(3);
 
-        test2();
+//        test2();
+        String bodyStr = "{" +
+                "    \"model\": \"deepseek-r1:8b\"," +
+                "    \"messages\": [{" +
+                "        \"role\": \"user\"," +
+                "        \"content\": \"北京市的面积是多少?\"}]," +
+                "    \"stream\": false" +
+                "}";
+        String postret = HttpUtil.post("http://127.0.0.1:11434/api/chat", bodyStr);
+        if(postret != null){
+            JSONObject jsonObject = JSONUtil.parseObj(postret);
+            System.out.println(postret);
+        }
     }
 
     private void test1(Integer inta){