繁体   English   中英

如何获取元素列表的所有不相交子集,如果将其连接在一起,则与 python 中的初始列表相同?

[英]How can I get all the disjoint subsets of a list of elements, and if join together it is same as the initial list in python?

假设,一个集合[0,1,2]我怎样才能得到所有集合列表,如果它们连接在一起,结果 = [0,1,2]那些子集可能是,

[[0],[1],[2]]

[[0,1],[2]]

[[0],[1,2]]

[[1],[0,2]]

[[0,1,2]]

这是我试过的 python 代码,

import collections

def get_subsets(fullset):
    listrep = list(fullset)
    n = len(listrep)
    return [[listrep[k] for k in range(n) if i&1<<k] for i in range(2**n)]


P_Set=list(df_distance.columns)
P_Set.pop(P_Set[-1])
powerSet=get_subsets(P_Set)
powerSet=get_subsets([0,1,2,3,4])


# Finding the disjoint subset that union make fullset
def common_data(list1, list2): 
    result = False
    # traverse in the 1st list 
    for x in list1: 
        # traverse in the 2nd list 
        for y in list2: 
            # if one common 
            if x == y: 
                result = True
                return result                   
    return result

# Delete the empty list from the power list
powerSet = [x for x in powerSet if x]

# Finding the subsets
disjointSubsetList=[]
# initialSet=P_Set
initialSet=[0,1,2,3,4]
coalitionSet=[]

for i in powerSet:
    coalitionSet=[]
    coalitionSet.append(i)
    for j in powerSet:
        if collections.Counter(i) != collections.Counter(j):
            if not common_data(i,j):
                coalitionSet.append(j)
            if collections.Counter(list(itertools.chain.from_iterable(coalitionSet))) == collections.Counter(initialSet):
                disjointSubsetList.append(coalitionSet)
                coalitionSet=[]

列表 [0,1,2] 的结果很好,但如果它的 [0,1,2,3,4] 则结果不正确。

在此先感谢您的时间。

# https://github.com/0xF4D3C0D3/snippets/blob/master/algorithm/partition.py

import itertools


def partition(list_, k):
    """
    partition([1, 2, 3, 4], 2) -> [[1], [2, 3, 4]], [[1, 2], [3, 4]], ..., [[1, 3], [2, 4]], [[3], [1, 2, 4]]
    """
    if k == 1:  # base case 1: k == 1, just yield itself as a list
        yield [list_]
    elif k == len(list_):  # base case 2: k == len(list_), yield each item in the list wrapped in a list
        yield [[s] for s in list_]
    else:
        head, *tail = list_  # head = the first element, tail = the rest
        for p in partition(tail, k-1):  # case 1: head -> 1, partition(tail, k-1) -> k-1.
                                        # head + partition(tail, k-1) -> 1+k-1 -> k
            yield [[head], *p]
        for p in partition(tail, k):  # case 2: head -> 1, partition(tail, k) -> k.
                                      # bloat x to [e1, e2, e3] -> [[x+e1, e2, e3], [e1, x+e2, e3], [e1, e2, x+e3]]
            for i in range(len(p)):
                yield p[:i] + [[head] + p[i]] + p[i+1:]  # bloat head to partition(tail, k) -> k

def get_all_disjoint_sets(iterable):
    l = list(iterable)
    return itertools.chain.from_iterable(list(partition(l, i)) for i in range(1, len(l)+1))

print('\n'.join(map(str, get_all_disjoint_sets([0, 1, 2]))))
'''
[[0, 1, 2]]
[[0], [1, 2]]
[[0, 1], [2]]
[[1], [0, 2]]
[[0], [1], [2]]
'''

list(get_all_disjoint_sets([0, 1, 2]))
# [[[0, 1, 2]], [[0], [1, 2]], [[0, 1], [2]], [[1], [0, 2]], [[0], [1], [2]]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM