簡體   English   中英

總和等於 0 的一組數字(也是負數)的最大子集

[英]Largest subset from set of numbers (also negative) having sum equal 0

我有大量具有定義順序的數字。 簡單來說,邏輯如下所示:

數據['值'] = [1,1,3,4,4,-9,10]

數據['訂單'] = [1,2,3,4,5,6,7]

預期總和 = 0

我希望返回的是我們可以在總和等於 0 的情況下獲得的最大可能值子集的原始順序和值。對於這種情況,一個最佳解決方案是

解決方案['值'] = [1,1,3,4,-9]

解決方案['訂單'] = [1,2,3,4,6]

求和也可以通過用五階數替換四階數來實現,但是,一個最優解就足夠了。 目標是達到總和 = 0 的子集的最大可能大小。

一直在尋找背包問題和最大子數組算法的變體,但沒有一個能滿足我的需求。

任何提示或指示表示贊賞。

可以使用“n choose 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)

也許我遺漏了一些東西(已經晚了),但是如果我們將具有k個元素的子集表示為S(k)並且我們總共有N個元素,您可以:

  • 查看S(N)總和是否為 0; 如果是這樣,那就是最大的子集
  • 如果不是,則查看S(N-1)中是否有任何一個和為 0; N個這樣的集合
  • 如果不是,則查看S(N-2)中是否有任何一個是; N*(N-1)這樣的集合

等等。 這是一個“蠻力”解決方案,可能遠非最佳,但如果預計最大子集相對較大(大小接近N ),它應該不會太糟糕。 請注意,每個步驟都可以使用在前一步中計算的總和。

您的solution[order]似乎是解決方案子集的索引。 當然可以做到,但我不確定為什么你需要同時獲得這些值和它們的索引? 這有點多余。

最后,雖然在純 Python 中可行,但 NumPy 庫可能對此類問題有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM