使用 Gosper 的 Hack(银行家序列)生成所有子集

Generating all subsets using Gosper's Hack (Bankers sequence)

我有一个生成数组所有子集的方法,我想尝试实现的是同一种方法,但使用二进制来实现。 Gosper 的 Hack 似乎是最好的主意,但我不知道如何实施它。下面的代码用于生成所有 subsets.The 子集可以是未知的 (http://imgur.com/KXflVjq) 这显示了 运行 几秒钟后的输出。感谢您的任何建议

int m = prop.length;
int list = (1 << m);
for(long i = 1; i<list; i++) {
   final List sub = new ArrayList<>();
   for(long j=0; j<m; j++) {
      if((i & (1<<j)) > 0) {      
         sub.add(j);
      }
   }
   Collections.sort(sub);
   System.out.println(sub);
}

编辑:由于我对问题的措辞不正确,我需要的输出是:

2  1  0
0  0  1 = 0 
0  1  0 = 1

等等

首先,我想指出,不清楚您要实现的目标到底是什么;请考虑澄清问题。我假设您想要生成 n 集的所有 k 子集。这个问题可以很容易地简化为生成 {1,2,...,n} 的所有 k-子集(即它足够计算所有 k-索引子集)。

一种算法,用于生成 n-set

k-子集

前段时间我写了 this implementation of a method (which I rediscovered few years ago) for generating all k-subsets of an n-set. Hope it helps. The algorithm essentially visists all binary sequences of length n containing exactly k ones in a clever way (without going through all 2^n sequences); see the accompanying note 描述算法,其中包含详细描述、伪代码和一个小的逐步示例。

我觉得时间复杂度是O(k {n choose k})量级。我还没有这方面的正式证据。 (很明显,任何算法都必须花费 Omega({n choose k}) 时间。)

C:

中的代码
#include <stdlib.h>
#include <stdio.h>

void subs(int n, int k);

int main(int argc, char **argv)
{
    if(argc != 3) return 1;
    int n, k;

    n = atoi(argv[1]); k = atoi(argv[2]);
    subs(n, k);

    return 0;
}

void subs(int n, int k)
{
    int *p = (int *)malloc(sizeof(int)*k);
    int i, j, r;

    for(i = 0; i < k; ++i) p[i] = i; // initialize our ``set'' 
    // the algorithm
    while(1)
     {  // visit the current k-subset
        for(i = 0; i < k; ++i)
            printf("%d ", p[i]+1);
        printf("\n");

        if(p[0] == n-k) break; // if this is the last k-subset, we are done 

        for(i = k-1; i >= 0 && p[i]+k-i == n; --i); // find the right element 
        r = p[i]; ++p[i]; j = 2; // exchange them 
        for(++i; i < k; ++i, ++j) p[i] = r+j; // move them 
     }
    free(p);
}

参考资料

如果这不够有效,我强烈推荐 Knuth 的 Volume 4 of The Art of Comouter Programming,他在其中广泛地处理了这个问题。它可能是最好的参考资料(而且是最近的!)。

您甚至可以找到分册草稿,TAOCP 第 4 卷分册 3,生成所有组合和分区 (2005),vi+150pp。 ISBN 0-201-85394-9,在 Knuth 的主页上(查看他 2011 年左右的新闻)。