![](/img/trans.png)
[英]How to get all the combinations of a list of pairs with a restriction on indices
[英]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 = 1
和a = (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.