总和等于 0 的一组数字(也是负数)的最大子集
Largest subset from set of numbers (also negative) having sum equal 0
我有一大堆数字,它们的顺序是固定的。简单来说,逻辑如下所示:
data['values'] = [1,1,3,4,4,-9,10]
data['order'] = [1,2,3,4,5,6,7]
ExpectedSum = 0
我想要return的是我们可以得到的总和等于0的最大可能值子集的原始顺序和值。
对于这种情况,一个最佳解决方案是
solution['values'] = [1,1,3,4,-9]
solution['order'] = [1,2,3,4,6]
求和也可以通过用5阶数代替4阶数来实现,但是,一个最优解就足够了。目标是达到总和 =0 的子集的最大可能大小。
正在寻找背包问题和最大子数组算法的变体,但 none 满足了我的需求。
感谢任何提示或指示。
也许我遗漏了什么(已经晚了),但是如果我们将具有 k
个元素的子集表示为 S(k)
并且我们总共有 N
个元素,您可以:
- 看看
S(N)
是否和为0;如果是这样,那就是最大的子集
- 如果不是,看
S(N-1)
中有没有和为0;有N
个这样的集合
- 如果没有,请查看
S(N-2)
是否有;有N*(N-1)
个这样的集合
等等。这是一个“蛮力”解决方案,可能远非最佳,但如果预计最大子集相对较大(大小接近 N
),它应该不会太糟糕。请注意,每一步都可以利用前一步计算的总和。
您的 solution[order]
似乎是解决方案子集的索引。当然可以做到,但我不确定为什么你需要同时获得这些值和它们的索引?有点多余。
最后,虽然在纯 Python 中可行,但 NumPy 库可能对此类问题有用。
所有固定长度的子集都可以用“n选k”的方式找到。要找到最长的迭代,从 k=n 开始并减一。
import itertools as it
def combination_finder(l: list) -> tuple:
for i in range(len(l)):
for pairs in it.combinations(enumerate(l, start=0), len(l)-i):
i, c = zip(*pairs)
if sum(c) == 0:
return i, c
raise Exception('No combination found.')
l = [1,1,3,4,4,-9,10]
id_, comb = combination_finder(l)
print(id_)
print(comb)
备注:要使id_
从1开始,只需将enumerate
更改为enumerate(l, start=1)
我有一大堆数字,它们的顺序是固定的。简单来说,逻辑如下所示:
data['values'] = [1,1,3,4,4,-9,10]
data['order'] = [1,2,3,4,5,6,7]
ExpectedSum = 0
我想要return的是我们可以得到的总和等于0的最大可能值子集的原始顺序和值。 对于这种情况,一个最佳解决方案是
solution['values'] = [1,1,3,4,-9]
solution['order'] = [1,2,3,4,6]
求和也可以通过用5阶数代替4阶数来实现,但是,一个最优解就足够了。目标是达到总和 =0 的子集的最大可能大小。
正在寻找背包问题和最大子数组算法的变体,但 none 满足了我的需求。
感谢任何提示或指示。
也许我遗漏了什么(已经晚了),但是如果我们将具有 k
个元素的子集表示为 S(k)
并且我们总共有 N
个元素,您可以:
- 看看
S(N)
是否和为0;如果是这样,那就是最大的子集 - 如果不是,看
S(N-1)
中有没有和为0;有N
个这样的集合 - 如果没有,请查看
S(N-2)
是否有;有N*(N-1)
个这样的集合
等等。这是一个“蛮力”解决方案,可能远非最佳,但如果预计最大子集相对较大(大小接近 N
),它应该不会太糟糕。请注意,每一步都可以利用前一步计算的总和。
您的 solution[order]
似乎是解决方案子集的索引。当然可以做到,但我不确定为什么你需要同时获得这些值和它们的索引?有点多余。
最后,虽然在纯 Python 中可行,但 NumPy 库可能对此类问题有用。
所有固定长度的子集都可以用“n选k”的方式找到。要找到最长的迭代,从 k=n 开始并减一。
import itertools as it
def combination_finder(l: list) -> tuple:
for i in range(len(l)):
for pairs in it.combinations(enumerate(l, start=0), len(l)-i):
i, c = zip(*pairs)
if sum(c) == 0:
return i, c
raise Exception('No combination found.')
l = [1,1,3,4,4,-9,10]
id_, comb = combination_finder(l)
print(id_)
print(comb)
备注:要使id_
从1开始,只需将enumerate
更改为enumerate(l, start=1)