You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多数值近似均等分配的优化方案及多列表分配方法咨询

多数值近似均等分配的优化方案及多列表分配方法咨询

嘿,我来帮你拆解这个问题~首先针对你现有的分配方法,我们可以优化得更均衡;另外关于多列表的分配逻辑,也有清晰的思路可以参考。

一、更均衡的两列表分配方案

你当前的思路是先降序排序,再把元素往总和更小的列表里加,直到列表满了再转向另一个。这个贪心策略简单高效,但有时候会因为列表长度的限制,错过更优的分配组合——毕竟当其中一个列表先满5个元素后,剩下的元素只能全丢去另一个,可能拉大和的差距。

针对10个元素分成两个各5个的场景,我们可以试试改进的贪心策略,或者在数据量小的情况下直接用回溯法找最优解:

1. 改进版贪心(更均衡的贪心逻辑)

排序后,我们先保证两个列表的元素数量同步增长,再根据总和调整分配方向,比“先填满一个”的方式更容易得到均衡结果:

import random

# 生成随机数列表
intList = [random.randint(10, 200) for _ in range(10)]
intList.sort(reverse=True)

listX = []
listY = []

for num in intList:
    # 优先填补元素更少的列表;元素数相同则往总和更小的列表加
    if len(listX) < len(listY):
        listX.append(num)
    elif len(listY) < len(listX):
        listY.append(num)
    else:
        if sum(listX) <= sum(listY):
            listX.append(num)
        else:
            listY.append(num)

print(f"listX = {listX} \nlistY = {listY}\nsumX = {sum(listX)}, sumY = {sum(listY)}")

2. 回溯法找最优解(绝对均衡)

如果追求理论上最均衡的分配(总和差最小),因为元素数量只有10个,回溯法的计算量完全可以接受,它会遍历所有可能的5+5分配组合,找到总和差最小的那一组:

import random

intList = [random.randint(10, 200) for _ in range(10)]
intList.sort(reverse=True)

min_diff = float('inf')
best_x = []
best_y = []

def backtrack(index, current_x, current_y):
    global min_diff, best_x, best_y
    # 终止条件:所有元素分配完毕
    if index == len(intList):
        if len(current_x) == 5 and len(current_y) ==5:
            diff = abs(sum(current_x) - sum(current_y))
            if diff < min_diff:
                min_diff = diff
                best_x = current_x.copy()
                best_y = current_y.copy()
        return
    # 尝试把当前元素加入x(如果x还没满)
    if len(current_x) <5:
        current_x.append(intList[index])
        backtrack(index+1, current_x, current_y)
        current_x.pop()
    # 尝试把当前元素加入y(如果y还没满)
    if len(current_y) <5:
        current_y.append(intList[index])
        backtrack(index+1, current_x, current_y)
        current_y.pop()

backtrack(0, [], [])
print(f"最优分配:\nlistX = {best_x} \nlistY = {best_y}\nsumX = {sum(best_x)}, sumY = {sum(best_y)}\n差值:{min_diff}")

二、多列表的分配方法

如果是要把数据分配到多个目标列表(每个最多5个元素),核心思路是扩展贪心策略:每次把当前最大的元素加到当前总和最小且未填满的列表里,循环直到所有元素分配完毕。

举个分配到3个列表的实现例子:

import random

intList = [random.randint(10, 200) for _ in range(12)]  # 12个元素,分配到3个列表(最多各5个)
intList.sort(reverse=True)

# 初始化3个空列表
target_lists = [[], [], []]

for num in intList:
    # 筛选出未满的列表,按总和排序后取最小的那个添加元素
    available = [lst for lst in target_lists if len(lst) <5]
    available.sort(key=lambda x: sum(x))
    available[0].append(num)

# 打印结果
for i, lst in enumerate(target_lists, 1):
    print(f"list{i} = {lst},总和:{sum(lst)}")

如果是从多个源列表取数分配,可以先把所有源列表的元素合并成一个大列表,再按上面的多列表分配逻辑处理;如果需要保留源列表的归属,可以给每个元素带上来源标记,分配后再按需拆分。

备注:内容来源于stack exchange,提问作者권대현

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 12:45:29