使用n 1&#39生成随机BitSet

时间:2012-10-10 11:10:52

标签: java random bitset

  

可能重复:
  Randomly pick k bits out of n from a Java BitSet

是否有一种简单的方法可以生成随机顺序大小为n * n(例如64)和n(e.q 8)数为1的随机BitSet?

我曾经想过的是,我可能会生成一个随机的bitset,并检查bitSet.cardinality()是否为8,如果没有则再次尝试,但这似乎是一个性能不佳的解决方案。

任何人都有更好的主意吗?

4 个答案:

答案 0 :(得分:4)

使用reservoir sampling,可以在O(N)时间内完成:

public static BitSet randomBitSet(int size, int cardinality, Random rnd) {
    if (0 > cardinality || cardinality > size) throw new IllegalArgumentException();
    BitSet result = new BitSet(size);
    int[] chosen = new int[cardinality];
    int i;
    for (i = 0; i < cardinality; ++ i) {
        chosen[i] = i;
        result.set(i);
    }
    for (; i < size; ++ i) {
        int j = rnd.nextInt(i+1);
        if (j < cardinality) {
            result.clear(chosen[j]);
            result.set(i);
            chosen[j] = i;
        }
    }
    return result;
}

答案 1 :(得分:3)

获取0到63之间的8个不同的随机数。将这些位设置为1。

你的方法并不能确保8个1,每个64位的平均值为8 1(如果重复的次数足够多)。

答案 2 :(得分:1)

创建您要选择的数字列表,例如从0到63。

随机播放列表。

将第一个n位设置为1,例如第8个。

这将具有O(n ^ 2)时间复杂度。


另一种方法是创建一个BitSet并保持设置随机清零位,直到总共设置为8。你不需要测试基数。

int n = ...
Random rand = new Random();
BitSet bs = new BitSet(n * n);
for(int i = 0; i < n; i++) {
   int j = rand.nextInt(n * n);
   if (bs.get(j)) 
       i--;
   else
       bs.set(j);
}

这通常略差于O(n)

答案 3 :(得分:1)

  1. 设置一个字符数组:{1 1 1 1 1 1 1 0 0 ... 0 0 0},正确的数字为1和0。

  2. 使用Fisher-Yates算法对字符数组进行随机随机播放。

  3. 将混洗数组转换为BitSet。无论何处出现'1'字符,都将相应位设置为0b1。所有其他位可以设置为0b0。

  4. ETA:考虑一下,你可以直接创建和改组BitSet。基础算法仍然是相同的。