索引大小为k的子集

时间:2013-11-30 02:52:18

标签: python algorithm indexing subset

有n个大小为k的{1,2,...,n}的k个子集。这些可以通过排序元素和使用词典顺序自然地排序。

是否有一种快速的方法来确定给定子集的索引,即其在大小为k的所有子集的排序列表中的索引?一种方法是通过枚举大小为k的所有子集来创建从子集到索引的字典,但这需要n选择k空间和时间。对于我的应用程序,n和k是不可能的大,但我只需要确定相对较少的子集的索引。

我在Python中编码,但我对通用算法比对任何特定实现更感兴趣。当然,如果在Python中有一种特别快速的方法可以做到这一点很棒。

动机:大小为k的{1,2,...,n}的子集与双向对​​应于具有维数n的向量空间的第k个外部幂的基础向量。我正在向量空间的外部代数中执行计算,并试图将得到的向量列表转换为稀疏矩阵来做线性代数,为此,我需要用整数而不是列表来索引向量。

2 个答案:

答案 0 :(得分:2)

s成为表示1..n。

的给定子集的排序列表

(n-s[0]) choose k个子集,其中元素的最低值大于s[0]。在以s[0]开头的子集中,(n-s[1]) choose (k-1)子集的第二个元素大于s[1],依此类推。我还没有制定证据,但以下功能应该有效:

def choose(n, k):
    ...

def index_of(sorted_subset, n):
    k = len(sorted_subset)
    subsets_after_the_input = 0
    for i, elem in enumerate(sorted_subset):
        subsets_after_the_input += choose(n-elem, k-i)
    return choose(n, k) - subsets_after_the_input - 1

答案 1 :(得分:1)

我认为你可以通过递归缩小范围来做到这一点,对吧?您知道以给定整数开头的所有子集都是相邻的,对于给定的第一个元素d,将有(n - d)选择它们(k-1)。您可以在虚拟子集列表中尽可能跳过,直到您处于以目标排序子集的第一个元素开头的子集范围内,然后递归以精确缩小范围。

EG,假设n = 20,k = 6。如果您的目标子集是{5,8,12,14,19},则以1-4开头的子集都不是有效选择。你知道从5开始的索引第一个子集将是((19选5)+(18选5)+(17选5)+(16选5))。称该索引为i0。现在你有(15个选择5个)子集,所有子集都以5开头索引,而没有以5,1-7开头的子集都很有趣。 (14选4)他们从1开始,(13选4)以2开始等。所以从5,8开始的第一组的索引将是i0 +(14选4)+(13选4)+ (12选4)+(11选4)+(10选4)+(9选4)+(8选4)。等

编写算法有点痛苦,但我认为它应该可以很好地与计算机一起工作,跟踪繁琐的细节。