繁体   English   中英

有没有更好的算法来为组合分配数字?

[英]Is there a better algorithm to assign numbers to combinations?

众所周知,Pascal的身份可用于将n个中k个元素的组合编码为使用组合数系统从0到(n \\choose k) - 1 (我们称这个数字为组合索引 )的数字 假设算术运算的时间恒定,该算法需要O( n )时间。

我有一个应用,其中k « n和O( n )时间的算法是不可行的。 有一种算法来分配双射和0之间的数(n \\choose k) - 1k个元素的组合n个其运行时间为顺序O(K)或类似的? 该算法不需要计算与组合数系统相同的映射,但是,逆需要在类似的时间复杂度下可计算。


†更具体地说,从组合索引计算组合的算法在O( n )时间内运行。 如果预先计算二项式系数,则从组合中计算组合索引在O( k )时间内起作用。

评论说明。

对于给定的组合索引( N ),为了找到第k'th数字,需要找到c_k使得(c_k \\choose k) <= N并且((c_k+1) \\choose k) > N

设置P(i,k) = i!/(ik)!

P(i, k) = i * (i-1) * ... * (i-k+1)
substitute x = i - (k-1)/2
  = (x+(k-1)/2) * (x+(k-1)/2-1) * ... * (x-(k-1)/2+1) * (x-(k-1)/2)
  = (x^2 - ((k-1)/2)^2) * (x^2 - ((k-1)/2-1)^2) * ...
  = x^k - sum(((k-2i-1)/2)^2))*x^(k-2) + O(x^(k-4))
  = x^k - O(x^(k-2))
P(i, k) = (i - (k-1)/2)^k - O(i^(k-2))

从上面的不平等:

(c_k \choose k) <= N
P(c_k, k) <= N * k!
c_k ~= (N * k!)^(1/k) + (k-1)/2

我不确定O(c_k ^(k-2))部分有多大。 我想它不会影响太大。 如果它是有序的(c_k+1)/(c_k-k+1)比近似非常好。 那是因为:

((c_k+1) \choose k) = (c_k \choose k) * (c_k + 1) / (c_k - k + 1)

我会尝试算法类似于:

For given k
Precalculate k!

For given N
For i in (k, ..., 0)
  Calculate c_i with (N * i!)^(1/i) + (i-1)/2
  (*) Check is P(c_i, k) <=> N * i!
    If smaller check c_i+1
    If larger check c_i-1
    Repeat (*) until found P(c_i, i) <= N * i! < P(c_i+1, i)
  N = N - P(c_i, i)

如果近似是好的, number of steps << k ,而不是找到一位是O(k)。

暂无
暂无

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

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