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

2024-09-25 08:32:20 发布

您现在位置: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],则结果不正确

提前感谢您抽出时间


Tags: theinforgetifcounterresultcollections
1条回答
网友
1楼 · 发布于 2024-09-25 08:32:20
# 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]]]

相关问题 更多 >