Jelajahi Sumber

均衡排产优化

fangpy 1 tahun lalu
induk
melakukan
abb1ef7b58

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

@@ -1,5 +1,6 @@
 package com.rongwei.rwapsserver.aps;
 
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.json.JSONUtil;
 import com.rongwei.rwapsserver.aps.domain.*;
@@ -82,13 +83,31 @@ public class ApsBalancingApplication {
         System.out.println(allRunTimes);*/
 //        System.out.println(1280/100);
 
-        ProductionProcesses a = new ProductionProcesses();
+        /*ProductionProcesses a = new ProductionProcesses();
         a.setProduceTime(20);
         a.setStartTime(LocalDateTime.now());
         LocalDateTime endTime = a.getStartTime();
         System.out.println(a.getStartTime());
         endTime = endTime.plusMinutes(10);
-        System.out.println(a.getStartTime());
+        System.out.println(a.getStartTime());*/
+
+        /*Date deliverydate = DateUtil.parseDateTime("2024-06-24 08:00:00");
+        Integer deliverytime = 33;
+        DateTime dateTime = DateUtil.offsetHour(deliverydate, -deliverytime);
+        System.out.println(dateTime);*/
+
+        Map<String,List<Integer>> equipmentPlanActualTime = new HashMap<>();
+        List<Integer> planActualTimeList = new ArrayList<>();
+        planActualTimeList.add(1);planActualTimeList.add(2);
+        equipmentPlanActualTime.put("a",planActualTimeList);
+        System.out.println(equipmentPlanActualTime);
+
+        List<Integer> planActualTimeList1 = equipmentPlanActualTime.get("a");
+        System.out.println(planActualTimeList1);
+        planActualTimeList1.set(0,2);
+        System.out.println(planActualTimeList1);
+
+        System.out.println(equipmentPlanActualTime);
     }
 
     public static void testAps(){

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

@@ -39,6 +39,11 @@ public class ProductionProcesses extends Step{
         this.produceTime = produceTime;
     }
 
+    /**
+     * 任务类型,默认:processes
+     */
+    private String taskType;
+
     /**
      * 业务表订单工序ID
      */
@@ -629,6 +634,14 @@ public class ProductionProcesses extends Step{
         this.cutfinishmin = cutfinishmin;
     }
 
+    public String getTaskType() {
+        return taskType;
+    }
+
+    public void setTaskType(String taskType) {
+        this.taskType = taskType;
+    }
+
     public String getSeriSort(){
         String sortStr = this.getId();
         if(this.getStartTime() != null){

+ 84 - 9
rw-aps-server/src/main/java/com/rongwei/rwapsserver/aps/score/ApsConstraintProvider.java

@@ -1,5 +1,7 @@
 package com.rongwei.rwapsserver.aps.score;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.StrUtil;
 import com.rongwei.rwapsserver.aps.domain.Equipment;
@@ -718,14 +720,25 @@ public class ApsConstraintProvider implements ConstraintProvider {
                             productionProcesses.getEndTime().atZone(zoneId).toInstant().toEpochMilli()>deliveryMinDate.getTime();
                     return bol;
                 })
-                .penalize(HardSoftScore.ONE_SOFT,
-                        (productionProcesses) ->
-                                100
-//                                ((int)(DateUtil.between(deliveryMinDate, Date.from(productionProcesses.getEndTime().atZone(zoneId).toInstant()), DateUnit.MINUTE)+1)*10)
-                )
+                .penalize(HardSoftScore.ONE_SOFT,(productionProcesses) ->{
+                    Date deliveryMinDate = null;
+                    for (ProduceOrder produceOrder : productionProcesses.getProduceOrder()) {
+                        if(deliveryMinDate == null){
+                            deliveryMinDate = produceOrder.getDeliveryDate();
+                        }else{
+                            if(deliveryMinDate.compareTo(produceOrder.getDeliveryDate())>0){
+                                deliveryMinDate = produceOrder.getDeliveryDate();
+                            }
+                        }
+                    }
+                    int i = (int) (DateUtil.between(deliveryMinDate, Date.from(productionProcesses.getEndTime().atZone(zoneId).toInstant()), DateUnit.MINUTE) + 1) * 10;
+                    return i;
+                })
                 .asConstraint("deliveryDate");
     }
 
+
+
     /**
      * 均衡排产的软约束,任务尽量分配到不同设备上
      * @param constraintFactory
@@ -736,13 +749,75 @@ public class ApsConstraintProvider implements ConstraintProvider {
                 .filter((tc) -> {
                     return true;
                 })
-                .groupBy(ProductionProcesses::getEquipmentId,count())
-                .filter((productionProcesses, num) -> num > 1)
-                .penalize(HardSoftScore.ONE_SOFT,
-                        (productionProcesses, num) -> 1)
+                .groupBy(ProductionProcesses::getTaskType,ConstraintCollectors.toList())
+                .filter((taskType, processess) ->{
+                    boolean isbalance = false;
+                    Integer balanceNum = balanceCount(processess);
+                    if(balanceNum>0){
+                        isbalance = true;
+                    }
+                    return isbalance;
+                })
+                .penalize(HardSoftScore.ONE_SOFT,(taskType, processess) -> {
+                    Integer balanceNum = balanceCount(processess);
+                    return balanceNum;
+                })
                 .asConstraint("balancedEqUse");
     }
 
+    /**
+     * 均衡排产分数计算
+     * @param processess
+     * @return
+     */
+    private Integer balanceCount(List<ProductionProcesses> processess){
+        Integer balanceNum = 0;
+        if(processess != null && processess.size()>0){
+            /**
+             * 缓存所有设备计划均衡排产时间和实际排产时间
+             * map的value是List<Integer>类型长度为2,第一个为计划均衡排产时间,第二个为实际排产时间
+             */
+            Map<String,List<Integer>> equipmentPlanActualTime = new HashMap<>();
+            for (ProductionProcesses productionProcesses : processess) {
+                if(productionProcesses.getEquipmentId() == null){
+                    continue;
+                }
+                // 排产作业的加工时间除以可选设备个数即为均衡排产时间
+                int balanceTime = (productionProcesses.getProduceTime() / productionProcesses.getOptionalEquipments().size())+1;
+                for (String optionalEquipment : productionProcesses.getOptionalEquipments()) {
+                    // 缓存里有当前设备时,累计计划和实际时间
+                    if(equipmentPlanActualTime.containsKey(optionalEquipment)){
+                        List<Integer> planActualTimeList = equipmentPlanActualTime.get(optionalEquipment);
+                        Integer planTime = planActualTimeList.get(0)+balanceTime;
+                        Integer actualTime = planActualTimeList.get(1);
+                        if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
+                            actualTime = actualTime + productionProcesses.getProduceTime();
+                        }
+                        planActualTimeList.set(0,planTime);
+                        planActualTimeList.set(1,actualTime);
+                    }
+                    // 缓存里没有当前设备时初始化并赋值
+                    else{
+                        List<Integer> planActualTimeList = new ArrayList<>();
+                        planActualTimeList.add(balanceTime);
+                        if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
+                            planActualTimeList.add(productionProcesses.getProduceTime());
+                        }else {
+                            planActualTimeList.add(0);
+                        }
+                        equipmentPlanActualTime.put(optionalEquipment,planActualTimeList);
+                    }
+                }
+            }
+            // 计算所有设备的计划时间和实际时间之差的绝对值之和
+            for(String eqid : equipmentPlanActualTime.keySet()){
+                List<Integer> integers = equipmentPlanActualTime.get(eqid);
+                balanceNum = balanceNum + (Math.abs(integers.get(1)-integers.get(0)));
+            }
+        }
+        return balanceNum;
+    }
+
     /**
      * 合并生产工序,订单合并、尽量保证单次生产设备最大量
      * @param constraintFactory

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

@@ -193,6 +193,9 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
         for (ProductionProcesses process : productionScheduleVo.getProcesses()) {
             // 全局配置设置
             process.setApsOverallConfig(apsOverallConfig);
+            if(StrUtil.isBlank(process.getTaskType())){
+                process.setTaskType("processes");
+            }
             // 前道工序
             if(process.getPreviousProcessesIds() != null && process.getPreviousProcessesIds().size()>0){
                 List<ProductionProcesses> pres = new ArrayList<>();
@@ -254,6 +257,11 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
             if(process.getCutfinishmin() == null){
                 process.setCutfinishmin(0);
             }
+            // 锁定工序处理
+            if(process.getIfLock()){
+                // 锁定工序的设备即可选设备
+                process.setEquipment(process.getOptionalProviderEquipments().get(0));
+            }
         }
         // 设备列表初始化
         unsolvedCloudBalance.setEquipmentList(productionScheduleVo.getEquipmentList());
@@ -281,6 +289,7 @@ public class ProductionScheduleServiceImpl implements ProductionScheduleService
                 roots.add(productionProcesses);
             }
         }
+        Collections.sort(roots, Comparator.comparing(pro -> pro.getProduceOrder().get(0).getDeliveryDate()));
         // 订单作业列表
         Map<String,List<ProductionProcesses>> orderMap = new HashMap<>();
         for (ProductionProcesses root : roots) {