有一些像这样的帖子 I have a list of numbers, how to generate all unique k-partitions?
但是我想知道是否有一些新的高效库来解决这个问题(itertools
?sagemath
?)
我有一个数字列表,如何生成所有唯一的有序k分区?
例如,如果我有[1,2,3,4,5]
和k = 3
[[1,2],[3],[4,5]]
就是这样一个分区
但是[[4,5],[3],[1,2]]
也是这样的分区
我还想将NULL集作为k子集中的可能集合包含在例如
中[[2,3],[],[1,4,5]]
之间的顺序很重要
[[1,2],[3],[4,5]]
和[[4,5],[3],[1,2]]
但是[[2,1],[3],[5,4]]被认为与[[1,2],[3],[4,5]]相同,如果你跟着我......
据我所知,来自Sagemath的OrderedSetPartitions(5,3)
将不会提供我的问题的答案,因为它排除了NULL集
编辑:这是一个(根本没有优化)尝试使用SAGEMATH天真地解决这个问题
def OrderedSetPartitions_0(A,k):
cols={i for i in range(k)}
# returns the list of k-OrderedSetPartitions of A, allowing for the empty set
s=Subsets(cols).list()
res=[]
count=0
P=[OrderedSetPartitions(A,i) for i in range(k+1)]
for sub in s:
print("sub=")
print(sub)
tmp=[ {} for i in range(k)]
c=sub.cardinality()
for part in P[c]:
print("part=")
print(part)
for i in range(c):
tmp[sub[i]]=part[i]
print("tmp=")
print(tmp)
res=res.append([tmp])
# res = res.append(tmp) # tried this too
print("res=")
print(res)
count=count+1
return(res)
# print(count)
A=range(3)
k=2
A
P=[OrderedSetPartitions(A,i) for i in range(k+1)]
# note that P[2].list is a list of list !
P[2].list()
[[{0, 1}, {2}], [{0, 2}, {1}], [{1, 2}, {0}], [{0}, {1, 2}], [{1}, {0, 2}], [{2}, {0, 1}]]
myset=OrderedSetPartitions_0(A,k)
我收到此错误消息,我承认我根本没有得到它,因为它在编码时看起来很好, 但不知何故res似乎是“无”而不是[]
sub= {} sub= {0} part= [{0, 1, 2}] tmp= [{0, 1, 2}, {}] res= None sub= {1} part= [{0, 1, 2}] tmp= [{}, {0, 1, 2}] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "_sage_input_21.py", line 10, in <module> exec compile(u'open("___code___.py","w").write("#
- - 编码:utf-8 - - \ n“+ 支持 .preparse_worksheet_cell(base64.b64decode(”bXlzZXQ9T3JkZXJlZFNldFBhcnRpdGlvbnNfMChBLGsp“),globals())+”\ N“); 的execfile(os.path.abspath则( “ 码 的.py”))
中的文件“”,第1行File "/private/var/folders/gm/z065gk616xg6g0xgn4c7_bvc0000gn/T/tmpryfYOj/___code___.py", line 2, in <module> exec compile(u'myset=OrderedSetPartitions_0(A,k) File "", line 1, in <module> File "/private/var/folders/gm/z065gk616xg6g0xgn4c7_bvc0000gn/T/tmpSH_9LF/___code___.py", line 27, in OrderedSetPartitions_0 res=res.append([tmp]) AttributeError: 'NoneType' object has no attribute 'append'
问题在于将列表聚合到res中。如果我对涉及res的所有行都设置了一个锐利,我可以正确枚举输出
编辑: 谢谢你的回答
实际上我将res=res.append(tmp)
更改为res.append(tmp)
我在执行print(tmp)
[{0, 1, 2}, {}, {}] [{}, {0, 1, 2}, {}] [{}, {}, {0, 1, 2}] [{0, 1}, {2}, {}] [{0, 2}, {1}, {}] [{1, 2}, {0}, {}] [{0}, {1, 2}, {}] [{1}, {0, 2}, {}] [{2}, {0, 1}, {}] [{0, 1}, {}, {2}] [{0, 2}, {}, {1}] [{1, 2}, {}, {0}] [{0}, {}, {1, 2}] [{1}, {}, {0, 2}] [{2}, {}, {0, 1}] [{}, {0, 1}, {2}] [{}, {0, 2}, {1}] [{}, {1, 2}, {0}] [{}, {0}, {1, 2}] [{}, {1}, {0, 2}] [{}, {2}, {0, 1}] [{0}, {1}, {2}] [{0}, {2}, {1}] [{1}, {0}, {2}] [{2}, {0}, {1}] [{1}, {2}, {0}] [{2}, {1}, {0}]
但奇怪的是res是错误的,必须有一些副作用
[[{0, 1, 2}, {}, {}],
[{}, {0, 1, 2}, {}],
[{}, {}, {0, 1, 2}],
[{2}, {0, 1}, {}],
[{2}, {0, 1}, {}],
[{2}, {0, 1}, {}],
[{2}, {0, 1}, {}],
[{2}, {0, 1}, {}],
[{2}, {0, 1}, {}],
[{2}, {}, {0, 1}],
[{2}, {}, {0, 1}],
[{2}, {}, {0, 1}],
[{2}, {}, {0, 1}],
[{2}, {}, {0, 1}],
[{2}, {}, {0, 1}],
[{}, {2}, {0, 1}],
[{}, {2}, {0, 1}],
[{}, {2}, {0, 1}],
[{}, {2}, {0, 1}],
[{}, {2}, {0, 1}],
[{}, {2}, {0, 1}],
[{2}, {1}, {0}],
[{2}, {1}, {0}],
[{2}, {1}, {0}],
[{2}, {1}, {0}],
[{2}, {1}, {0}],
[{2}, {1}, {0}]]
前3行是正确的,然后它开始与print(tmp)
得到的分歧。这对我很陌生,因为print(tmp)
和res.append(tmp)
之间没有说明!!!!!
答案 0 :(得分:2)
这是Sagemath中使用NumPy数组和itertools的解决方案。这个想法和你的代码一样:创建OrderedSetPartitions并用空集加强它们。为了在没有太多循环的情况下执行此操作,使用NumPy数组:关键部分是partitions[:, s] = P
,其中最初用空集填充的2D数组partitions
的某些列被来自OrderedSetPartitions的非空集替换。
import numpy as np
from itertools import combinations
A = Set([1, 2, 3, 4, 5]) # Sage set, not Python set
k = 3 # number of elements in partition
all_partitions = np.array(OrderedSetPartitions(A, k).list())
for i in range(k-1, 0, -1):
P = np.array(OrderedSetPartitions(A, i).list()) if i > 1 else [[A]]
for s in combinations(range(k), i):
partitions = np.empty((len(P), k), dtype=object)
partitions[:, :] = [[Set()]]
partitions[:, s] = P
all_partitions = np.vstack((all_partitions, partitions))
print all_partitions
输出是一个双NumPy数组。如果需要Python列表,您可以返回all_partitions.tolist()
。
Sage集(使用Set([1,2,3])
创建)和Python集(使用set([1,2,3])
或{1,2,3,4,5}
创建)是不同类的对象。在Sagemath中,Sage集的输出看起来更好:它们显示为{1,2,3},而Python集显示为set([1,2,3])
。出于这个原因,Sage套装在Sagemath中是首选。此外,OrderedSetPartitions返回Sage集。
但让NumPy与Sage集合一起玩需要更多的努力:特别是,我无法让np.full
接受空Sage集Set()
作为填充对象。这就是使用np.empty
然后将其填入的原因。
类似的问题导致案件i == 1
被区别对待:NumPy尝试将[[Set([1,2,3,4,5])]]
转换为三维数字数组,而不是包含一个Sage设置对象的二维数组。