From 5099dfcf8e015c35a2f81986101e08e93a7d7944 Mon Sep 17 00:00:00 2001
From: L <L@123>
Date: 星期一, 13 十月 2025 17:09:01 +0800
Subject: [PATCH] *

---
 src/main/java/com/zy/asrs/utils/GroupedLockerOptimizerUtils.java |   84 ++++----
 src/main/java/com/zy/asrs/utils/param/ItemUtilParam.java         |   25 ++
 src/main/java/com/zy/asrs/task/OrderToSortLineScheduler.java     |   10 
 src/main/java/com/zy/asrs/utils/OptimizedLockerPackingUtils.java |  442 ++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/com/zy/asrs/utils/ToSortLineUtils.java             |   30 ++
 5 files changed, 543 insertions(+), 48 deletions(-)

diff --git a/src/main/java/com/zy/asrs/task/OrderToSortLineScheduler.java b/src/main/java/com/zy/asrs/task/OrderToSortLineScheduler.java
index 092ced5..c01130e 100644
--- a/src/main/java/com/zy/asrs/task/OrderToSortLineScheduler.java
+++ b/src/main/java/com/zy/asrs/task/OrderToSortLineScheduler.java
@@ -13,6 +13,7 @@
 import com.zy.asrs.task.core.ReturnT;
 import com.zy.asrs.task.handler.OrderToLineHandler;
 import com.zy.asrs.utils.GroupedLockerOptimizerUtils;
+import com.zy.asrs.utils.OptimizedLockerPackingUtils;
 import com.zy.asrs.utils.ToSortLineUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -50,7 +51,8 @@
         for (String orderNo : orderNos) {
             try{
                 List<OrderDetl> orderDetls = orderDetlService.selectByOrderNo(orderNo);
-                List<GroupedLockerOptimizerUtils.Item> items = new ArrayList<>();
+//                List<GroupedLockerOptimizerUtils.Item> items = new ArrayList<>();
+                List<OptimizedLockerPackingUtils.Item> items = new ArrayList<>();
                 for (OrderDetl orderDetl:orderDetls){
                     Integer number =  basArmRulesService.getNumber(orderDetl.getWeight(),orderDetl.getVolume(),orderDetl.getManLength(),orderDetl.getWidth(),orderDetl.getHeight());
                     if (number == null) {
@@ -67,13 +69,15 @@
                     String name = ToSortLineUtils.MergerParameter(orderDetl.getMatnr(),orderDetl.getStandby1(),orderDetl.getStandby2());
                     int maxCapacity = number;
                     int stock = orderDetl.getAnfme().intValue();
-                    items.add(new GroupedLockerOptimizerUtils.Item(name, maxCapacity, stock));
+//                    items.add(new GroupedLockerOptimizerUtils.Item(name, maxCapacity, stock));
+                    items.add(new OptimizedLockerPackingUtils.Item(name, maxCapacity, stock));
                 }
 
                 OrderToLine orderToLine = new OrderToLine();
                 orderToLine.setOrderNo(orderNo);  //鍗曟嵁缂栧彿
                 orderToLine.setCreateTime(System.currentTimeMillis());  //鍒涘缓鏃堕棿
-                OrderToLine orderToLineR = ToSortLineUtils.GetOrderToLine(items, orderToLine);
+//                OrderToLine orderToLineR = ToSortLineUtils.GetOrderToLineGro(items, orderToLine);
+                OrderToLine orderToLineR = ToSortLineUtils.GetOrderToLineOpt(items, orderToLine);
 
                 try{
                     ReturnT<String> returnT = orderToLineHandler.start(orderToLineR);
diff --git a/src/main/java/com/zy/asrs/utils/GroupedLockerOptimizerUtils.java b/src/main/java/com/zy/asrs/utils/GroupedLockerOptimizerUtils.java
index 0512ba1..e09d705 100644
--- a/src/main/java/com/zy/asrs/utils/GroupedLockerOptimizerUtils.java
+++ b/src/main/java/com/zy/asrs/utils/GroupedLockerOptimizerUtils.java
@@ -28,6 +28,7 @@
     static class Locker {
         int id;
         double remainingSpace;
+        long bindingTags;
         Map<String, Integer> contents;
         Set<String> itemTypes; // 褰撳墠鍌ㄧ墿鏌滀腑鐨勭墿鍝佺绫�
 
@@ -36,6 +37,7 @@
             this.remainingSpace = 1.0;
             this.contents = new HashMap<>();
             this.itemTypes = new HashSet<>();
+            this.bindingTags = System.currentTimeMillis();
         }
 
         public boolean canAdd(Item item, int quantity) {
@@ -122,60 +124,60 @@
         }
     }
 
-//    public static void main(String[] args) {
-//        Scanner scanner = new Scanner(System.in);
-//
-//        System.out.println("璇疯緭鍏ョ墿鍝佺绫绘暟閲�:");
-//        int itemTypes = scanner.nextInt();
-//        scanner.nextLine();
-//
-//        List<Item> items = new ArrayList<>();
-//
-//        for (int i = 0; i < itemTypes; i++) {
-//            System.out.println("\n璇疯緭鍏ョ" + (i + 1) + "绉嶇墿鍝佺殑淇℃伅:");
-//            System.out.print("鐗╁搧鍚嶇О: ");
-//            String name = scanner.nextLine();
-//
-//            System.out.print("鍗曠瀛樻斁鏈�澶ф暟閲�: ");
-//            int maxCapacity = scanner.nextInt();
-//
-//            System.out.print("搴撳瓨鏁伴噺: ");
-//            int stock = scanner.nextInt();
-//            scanner.nextLine();
-//
-//            items.add(new Item(name, maxCapacity, stock));
-//        }
-//
-//        // 浣跨敤鍒嗙粍浼樺厛绠楁硶
-//        PackingSolution solution = packItemsWithGrouping(items);
-//
-//        System.out.println("\n" + solution);
-//
-//        scanner.close();
-//    }
     public static void main(String[] args) {
-        int itemTypes = 5;
+        Scanner scanner = new Scanner(System.in);
+
+        System.out.println("璇疯緭鍏ョ墿鍝佺绫绘暟閲�:");
+        int itemTypes = scanner.nextInt();
+        scanner.nextLine();
 
         List<Item> items = new ArrayList<>();
 
         for (int i = 0; i < itemTypes; i++) {
-            String name = i+"a";
-            int maxCapacity = i*10;
-            int stock = i*11;
+            System.out.println("\n璇疯緭鍏ョ" + (i + 1) + "绉嶇墿鍝佺殑淇℃伅:");
+            System.out.print("鐗╁搧鍚嶇О: ");
+            String name = scanner.nextLine();
+
+            System.out.print("鍗曠瀛樻斁鏈�澶ф暟閲�: ");
+            int maxCapacity = scanner.nextInt();
+
+            System.out.print("搴撳瓨鏁伴噺: ");
+            int stock = scanner.nextInt();
+            scanner.nextLine();
+
             items.add(new Item(name, maxCapacity, stock));
         }
 
         // 浣跨敤鍒嗙粍浼樺厛绠楁硶
         PackingSolution solution = packItemsWithGrouping(items);
-        for (Locker locker:solution.lockers) {
-            for (String mantnr : locker.contents.keySet()){
-                System.out.println(mantnr+"<===>"+locker.contents.get(mantnr));
-            }
-        }
+
         System.out.println("\n" + solution);
 
-//        scanner.close();
+        scanner.close();
     }
+//    public static void main(String[] args) {
+//        int itemTypes = 5;
+//
+//        List<Item> items = new ArrayList<>();
+//
+//        for (int i = 0; i < itemTypes; i++) {
+//            String name = i+"a";
+//            int maxCapacity = i*10;
+//            int stock = i*11;
+//            items.add(new Item(name, maxCapacity, stock));
+//        }
+//
+//        // 浣跨敤鍒嗙粍浼樺厛绠楁硶
+//        PackingSolution solution = packItemsWithGrouping(items);
+//        for (Locker locker:solution.lockers) {
+//            for (String mantnr : locker.contents.keySet()){
+//                System.out.println(mantnr+"<===>"+locker.contents.get(mantnr));
+//            }
+//        }
+//        System.out.println("\n" + solution);
+//
+////        scanner.close();
+//    }
 
     /**
      * 鍒嗙粍浼樺厛瑁呯绠楁硶
diff --git a/src/main/java/com/zy/asrs/utils/OptimizedLockerPackingUtils.java b/src/main/java/com/zy/asrs/utils/OptimizedLockerPackingUtils.java
new file mode 100644
index 0000000..806fd5d
--- /dev/null
+++ b/src/main/java/com/zy/asrs/utils/OptimizedLockerPackingUtils.java
@@ -0,0 +1,442 @@
+package com.zy.asrs.utils;
+
+import java.util.*;
+
+public class OptimizedLockerPackingUtils {
+
+    public static class Item {
+        String name;
+        double unitSpace;
+        int maxCapacity;
+        int stock;
+        int remaining;
+
+        public Item(String name, int maxCapacity, int stock) {
+            this.name = name;
+            this.maxCapacity = maxCapacity;
+            this.unitSpace = 1.0 / maxCapacity;
+            this.stock = stock;
+            this.remaining = stock;
+        }
+
+        @Override
+        public String toString() {
+            return name + "(鍗曟斁" + maxCapacity + "涓�, 搴撳瓨" + stock + "涓�)";
+        }
+    }
+
+    static class Locker {
+        int id;
+        double remainingSpace;
+        long bindingTags;
+        Map<String, Integer> contents;
+        Set<String> itemTypes;
+
+        public Locker(int id) {
+            this.id = id;
+            this.remainingSpace = 1.0;
+            this.contents = new HashMap<>();
+            this.itemTypes = new HashSet<>();
+            this.bindingTags = System.currentTimeMillis();
+
+        }
+
+        public boolean canAdd(Item item, int quantity) {
+            return remainingSpace >= quantity * item.unitSpace;
+        }
+
+        public void addItem(Item item, int quantity) {
+            double spaceUsed = quantity * item.unitSpace;
+            remainingSpace -= spaceUsed;
+            contents.put(item.name, contents.getOrDefault(item.name, 0) + quantity);
+            itemTypes.add(item.name);
+            item.remaining -= quantity;
+        }
+
+        public boolean containsItemType(String itemName) {
+            return itemTypes.contains(itemName);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("鍌ㄧ墿鏌�").append(id).append(": ");
+            sb.append(String.format("鍓╀綑绌洪棿%.4f", remainingSpace)).append("\n");
+            for (Map.Entry<String, Integer> entry : contents.entrySet()) {
+                sb.append("  ").append(entry.getKey()).append(": ").append(entry.getValue()).append("涓猏n");
+            }
+            return sb.toString();
+        }
+    }
+
+    static class PackingSolution {
+        List<Locker> lockers;
+        int totalLockersUsed;
+        double overallUtilization;
+        int itemTypeChanges;
+        int pureLockers; // 绾绫诲偍鐗╂煖鏁伴噺
+
+        public PackingSolution() {
+            this.lockers = new ArrayList<>();
+        }
+
+        public void addLocker(Locker locker) {
+            lockers.add(locker);
+            totalLockersUsed = lockers.size();
+        }
+
+        public void calculateMetrics() {
+            double totalUsedSpace = 0;
+            itemTypeChanges = 0;
+            pureLockers = 0;
+            String lastItemType = null;
+
+            for (Locker locker : lockers) {
+                totalUsedSpace += (1.0 - locker.remainingSpace);
+
+                // 缁熻绾绫诲偍鐗╂煖
+                if (locker.itemTypes.size() == 1) {
+                    pureLockers++;
+                }
+
+                for (String itemType : locker.itemTypes) {
+                    if (lastItemType != null && !lastItemType.equals(itemType)) {
+                        itemTypeChanges++;
+                    }
+                    lastItemType = itemType;
+                }
+            }
+
+            overallUtilization = totalUsedSpace / totalLockersUsed;
+        }
+
+        @Override
+        public String toString() {
+            calculateMetrics();
+            StringBuilder sb = new StringBuilder();
+            sb.append("=== 浼樺寲鎽嗘斁鏂规 ===\n");
+            sb.append("浣跨敤鐨勫偍鐗╂煖鏁伴噺: ").append(totalLockersUsed).append("涓猏n");
+            sb.append("绾绫诲偍鐗╂煖: ").append(pureLockers).append("涓猏n");
+            sb.append("骞冲潎绌洪棿鍒╃敤鐜�: ").append(String.format("%.2f", overallUtilization * 100)).append("%\n");
+            sb.append("鐗╁搧绉嶇被鍒囨崲娆℃暟: ").append(itemTypeChanges).append("娆n\n");
+
+            // 鍏堟樉绀虹函绉嶇被鍌ㄧ墿鏌滐紝鍐嶆樉绀烘贩鍚堝偍鐗╂煖
+            List<Locker> pureLockersList = new ArrayList<>();
+            List<Locker> mixedLockersList = new ArrayList<>();
+
+            for (Locker locker : lockers) {
+                if (locker.itemTypes.size() == 1) {
+                    pureLockersList.add(locker);
+                } else {
+                    mixedLockersList.add(locker);
+                }
+            }
+
+            sb.append("銆愮函绉嶇被鍌ㄧ墿鏌溿��:\n");
+            for (Locker locker : pureLockersList) {
+                sb.append(locker.toString()).append("\n");
+            }
+
+            sb.append("銆愭贩鍚堝偍鐗╂煖銆�:\n");
+            for (Locker locker : mixedLockersList) {
+                sb.append(locker.toString()).append("\n");
+            }
+
+            return sb.toString();
+        }
+    }
+
+    public static void main(String[] args) {
+        Scanner scanner = new Scanner(System.in);
+
+        System.out.println("璇疯緭鍏ョ墿鍝佺绫绘暟閲�:");
+        int itemTypes = scanner.nextInt();
+        scanner.nextLine();
+
+        List<Item> items = new ArrayList<>();
+
+        for (int i = 0; i < itemTypes; i++) {
+            System.out.println("\n璇疯緭鍏ョ" + (i + 1) + "绉嶇墿鍝佺殑淇℃伅:");
+            System.out.print("鐗╁搧鍚嶇О: ");
+            String name = scanner.nextLine();
+
+            System.out.print("鍗曠瀛樻斁鏈�澶ф暟閲�: ");
+            int maxCapacity = scanner.nextInt();
+
+            System.out.print("搴撳瓨鏁伴噺: ");
+            int stock = scanner.nextInt();
+            scanner.nextLine();
+
+            items.add(new Item(name, maxCapacity, stock));
+        }
+
+        PackingSolution solution = optimizedPacking(items);
+        System.out.println("\n" + solution);
+
+        scanner.close();
+    }
+
+    /**
+     * 浼樺寲瑁呯绠楁硶锛氬厛闆嗕腑澶勭悊鍚岀鐗╁搧锛屾渶鍚庡鐞嗕綑鏂�
+     */
+    public static PackingSolution optimizedPacking(List<Item> items) {
+        List<Item> itemsToPack = new ArrayList<>();
+        for (Item item : items) {
+            itemsToPack.add(new Item(item.name, item.maxCapacity, item.stock));
+        }
+
+        PackingSolution solution = new PackingSolution();
+        int lockerId = 1;
+
+        // 绗竴闃舵锛氬姣忕鐗╁搧杩涜闆嗕腑澶勭悊
+        for (Item item : itemsToPack) {
+            if (item.remaining == 0) continue;
+
+            // 璁$畻杩欑鐗╁搧闇�瑕佸灏戜釜瀹屾暣鐨勫偍鐗╂煖
+            int fullLockersNeeded = item.remaining / item.maxCapacity;
+            int remainder = item.remaining % item.maxCapacity;
+
+            // 鍒嗛厤瀹屾暣鍌ㄧ墿鏌�
+            for (int i = 0; i < fullLockersNeeded; i++) {
+                Locker locker = new Locker(lockerId++);
+                locker.addItem(item, item.maxCapacity);
+                solution.addLocker(locker);
+            }
+
+            // 濡傛灉鏈変綑鏂欙紝鏆傛椂淇濈暀锛堢浜岄樁娈靛鐞嗭級
+        }
+
+        // 绗簩闃舵锛氭敹闆嗘墍鏈変綑鏂�
+        List<Item> remainingItems = new ArrayList<>();
+        for (Item item : itemsToPack) {
+            if (item.remaining > 0) {
+                remainingItems.add(item);
+            }
+        }
+
+        // 濡傛灉杩樻湁浣欐枡锛岀敤鏈�浣抽�傚簲绠楁硶澶勭悊
+        if (!remainingItems.isEmpty()) {
+            processRemainingItems(remainingItems, solution, lockerId);
+        }
+
+        return solution;
+    }
+
+    /**
+     * 澶勭悊鍓╀綑鐗╁搧锛堜綑鏂欙級
+     */
+    private static void processRemainingItems(List<Item> remainingItems, PackingSolution solution, int startLockerId) {
+        int lockerId = startLockerId;
+
+        // 鎸夌┖闂村崰鐢ㄤ粠澶у埌灏忔帓搴忥紙浼樺厛澶勭悊澶х墿鍝侊級
+        remainingItems.sort((a, b) -> Double.compare(b.unitSpace, a.unitSpace));
+
+        for (Item item : remainingItems) {
+            while (item.remaining > 0) {
+                // 浼樺厛灏濊瘯鏀惧叆宸叉湁鍚岀鐗╁搧鐨勫偍鐗╂煖
+                Locker sameTypeLocker = findSameTypeLocker(solution, item);
+                if (sameTypeLocker != null) {
+                    int maxCanAdd = (int) Math.floor(sameTypeLocker.remainingSpace / item.unitSpace);
+                    int actualAdd = Math.min(item.remaining, maxCanAdd);
+                    sameTypeLocker.addItem(item, actualAdd);
+                    continue;
+                }
+
+                // 鍏舵灏濊瘯鏀惧叆鐜版湁鍌ㄧ墿鏌滐紙鏈�浣抽�傚簲锛�
+                Locker bestLocker = findBestLocker(solution, item);
+                if (bestLocker != null) {
+                    int maxCanAdd = (int) Math.floor(bestLocker.remainingSpace / item.unitSpace);
+                    int actualAdd = Math.min(item.remaining, maxCanAdd);
+                    bestLocker.addItem(item, actualAdd);
+                    continue;
+                }
+
+                // 鏈�鍚庡垱寤烘柊鍌ㄧ墿鏌�
+                Locker newLocker = new Locker(lockerId++);
+                int maxCanAdd = (int) Math.floor(1.0 / item.unitSpace);
+                int actualAdd = Math.min(item.remaining, maxCanAdd);
+                newLocker.addItem(item, actualAdd);
+                solution.addLocker(newLocker);
+            }
+        }
+    }
+
+    /**
+     * 瀵绘壘宸叉湁鍚岀鐗╁搧鐨勫偍鐗╂煖
+     */
+    private static Locker findSameTypeLocker(PackingSolution solution, Item item) {
+        Locker bestLocker = null;
+        double bestRemaining = -1;
+
+        for (Locker locker : solution.lockers) {
+            if (locker.containsItemType(item.name) && locker.canAdd(item, 1)) {
+                if (locker.remainingSpace > bestRemaining) {
+                    bestLocker = locker;
+                    bestRemaining = locker.remainingSpace;
+                }
+            }
+        }
+
+        return bestLocker;
+    }
+
+    /**
+     * 瀵绘壘鏈�浣抽�傚簲鐨勫偍鐗╂煖
+     */
+    private static Locker findBestLocker(PackingSolution solution, Item item) {
+        Locker bestLocker = null;
+        double bestRemaining = Double.MAX_VALUE;
+
+        for (Locker locker : solution.lockers) {
+            if (locker.canAdd(item, 1) && locker.remainingSpace < bestRemaining) {
+                bestLocker = locker;
+                bestRemaining = locker.remainingSpace;
+            }
+        }
+
+        return bestLocker;
+    }
+
+    /**
+     * 楂樼骇浼樺寲锛氭櫤鑳戒綑鏂欏垎閰�
+     */
+    public static PackingSolution advancedOptimizedPacking(List<Item> items) {
+        List<Item> itemsToPack = new ArrayList<>();
+        for (Item item : items) {
+            itemsToPack.add(new Item(item.name, item.maxCapacity, item.stock));
+        }
+
+        PackingSolution solution = new PackingSolution();
+        int lockerId = 1;
+
+        // 绗竴闃舵锛氶泦涓鐞嗘瘡绉嶇墿鍝�
+        Map<String, Integer> remainders = new HashMap<>();
+
+        for (Item item : itemsToPack) {
+            if (item.remaining == 0) continue;
+
+            int fullLockers = item.remaining / item.maxCapacity;
+            int remainder = item.remaining % item.maxCapacity;
+
+            for (int i = 0; i < fullLockers; i++) {
+                Locker locker = new Locker(lockerId++);
+                locker.addItem(item, item.maxCapacity);
+                solution.addLocker(locker);
+            }
+
+            if (remainder > 0) {
+                remainders.put(item.name, remainder);
+            }
+        }
+
+        // 绗簩闃舵锛氭櫤鑳戒綑鏂欏垎閰�
+        if (!remainders.isEmpty()) {
+            smartRemainderProcessing(remainders, itemsToPack, solution, lockerId);
+        }
+
+        return solution;
+    }
+
+    /**
+     * 鏅鸿兘浣欐枡澶勭悊锛氬皾璇曞皢浣欐枡缁勫悎鎴愬畬鏁村偍鐗╂煖
+     */
+    private static void smartRemainderProcessing(Map<String, Integer> remainders,
+                                                 List<Item> items,
+                                                 PackingSolution solution,
+                                                 int startLockerId) {
+        int lockerId = startLockerId;
+
+        // 灏濊瘯鎵惧埌鍙互瀹岀編缁勫悎鐨勪綑鏂�
+        boolean foundCombination;
+        do {
+            foundCombination = false;
+
+            // 瀵绘壘鍙互濉弧涓�涓偍鐗╂煖鐨勪綑鏂欑粍鍚�
+            for (Item item1 : items) {
+                if (remainders.getOrDefault(item1.name, 0) == 0) continue;
+
+                for (Item item2 : items) {
+                    if (item1.name.equals(item2.name) || remainders.getOrDefault(item2.name, 0) == 0) continue;
+
+                    double spaceNeeded = remainders.get(item1.name) * item1.unitSpace +
+                            remainders.get(item2.name) * item2.unitSpace;
+
+                    if (spaceNeeded <= 1.0 + 1e-6) { // 鑰冭檻娴偣璇樊
+                        Locker locker = new Locker(lockerId++);
+                        locker.addItem(item1, remainders.get(item1.name));
+                        locker.addItem(item2, remainders.get(item2.name));
+                        solution.addLocker(locker);
+
+                        remainders.put(item1.name, 0);
+                        remainders.put(item2.name, 0);
+                        foundCombination = true;
+                        break;
+                    }
+                }
+                if (foundCombination) break;
+            }
+        } while (foundCombination);
+
+        // 澶勭悊鍓╀綑鐨勯浂鏁d綑鏂�
+        for (Item item : items) {
+            int remainder = remainders.getOrDefault(item.name, 0);
+            if (remainder > 0) {
+                Locker bestLocker = findBestLockerForRemainder(solution, item, remainder);
+                if (bestLocker != null) {
+                    bestLocker.addItem(item, remainder);
+                } else {
+                    Locker newLocker = new Locker(lockerId++);
+                    newLocker.addItem(item, remainder);
+                    solution.addLocker(newLocker);
+                }
+            }
+        }
+    }
+
+    private static Locker findBestLockerForRemainder(PackingSolution solution, Item item, int quantity) {
+        Locker bestLocker = null;
+        double bestFit = Double.MAX_VALUE;
+
+        for (Locker locker : solution.lockers) {
+            if (locker.canAdd(item, quantity)) {
+                double remainingAfterAdd = locker.remainingSpace - quantity * item.unitSpace;
+                if (remainingAfterAdd < bestFit) {
+                    bestLocker = locker;
+                    bestFit = remainingAfterAdd;
+                }
+            }
+        }
+
+        return bestLocker;
+    }
+
+    /**
+     * 鎬ц兘娴嬭瘯鍜屾瘮杈�
+     */
+    public static void performanceTest() {
+        System.out.println("=== 鎬ц兘娴嬭瘯 ===");
+
+        // 娴嬭瘯鏁版嵁
+        List<Item> testItems = Arrays.asList(
+                new Item("X", 20, 87),
+                new Item("Y", 15, 63),
+                new Item("Z", 34, 125),
+                new Item("T", 25, 48),
+                new Item("U", 40, 92)
+        );
+
+        System.out.println("娴嬭瘯鐗╁搧鏁伴噺: " + testItems.size());
+        int totalItems = testItems.stream().mapToInt(item -> item.stock).sum();
+        System.out.println("鎬荤墿鍝佹暟閲�: " + totalItems);
+
+        long startTime = System.currentTimeMillis();
+        PackingSolution solution = optimizedPacking(testItems);
+        long endTime = System.currentTimeMillis();
+
+        System.out.println("\n浼樺寲绠楁硶缁撴灉:");
+        System.out.println("澶勭悊鏃堕棿: " + (endTime - startTime) + "ms");
+        System.out.println("鍌ㄧ墿鏌滄暟閲�: " + solution.totalLockersUsed);
+        System.out.println("绾绫诲偍鐗╂煖: " + solution.pureLockers);
+        System.out.println("绌洪棿鍒╃敤鐜�: " + String.format("%.2f", solution.overallUtilization * 100) + "%");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/asrs/utils/ToSortLineUtils.java b/src/main/java/com/zy/asrs/utils/ToSortLineUtils.java
index 19ee586..7195635 100644
--- a/src/main/java/com/zy/asrs/utils/ToSortLineUtils.java
+++ b/src/main/java/com/zy/asrs/utils/ToSortLineUtils.java
@@ -36,8 +36,7 @@
         return sku+sign_F+po+sign_F+upc;
     }
 
-    public static OrderToLine GetOrderToLine(List<GroupedLockerOptimizerUtils.Item> items,OrderToLine orderToLine){
-        Long bindingTag = System.currentTimeMillis();//娣锋惌鏍囪
+    public static OrderToLine GetOrderToLineGro(List<GroupedLockerOptimizerUtils.Item> items,OrderToLine orderToLine){
         List<OrderToLine.MatList> matLists = new ArrayList<>();
         // 浣跨敤鍒嗙粍浼樺厛绠楁硶
         GroupedLockerOptimizerUtils.PackingSolution solution = GroupedLockerOptimizerUtils.packItemsWithGrouping(items);
@@ -52,11 +51,34 @@
                         split[2],   //barcode -> upc -> s2
                         1,
                         null,   //origin -> supplier 璐ф簮
-                        bindingTag
+                        locker.bindingTags
                 );
                 matLists.add(mat);
             }
-            bindingTag++;
+        }
+        orderToLine.setMatList(matLists);
+        return orderToLine;
+    }
+
+    public static OrderToLine GetOrderToLineOpt(List<OptimizedLockerPackingUtils.Item> items,OrderToLine orderToLine){
+        List<OrderToLine.MatList> matLists = new ArrayList<>();
+        // 浣跨敤鍒嗙粍浼樺厛绠楁硶
+        OptimizedLockerPackingUtils.PackingSolution packingSolution = OptimizedLockerPackingUtils.optimizedPacking(items);
+        for (OptimizedLockerPackingUtils.Locker locker:packingSolution.lockers) {
+            for (String mantnr : locker.contents.keySet()){
+                System.out.println(mantnr+"<===>"+locker.contents.get(mantnr));
+                String[] split = mantnr.split(Pattern.quote(sign_F));
+                OrderToLine.MatList mat = new OrderToLine.MatList(
+                        split[0],  // matnr -> sku
+                        split[1],  //  supp -> po -> s1
+                        locker.contents.get(mantnr).doubleValue(),   //鏁存枡
+                        split[2],   //barcode -> upc -> s2
+                        1,
+                        null,   //origin -> supplier 璐ф簮
+                        locker.bindingTags
+                );
+                matLists.add(mat);
+            }
         }
         orderToLine.setMatList(matLists);
         return orderToLine;
diff --git a/src/main/java/com/zy/asrs/utils/param/ItemUtilParam.java b/src/main/java/com/zy/asrs/utils/param/ItemUtilParam.java
new file mode 100644
index 0000000..4ca44df
--- /dev/null
+++ b/src/main/java/com/zy/asrs/utils/param/ItemUtilParam.java
@@ -0,0 +1,25 @@
+package com.zy.asrs.utils.param;
+
+import lombok.Data;
+
+@Data
+public class ItemUtilParam {
+    String name;
+    double unitSpace;
+    int maxCapacity;
+    int stock;
+    int remaining;
+
+    public ItemUtilParam(String name, int maxCapacity, int stock) {
+        this.name = name;
+        this.maxCapacity = maxCapacity;
+        this.unitSpace = 1.0 / maxCapacity;
+        this.stock = stock;
+        this.remaining = stock;
+    }
+
+    @Override
+    public String toString() {
+        return name + "(鍗曟斁" + maxCapacity + "涓�, 搴撳瓨" + stock + "涓�)";
+    }
+}

--
Gitblit v1.9.1