簡體   English   中英

組合嵌套集的排列

[英]combining permutations of nested sets

我有兩組集合,我需要將它們的組合的所有排列(如在union中)放到一個集合中,使得其中沒有2個集合包含重復元素(您可以假設每個父集合沒有具有重復元素的集合本身),雖然我只能刪除第二級集,而不是元素本身,例如:

[(a,b),(c),(d)] and [(a),(b,c),(e)]

會得到我:

[(a,b),(c),(d),(e)],[(a),(b,c),(d),(e)],[(a),(c),(d),(e)]

從一個父集合中的一個集合可以給我一個來自另一個父集合的集合的子集是不兼容的(即包含一個或多個公共元素),保持第二集合中的每個集合將給我一個新的集合子集,我可以從第一個中刪除等等..遞歸地運行並檢查重復是非常耗時的...

有沒有更好的方法來解決這個問題? 我可以用什么工具? (目前在python中這樣做)

PS我的意思的一個小代碼示例,再次,我不是要修復錯誤,只是要求一個更簡潔的方法:

def combine(S1, S2, incompatible_set, parent_set_pairs):

    new_S2 = None
    new_incompatible_sets = set()

    for s2 in S2:
        if incompatible_set & s2:
            new_incompatible_sets.add(s2)
            if not S2:
                S2 = S2.copy()
            new_S2.remove(s2)
    parent_set_pairs.add((S1, new_S2)) # here it should look for a new incompatible set in S1 and apply the function again..
    for new_incompatible_set in new_incompatible_sets:
        new_parent_set_pairs = combine(S2, S1, new_incompatible_set,
                                 parent_set_pairs)
        for pair1 in new_parent_set_pairs:
            for pair2 in parent_set_pairs:
                if pair1[0]|pair1[1] not in pair2[0]|pair2[1]
            parent_set_pairs.add(new_parent_set_pairs)

    return parent_set_pairs

這是一個基於itertools的方法,它采用兩個不相交的集合列表,並返回從兩個列表中繪制的所有最大的脫離集合組合,這些集合受限於組合中的集合是不相交的:

from itertools import combinations

def maxDisjoints(A,B):
    n = len(A)
    combos = set()
    for i in range(n+1):
        for partA in combinations(A,i):
            A_covered = set().union(*partA)
            filteredB = [s for s in B if A_covered & s == set()]
            B_covered = set().union(*filteredB)
            filteredA = [s for s in A if B_covered & s == set()]
            #filteredA is a superset of partA
            #freeze and record:
            combos.add(tuple(frozenset(s) for s in filteredA + filteredB))
    #unfreeze and return as list of lists of sets:       
    return [[set(f) for f in t] for t in combos]

測試它:

A = [{'a','b'},{'c'},{'d'}]
B = [{'a'},{'b','c'},{'e'}]
for p in jointPartitions(A,B):
    print(p)

輸出:

[{'c'}, {'d'}, {'a'}, {'e'}]
[{'d'}, {'a'}, {'b', 'c'}, {'e'}]
[{'b', 'a'}, {'c'}, {'d'}, {'e'}]

作為技術煩惱,設置和列表都不可清除,因此不可能維護一組集合列表以過濾冗余(因為算法不止一次地生成相同的最大組合)。 因此,我不得不將集合列表轉換為凍結集合的元組以臨時記錄它們,只是為了在最后反轉過程。

這是一種蠻力的方法。 它遍歷A所有2 ^ n個子集,以唯一可能的方式將每個子集擴展為最大組合。 如果A的大小和B的大小之間存在差異,則首先傳遞兩個列表中較短的一個(或調整代碼以便它自動執行此操作)。 這種方法對於小型集合來說是合理的,但是不能很好地擴展。 我懷疑問題本身是NP難的,所以你可以預期的效率有限(這並不是說這個算法是最優的)。

暫無
暫無

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

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