Algorithm 递归地将一组n个对象的所有分区划分为k个非空子集
我想把n个元素的所有分区都划分成k个子集,这是我基于递归公式的算法Algorithm 递归地将一组n个对象的所有分区划分为k个非空子集,algorithm,kotlin,np-hard,Algorithm,Kotlin,Np Hard,我想把n个元素的所有分区都划分成k个子集,这是我基于递归公式的算法 fun main(args:Array){ val s=可变集合(1,2,3,4,5) val分区=3 val res=mutableSetOf() 分区(s、分区、res) //println(res) println(“第二类斯特林数${res.size}”) } 有趣的分区(inputSet:MutableSet,numOfPartitions:Int,result:MutableSet){ if(inputSet.siz
fun main(args:Array){
val s=可变集合(1,2,3,4,5)
val分区=3
val res=mutableSetOf()
分区(s、分区、res)
//println(res)
println(“第二类斯特林数${res.size}”)
}
有趣的分区(inputSet:MutableSet,numOfPartitions:Int,result:MutableSet){
if(inputSet.size==numOfPartitions){
val sets=inputSet.map{mutableSetOf(it)}.toMutableSet()
结果。添加(组)
}
else if(numOfPartitions==1){
结果.添加(可变集合(输入集合))
}
否则{
val popped:Int=inputSet.first()。还有{inputSet.remove(it)}
val r1=mutableSetOf()
分区(inputSet,numOfPartitions,r1)//将弹出的添加到解决方案中的每个集合(所有组合)
用于(r1中的溶液){
用于(在解决方案中设置){
set.add(弹出)
result.add(solution.map{it.toMutableSet()}.toMutableSet())//深度复制
设置。移除(弹出)
}
}
val r2=mutableSetOf()
分区(inputSet,numOfPartitions-1,r2)//弹出的是单个元素集
r2.map{it.add(mutableSetOf(popped))}
r2.map{result.add(it)}
}
}
代码在k=2时运行良好,但对于较大的n和k,它会丢失一些分区,我在这里找不到错误。
示例:n=5和k=3输出
<代码>第二类斯特灵第19号<代码>正确的输出将是25。< /P> < P>如果您能读取Python代码,请考虑下一个算法,这是我快速实现的,从实现集合划分到大小相等的部分。 递归函数用N个值填充K个部分
lastfilled
参数有助于避免重复-它提供了每个零件前导(最小)元素的递增顺序
empty
参数用于避免空零件
def genp(部件:列表、空、n、k、m、最后填充):
如果m==n:
印刷品(部分)
全球c
c+=1
返回
如果n-m==空:
开始=k-空
其他:
开始=0
对于范围内的i(开始,最小(k,最后填充+2)):
第[i]部分。追加(m)
如果len(部分[i])==1:
空-=1
genp(零件,空,n,k,m+1,最大值(i,最后填充))
第[i].pop()部分
如果len(部分[i])==0:
空+=1
def设置部分(n,k):
范围(k)内的零件=[]
碳纳米管=[0]*k
genp(部分,k,n,k,0,-1)
c=0
设置部分(5,3)
#设置部分(7,5)
印刷品(c)
[[0, 1, 2], [3], [4]]
[[0, 1, 3], [2], [4]]
[[0, 1], [2, 3], [4]]
[[0, 1, 4], [2], [3]]
[[0, 1], [2, 4], [3]]
[[0, 1], [2], [3, 4]]
[[0, 2, 3], [1], [4]]
[[0, 2], [1, 3], [4]]
[[0, 2, 4], [1], [3]]
[[0, 2], [1, 4], [3]]
[[0, 2], [1], [3, 4]]
[[0, 3], [1, 2], [4]]
[[0], [1, 2, 3], [4]]
[[0, 4], [1, 2], [3]]
[[0], [1, 2, 4], [3]]
[[0], [1, 2], [3, 4]]
[[0, 3, 4], [1], [2]]
[[0, 3], [1, 4], [2]]
[[0, 3], [1], [2, 4]]
[[0, 4], [1, 3], [2]]
[[0], [1, 3, 4], [2]]
[[0], [1, 3], [2, 4]]
[[0, 4], [1], [2, 3]]
[[0], [1, 4], [2, 3]]
[[0], [1], [2, 3, 4]]
25
不确定,代码中的确切问题是什么,但以递归方式查找所有斯特林秒数要简单得多:
private val memo=hashMapOf()
有趣的斯特林2(n:Int,k:Int):大整数{
val key=n到k
返回备忘。getOrPut(键){
什么时候{
k==0 | | k>n->BigInteger.ZERO
n==k->biginger.ONE
else->k.Tobiginger()*stirling2(n-1,k)+stirling2(n-1,k-1)
}
}
}
我改进了Kornel_的代码。
有一个func,它列出了所有可能的组合。小心大数字:)
例如:
# EXAMPLE
print('\n'.join([f"{x}" for x in Stirling2Iterate(['A', 'B', 'X', 'Z'])]))
# OUTPUT
[['A', 'B', 'X', 'Z']]
[['A', 'B', 'X'], ['Z']]
[['A', 'B', 'Z'], ['X']]
[['A', 'B'], ['X', 'Z']]
[['A', 'X', 'Z'], ['B']]
[['A', 'X'], ['B', 'Z']]
[['A', 'Z'], ['B', 'X']]
[['A'], ['B', 'X', 'Z']]
[['A', 'B'], ['X'], ['Z']]
[['A', 'X'], ['B'], ['Z']]
[['A'], ['B', 'X'], ['Z']]
[['A', 'Z'], ['B'], ['X']]
[['A'], ['B', 'Z'], ['X']]
[['A'], ['B'], ['X', 'Z']]
[['A'], ['B'], ['X'], ['Z']]
# EXAMPLE
print('\n'.join([f"{x}" for x in Stirling2Iterate(['A', 'B', 'X', 'Z'])]))
# OUTPUT
[['A', 'B', 'X', 'Z']]
[['A', 'B', 'X'], ['Z']]
[['A', 'B', 'Z'], ['X']]
[['A', 'B'], ['X', 'Z']]
[['A', 'X', 'Z'], ['B']]
[['A', 'X'], ['B', 'Z']]
[['A', 'Z'], ['B', 'X']]
[['A'], ['B', 'X', 'Z']]
[['A', 'B'], ['X'], ['Z']]
[['A', 'X'], ['B'], ['Z']]
[['A'], ['B', 'X'], ['Z']]
[['A', 'Z'], ['B'], ['X']]
[['A'], ['B', 'Z'], ['X']]
[['A'], ['B'], ['X', 'Z']]
[['A'], ['B'], ['X'], ['Z']]