簡體   English   中英

列表中總和等於或小於給定數字的元素列表

[英]list of elements from a list that sum is equal or less than to a given number

n = [5, 5, 4, 6] # number of list
X = 8 # user have to pass 2 input has X, Y.
Y = 8
result1 = [5] or [5] or [4] or [6] # if I choose 5. n = [5,4,6]
# total = sum(result1).
# total <= user X.
result2 = [5] or [4] or [6]
# total = sum(result2).
# total <= user Y. 
Ans : 2

n = [6,5,2,1,8] 
X = 17
Y = 5
X = [8, 6, 2, 1] 
Y = [5] 
Ans: 5

n = [6,5,5,4,3] 
X = 8 
Y = 9
X = [5,3] # if I choose 5,3 remaining list of elements will be [6,5,4]
Y = [5,4]
Ans : 4

1.我找不到這個邏輯技巧。 所以請幫助我。 2.我試着像子集和一樣解決。 但我仍然無法弄清楚邏輯。 注意:使用python語言。

除非您正在尋找最大化兩個值的解決方案,否則您可以獲得每個數字的最接近的總和(在第二次搜索之前從列表中刪除第一個結果的項目)。

如果是這種情況,您可以通過選擇每個數字作為組合中的第一個數字並使用剩余數字遞歸以接近剩余總和來遞歸處理它。

要處理 Y,您需要第二個函數從列表中刪除(減去)X 結果。

def sumless(A,S):
    if not S: return []       # target reached
    closest = []              # track closest combo
    for i,a in enumerate(A):  # try each number as start of combo
        if a>S: continue      # skip nnumbers that are too large
        sl = [a] + sumless(A[i+1:],S-a) # find closest with rest
        if sum(sl)>=sum(closest):  
            closest = sl      # track closest combo
    return closest


def subtract(A,B):
    B = B.copy()
    return [a for a in A if a not in B or B.pop(B.index(a))*0 ]

輸出:

n = [5,5,4,6] 
X = 8
Y = 8
Xn = sumless(n,X)
Yn = sumless(subtract(n,Xn),Y)
print("X",Xn) # [6]
print("Y",Yn) # [5]

n = [6,5,2,1,8] 
X = 17
Y = 5
Xn = sumless(n,X)
Yn = sumless(subtract(n,Xn),Y)
print(Xn) # [6,2,1,8]
print(Yn) # [5]

n = [6,5,5,4,3] 
X = 8 
Y = 9
Xn = sumless(n,X)
Yn = sumless(subtract(n,Xn),Y)
print(Xn) # [5,3]
print(Yn) # [5,4]

如果您確實需要獲得最大可能的“最接近”總和,則需要組合兩個目標的所有子集並找到最佳的一對子集(即總和最大的地方):

def sumGen(A,S):                        # sum set generator
    if not S: return                    # target reached
    for i,a in enumerate(A):            # try each number as start 
        if a>S: continue                # skip if too large
        yield [a]                       # return single value
        for sl in sumGen(A[i+1:],S-a):  # combine rest
            yield [a]+sl                # return longer combos

def twoSums(A,X,Y):
    bestX,bestY,bestSum = [],[],0       # track closest pair of combos
    for Xn in sumGen(A,X):              # subsets <= X
        for Yn in sumGen(subtract(A,Xn),Y): # subsets <= Y (from rest)
            if sum(Xn)+sum(Yn)>bestSum:     # track closest
                bestX,bestY,bestSum = Xn,Yn,sum(Xn)+sum(Yn)
    return bestX,bestY

輸出:(與上面相同,因為您的示例沒有突出簡單搜索和優化搜索之間的區別)

n = [5,5,4,6] 
X = 8
Y = 8
print(*twoSums(n,X,Y)) # [6],[5]


n = [6,5,2,1,8] 
X = 17
Y = 5
print(*twoSums(n,X,Y)) # [6, 2, 1, 8] [5]

n = [6,5,5,4,3] 
X = 8 
Y = 9
print(*twoSums(n,X,Y)) # [5, 3] [5, 4]

不過,這會有所作為:

n = [6,5,5,4,3,2] 
X = 9 
Y = 15
Xn = sumless(n,X)
Yn = sumless(subtract(n,Xn),Y)
print(Xn) # [4,3,2] = 9
print(Yn) # [6,5]   = 11
print(*twoSums(n,X,Y)) # [6, 3] [5, 5, 4] = 9, 14

暫無
暫無

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

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