【问题标题】:Is there a better algorithm to assign numbers to combinations?有没有更好的算法来为组合分配数字?
【发布时间】:2016-11-30 12:57:37
【问题描述】:

众所周知,帕斯卡的恒等式可用于将 n 中的 k 个元素的组合编码为一个从 0 到 (n \choose k) - 1 的数字(我们称之为使用combinatorial number system 编号组合索引)。假设算术运算的时间恒定,该算法需要 O(n) 时间。

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


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

【问题讨论】:

  • 您是否必须将其专门映射到介于 0 和 (n \choose k) - 1 之间的“密集”范围内的数字?如果你能把它放宽到一个更稀疏的范围,就很容易想出 w(n) 的东西。
  • @AmiTavory 为了我的目的,地图必须密集。
  • 预处理呢?如果可以,时间/空间限制是多少?
  • @AmiTavory 输入是一个数字 k 和一个(可选排序的)k 个从 0 到 n 的不同数字的数组i> 减号; 1. 您可以使用合理大小的预计算表(例如,O(n),但不要觉得受此限制)以及您喜欢的空间大小。
  • @AmiTavory 好吧,您可以使用预先计算的系数查找表。

标签: algorithm language-agnostic combinations combinatorics


【解决方案1】:

评论的描述。

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

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

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 &lt;&lt; k,那么找到一个数字是 O(k)。

【讨论】:

    猜你喜欢
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 2012-06-02
    • 2021-11-23
    • 1970-01-01
    相关资源
    最近更新 更多