簡體   English   中英

列出所有組合但有限制

[英]List all combinations but with restriction

我找到了列出以k個元素為一組的n個元素的所有可能組合的方法。 從數學上看,數字很容易:n!/(k!*(nk)!),使用itertools的python代碼非常簡單:

>>> import itertools
>>> a = [1,2,3,4]
>>> list(itertools.combinations(a,3))
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

但是如何實現這樣的限制:僅列出共有m個元素的組? 因此,在前面的示例中,對於m = 1,結果應為:

[(1, 2, 3)]

有5個元素且m = 1:

>>> b=[1,2,3,4,5]
>>> list(itertools.combinations(b,3))
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)]

所以我的結果是:

[(1, 2, 3), (1, 4, 5)]

考慮到只有m個人可以在結果組中重復,此問題的實際應用是如何對人員進行分組。 想法是找到與不同的人在一起的團體,避免“朋友”的團體。 想象一下,這是重復幾天的學校活動,我們要確保避免人們盡可能多地與他人重復。

可以使用for循環將第一個組合與其他組合進行比較(使用設置的交集函數"&" ):

def getsets(a, n):              # FUNCTION FOR THIS PURPOSE
    combos = list(itertools.combinations(a,n))  # GET ALL COMBINATIONS
    print(combos[0])            # PRINT FIRST COMBINATION
    for i in combos[1:]:        # FOR EACH OF REST
        if len(set(combos[0]) & set(i)) == 1:       # IF ONLY 1 ITEM COMMON WITH INITIAL
            print(i)            # PRINT IT

測試:

getsets([1,2,3,4], 3)
print("---------")
getsets([1,2,3,4,5], 3)

輸出:

(1, 2, 3)   # INITIAL SET ONLY
---------
(1, 2, 3)   # INITIAL SET
(1, 4, 5)   # ONLY '1' IS COMMON WITH FIRST SET
(2, 4, 5)   # ONLY '2' IS COMMON WITH FIRST SET
(3, 4, 5)   # ONLY '3' IS COMMON WITH FIRST SET
{1, 2, 3}   # ONLY '4' IS COMMON WITH FIRST SET

您可以使用for循環:

m = 1
combos = list(itertools.combinations(a,3))
result = []
for combo in combos:
    if result:
        if all([sum([1 for item in combo if item in tup]) == 1 for tup in result]):
            result.append(combo)
    else:
        result.append(combo)
result
#[(1, 2, 3), (1, 4, 5)]

這樣,您將能夠控制相互成員的數量並獲得所需的輸出。

看來,您得到的結果在邏輯上是這樣的:

a = range(1,6)
shared_elem_count = 1
group_count = 3

combinations = itertools.combinations(a, group_count)
results = []

for combination in combinations:
    res_union = set().union(*results)
    intersection = set(combination).intersection(res_union)
    if len(intersection) <= shared_elem_count:
        results.append(combination)

就像在您的示例中一樣,元組與其他任何可用元素之間共享的共有m個以上。 但是正如評論中指出的那樣,該解決方案嚴格遵循操作順序。 第一個元組確定可接受的下一個元組。

請注意,您在評論中說的是一個更廣泛的問題:將n個人歸為不超過m共同點的k群體將提供比我們沒有的解決方案多得多的解決方案過濾掉”。 例如,您已經指出,對於m = 1a = (1,2,3,4,5)解決方案是:

(1,2,3),(1,4,5)

...但是實際上還有更多解決方案,例如:

(2,3,4),(1,2,5)
(3,4,5),(1,2,3)
(1,4,5),(2,3,4)

因此,我不能完全確定過濾組合是否是解決問題的正確方法(不過,尚不清楚您實際上想實現什么目標,所以知道)。

暫無
暫無

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

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