簡體   English   中英

如何獲取我的列表的所有組合?

[英]How can I obtain all combinations of my list?

我正在嘗試創建一個包含兩個數字的所有可能組合的數組。

我的數組是[0, 17.1]

我希望在 48 個元素的列表中獲得這兩個值的所有可能組合,這兩個值都可以重復。

from itertools import combinations_with_replacement
array = [0, 17.1]
combo_wr = combinations_with_replacement(array, 48)
print(len(list(combo_wr)))

我嘗試使用itertools.combinations_with_replacement來創建如下所示的內容 -> combo_wr = combinations_with_replacement(array, 48)

當我打印這個長度時,我希望有一個更大的數字,但我只得到這些數字的 49 個組合。 我哪里出錯了,或者什么其他函數可以更好地獲得所有可能的組合,順序在實例中並不重要。

以下是我迄今為止為可重復性所做的嘗試

>>> from itertools import combinations_with_replacement
>>> array = [0, 17.1]
>>> combo_wr = combinations_with_replacement(array, 48)
>>> print(len(list(combo_wr)))
49

一個由48數字組成的序列,每個數字從 2 個不同的選項中選出,搜索空間為2^48 ,即281.4萬億。

添加一個常量,即數字的總和應大於 250,然后使用[0,17.1]表示至少有 15 個元素必須是17.1因此您將搜索空間減少48 choose 15 ,即 1 萬億,IE 不夠發揮很大的作用。

如果您將第一個(或最后一個)15 個元素設置為17.1那么它將減少選擇其余元素的搜索空間,因此2^(58-15) = 2^33即 86 億,但我不確定是您真正想要的約束,或者它是否仍然足夠小以供使用。

因此,產生您要求的結果的代碼不太可能對您有所幫助。

但是如果你仍然需要幫助生成那些數萬億的組合

闡明您可以使用的不同選項:

  • itertools.product給出了每一個可能的itertools.product序列
  • itertools.combinations給出給定長度的無序子集
  • itertools.permutations給出了重新排序給定序列的所有方法,或給定長度的所有子集的排序
  • itertools.combinations_with_replacement給出不同選項的重復次數唯一的所有子集,對於 2 個元素輸入,這就像“在 n 次硬幣翻轉后,正面數量唯一的序列是什么”

permutationscombinations對於len(array)==2r=48沒有意義,因為它們是關於子集的, product會做比你想要的更多的冗余。

順序在實例中無關緊要。

如果是這種情況,那么您可能只是期待更多的組合。

我希望獲得所有這些,但是否有可能縮小其中滿足總和值 >= 250 的范圍

好的,那么你可以得到每個元素總和的唯一值, combinations_with_replacements然后對其進行permutations

array = [0, 17.1]
reps = 48
lower_bound = 250
upper_bound = float("inf") # you might have an upper bound, if not you can remove this from the condition below or leave it as inf
for combo in combinations_with_replacement(array, reps):
    if lower_bound <= sum(combo) <= upper_bound:
        # this combo of 'number of elements that are 17.1` meets criteria for further investigation
        for perm in permutations(combo):
            do_thing(perm)

盡管這最終仍然會訪問大量重復條目,因為具有大量重復條目的序列的permutations將交換相等的元素並給出相同的條目,因此我們可以做得更好。

首先, combinations_with_replacement實際上只是傳達了我們正在處理的每個元素的數量,因此我們可以只for k in range(reps)執行for k in range(reps)來獲取該信息,然后希望每個排列都恰好具有array第二個元素的k重復 -這恰好相當於選擇k索引來設置。

所以我們可以使用combinations(range(reps), k)來獲得一組索引以設置為第二個元素,我相信這是您必須檢查的最小可能序列集以滿足“總和大於250要求。

reps = 48
def isSummationValidCombo(summation):
    return summation >= 250

for k in range(reps):
    summation = array[1] *k + array[0] * (reps-k)
    if not isSummationValidCombo(summation):
        continue
    for indices_of_sequence_to_set_to_second_element in combinations(range(reps), k):
        # each combination of k inices to set to the higher value
        seq = [array[0]]*reps
        for idx in indices_of_sequence_to_set_to_second_element:
            seq[idx] = array[1]
        do_thing(seq)

這將使您的組合數量為 280 萬億,而product會影響 281 萬億,因此您可能需要找出其他技術來減少搜索空間

暫無
暫無

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

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