簡體   English   中英

如何生成給定長度的所有可能組合

[英]How to generate all possible combinations of given length

假設我們有一個價格列表items_prices = [1500, 2000, 1600, 2100, 2200, 1400, 1900]

我們想要找到將所有 7 個價格放入每個桶中包含以下價格數量的桶的所有可能組合[3, 2, 2] 價格是否放在同一個桶中並不重要,但放在哪個桶中價格很重要。

這該怎么做? 我找到了這個答案,但它假設我們只對給定元素的r長度子序列的一種組合感興趣。 然而,在這里,我們也對包含3價格的第一個組合之后的剩余部分感興趣,然后是2 ,最后是2

請注意,給定桶中的 7 個價格和組合是一般問題的簡單情況。

我可能錯誤地解釋了這一點,如果有的話,我會編輯這個答案,但我假設單個組中的順序無關緊要。

如果是這樣,則有 7C5 = 21 種獨特的方式(例如,在 3 組中, [1500, 2000, 1600][2000, 1600, 1500] )。 我只是做所有獨特的組合(不是排列),從 7 中選擇 5 個價格,然后將 5 分成 3 和 2,然后附加剩余的 2 個沒有被選為第 3 組的值(按任一順序)。

他們是:

((1600, 1400, 1900), (2000, 2100), (2200, 1500))
((1600, 1400, 1900), (2000, 2200), (1500, 2100))
((1600, 1400, 1900), (2000, 1500), (2200, 2100))
((1600, 1400, 1900), (2100, 2200), (2000, 1500))
((1600, 1400, 1900), (2100, 1500), (2000, 2200))
((1600, 1400, 1900), (2200, 1500), (2000, 2100))
((1600, 1400, 2000), (2100, 2200), (1500, 1900))
((1600, 1400, 2000), (2100, 1500), (2200, 1900))
((1600, 1400, 2000), (2200, 1500), (1900, 2100))
((1600, 1400, 2100), (2200, 1500), (2000, 1900))
((1600, 1900, 2000), (2100, 2200), (1400, 1500))
((1600, 1900, 2000), (2100, 1500), (1400, 2200))
((1600, 1900, 2000), (2200, 1500), (1400, 2100))
((1600, 1900, 2100), (2200, 1500), (1400, 2000))
((1600, 2000, 2100), (2200, 1500), (1400, 1900))
((1400, 1900, 2000), (2100, 2200), (1600, 1500))
((1400, 1900, 2000), (2100, 1500), (1600, 2200))
((1400, 1900, 2000), (2200, 1500), (1600, 2100))
((1400, 1900, 2100), (2200, 1500), (1600, 2000))
((1400, 2000, 2100), (2200, 1500), (1600, 1900))
((1900, 2000, 2100), (2200, 1500), (1600, 1400))

計算自

[(chosen_5[:3], chosen_5[3:5], tuple(set(items_prices) - set(chosen_5))) for chosen_5 in tuple(itertools.combinations(items_prices, 5))]

請注意,在所有 3 個元組中,實際值並不完全相同,即使順序不同,因為我們不關心值的順序 - 我們可以將每個順序中的 3 個元組視為 3 個(凍結)集.


但是,如果您的意思是各個組中的排序確實很重要,那么有 7 個! = 5040 個可能的排列,這與選擇 7 個中的任意 1 個相同,然后是 6 個剩余中的任意一個(因為您已經選擇了一個),然后是 5 個中的 1 個......直到最后一個。他們都可以計算使用

[(this_permutation[:3], this_permutation[3:5], this_permutation[5:]) for this_permutation in itertools.permutations(items_prices)]
((1500, 2000, 1600), (2100, 2200), (1400, 1900))
((1500, 2000, 1600), (2100, 2200), (1900, 1400))
((1500, 2000, 1600), (2100, 1400), (2200, 1900))
((1500, 2000, 1600), (2100, 1400), (1900, 2200))
((1500, 2000, 1600), (2100, 1900), (2200, 1400))
((1500, 2000, 1600), (2100, 1900), (1400, 2200))
((1500, 2000, 1600), (2200, 2100), (1400, 1900))
((1500, 2000, 1600), (2200, 2100), (1900, 1400))
((1500, 2000, 1600), (2200, 1400), (2100, 1900))
((1500, 2000, 1600), (2200, 1400), (1900, 2100))
((1500, 2000, 1600), (2200, 1900), (2100, 1400))
((1500, 2000, 1600), (2200, 1900), (1400, 2100))
...

請注意,第一個和第二個元組是不同的,因為 2200 和 1500 的順序不同,在使用組合而非排列的其他輸出中不會區分

首先,您發布的答案不假設任何內容。 “組合”是一個定義明確的術語。 https://mathworld.wolfram.com/Combination.html

其次,我會按如下方式處理問題(在偽代碼中):

  • 生成從0len(items_prices) - 1的所有索引的列表
  • 從給定的索引生成長度為 3 的所有組合的列表(使用您鏈接的 Combination 和itertools.combinations函數的正式定義)。
  • 對於每個生成的組合:
    • 刪除選定的索引
    • 從剩余的索引列表中為下一個存儲桶(在您的長度為 2 的示例中)生成組合

只要你沒有桶就繼續。

我使用索引而不是元素來處理輸入時價格可能重復的情況。 如果您有不同的約束,您可以使用實際值。

暫無
暫無

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

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