From b0926b3d4379d087d5c0187882b98be0ed88da83 Mon Sep 17 00:00:00 2001
From: skyouc
Date: 星期一, 28 四月 2025 17:40:44 +0800
Subject: [PATCH] #新增  1. 波次生成出库任务

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/OptimalAlgorithmUtil.java |  174 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 131 insertions(+), 43 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/OptimalAlgorithmUtil.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/OptimalAlgorithmUtil.java
index 7ada63a..a3704cb 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/OptimalAlgorithmUtil.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/OptimalAlgorithmUtil.java
@@ -6,9 +6,9 @@
 import java.util.stream.Collectors;
 
 /**
+ * @param
  * @author Ryan
  * @description 鏍规嵁瀵硅薄澶氫釜灞炴�у悎骞跺鐞�
- * @param
  * @return
  * @time 2025/4/25 10:55
  */
@@ -46,9 +46,9 @@
     }
 
     /**
+     * @param
      * @author Ryan
      * @description 鐢ㄤ簬瀛樺偍澶氫釜鍒嗙粍閿殑鍐呴儴绫�
-     * @param
      * @return
      * @time 2025/4/25 10:56
      */
@@ -80,52 +80,140 @@
     }
 
 
-    public static List<Double> findBestCombination(Double[] candidates, double targetSum) {
-        bestSolution = null;
-        target = targetSum;
-        minDifference = Double.MAX_VALUE;
-        Arrays.sort(candidates);
-        backtrack(candidates, 0, new ArrayList<>(), 0.0);
-
-        // 濡傛灉娌℃湁绮剧‘瑙o紝杩斿洖鏈�鎺ヨ繎鐨勮繎浼艰В
-        return bestSolution != null ? bestSolution : new ArrayList<>();
-    }
-
-    private static void backtrack(Double[] candidates, int start,
-                                  List<Double> current, double currentSum) {
-        // 璁$畻褰撳墠鍜屼笌鐩爣鐨勫樊鍊�
-        double difference = Math.abs(currentSum - target);
-
-        // 濡傛灉鎵惧埌鏇翠紭瑙o紙宸�兼洿灏忔垨宸�肩浉鍚屼絾缁勫悎鏇寸煭锛�
-        if (difference < minDifference - EPSILON ||
-                (Math.abs(difference - minDifference) < EPSILON &&
-                        (bestSolution == null || current.size() < bestSolution.size()))) {
-            minDifference = difference;
-            bestSolution = new ArrayList<>(current);
+    /**
+     * @param
+     * @return
+     * @author Ryan
+     * @description 鑾峰彇鍏ㄦ嫋鎴栭潪鍏ㄦ嫋搴撲綅
+     * @time 2025/4/28 09:41
+     */
+    public static List<Integer> findCombination(double[] nums, Double target) {
+        // 澶勭悊绛夊�兼儏鍐�
+        List<Integer> equal = findEqual(nums, target);
+        if (equal != null && !equal.isEmpty()) {
+            return equal;
         }
 
-        // 濡傛灉宸茬粡鎵惧埌绮剧‘瑙o紝涓嶉渶瑕佺户缁悳绱㈡洿闀跨殑缁勫悎
-        if (minDifference < EPSILON) {
+        // 澶勭悊澶т簬鐨勬儏鍐�
+        List<Integer> greater = findGreater(nums, target);
+        if (greater != null && !greater.isEmpty()) {
+            return greater;
+        }
+
+        // 澶勭悊灏忎簬鐨勬儏鍐�
+        List<Integer> less = findLess(nums, target);
+        return less != null ? less : new ArrayList<>(); // 纭繚涓嶈繑鍥瀗ull
+    }
+
+    /**
+     * @author Ryan
+     * @description 浣跨敤鍔ㄦ�佽鍒掑鎵惧拰绛変簬鐩爣鍊肩殑鏈�灏戝厓绱犵粍鍚堛�傚姩鎬佽鍒掓暟缁刣p璁板綍杈惧埌姣忎釜鍜屾墍闇�鐨勬渶灏戝厓绱犳暟鐩紝prev鏁扮粍璁板綍璺緞浠ヤ究鍥炴函鎵惧埌鍏蜂綋绱㈠紩銆�
+     * @param  
+     * @return 
+     * @time 2025/4/28 12:33
+     */
+    private static List<Integer> findEqual(double[] nums, double target) {
+        int n = nums.length;
+        double[] dp = new double[(int) (target * 100 + 1)]; // 鏀惧ぇ100鍊嶅鐞嗙簿搴﹂棶棰�
+        Arrays.fill(dp, Double.MAX_VALUE);
+        dp[0] = 0;
+        int[] prev = new int[(int) (target * 100 + 1)];
+        Arrays.fill(prev, -1);
+
+        for (int j = 0; j < n; j++) {
+            int num = (int) (nums[j] * 100); // 鏀惧ぇ100鍊嶅鐞嗙簿搴﹂棶棰�
+            for (int i = (int) (target * 100); i >= num; i--) {
+                if (dp[i - num] != Double.MAX_VALUE && dp[i - num] + 1 < dp[i]) {
+                    dp[i] = dp[i - num] + 1;
+                    prev[i] = j;
+                }
+            }
+        }
+
+        if (dp[(int) (target * 100)] == Double.MAX_VALUE) {
+            return null;
+        }
+
+        List<Integer> indices = new ArrayList<>();
+        int current = (int) (target * 100);
+        while (current > 0) {
+            int j = prev[current];
+            if (j == -1) return null;
+            indices.add(j);
+            current -= (int) (nums[j] * 100);
+        }
+
+        return indices;
+    }
+
+    /**
+     * @author Ryan
+     * @description 灏嗘暟缁勯檷搴忔帓搴忓悗锛岃椽蹇冨湴绱姞鍏冪礌鐩村埌鎬诲拰瓒呰繃鐩爣鍊硷紝杩斿洖杩欎簺鍏冪礌鐨勭储寮�
+     * @param
+     * @return 
+     * @time 2025/4/28 12:34
+     */
+    private static List<Integer> findGreater(double[] nums, double target) {
+        List<double[]> sorted = new ArrayList<>();
+        for (int i = 0; i < nums.length; i++) {
+            sorted.add(new double[]{nums[i], i});
+        }
+        sorted.sort((a, b) -> Double.compare(b[0], a[0]));
+
+        double sum = 0;
+        List<Integer> indices = new ArrayList<>();
+        for (double[] pair : sorted) {
+            sum += pair[0];
+            indices.add((int) pair[1]);
+            if (sum > target) {
+                return indices;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @author Ryan
+     * @description 浣跨敤鍥炴函娉曠敓鎴愭墍鏈夊彲鑳界殑缁勫悎锛屽鎵炬�诲拰鏈�澶т絾涓嶈秴杩囩洰鏍囧�肩殑缁勫悎锛屽苟璁板綍鍏冪礌鏁扮洰鏈�灏戠殑缁勫悎銆�
+     * @param
+     * @return
+     * @time 2025/4/28 12:34
+     */
+    private static List<Integer> findLess(double[] nums, double target) {
+        int n = nums.length;
+        List<Integer> bestIndices = new ArrayList<>();
+        double[] maxSum = {-1.0};
+        for (int k = 1; k <= n; k++) {
+            List<Integer> currentIndices = new ArrayList<>();
+            double[] currentMax = {-1.0};
+            backtrack(nums, target, 0, k, 0.0, 0, currentIndices, currentMax, new ArrayList<>());
+            if (currentMax[0] != -1.0) {
+                if (currentMax[0] > maxSum[0] || (currentMax[0] == maxSum[0] && currentIndices.size() < bestIndices.size())) {
+                    maxSum[0] = currentMax[0];
+                    bestIndices = new ArrayList<>(currentIndices);
+                }
+            }
+        }
+
+        return bestIndices.isEmpty() ? null : bestIndices;
+    }
+
+    private static void backtrack(double[] nums, double target, int start, int k, double currentSum, int count, List<Integer> currentIndices, double[] currentMax, List<Integer> path) {
+        if (count == k) {
+            if (currentSum <= target && currentSum > currentMax[0]) {
+                currentMax[0] = currentSum;
+                currentIndices.clear();
+                currentIndices.addAll(path);
+            }
             return;
         }
 
-        // 閬嶅巻鍊欓�夋暟瀛�
-        for (int i = start; i < candidates.length; i++) {
-            double num = candidates[i];
-
-            // 鍓灊锛氬鏋滃綋鍓嶅拰宸茬粡杩滃ぇ浜庣洰鏍囧�硷紝璺宠繃
-            if (currentSum + num > target + minDifference + EPSILON) {
-                continue;
-            }
-
-            // 璺宠繃閲嶅鏁板瓧
-            if (i > start && Math.abs(candidates[i] - candidates[i - 1]) < EPSILON) {
-                continue;
-            }
-
-            current.add(num);
-            backtrack(candidates, i + 1, current, currentSum + num);
-            current.remove(current.size() - 1);
+        for (int i = start; i < nums.length; i++) {
+            if (currentSum + nums[i] > target) continue;
+            path.add(i);
+            backtrack(nums, target, i + 1, k, currentSum + nums[i], count + 1, currentIndices, currentMax, path);
+            path.remove(path.size() - 1);
         }
     }
 

--
Gitblit v1.9.1