生成一个随机的二进制数与“1”比特的可变比例 [英] Generate a random binary number with a variable proportion of '1' bits

查看:246
本文介绍了生成一个随机的二进制数与“1”比特的可变比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个函数来生成随机整数。 (假设Java的键入现在,但是这将扩展到的BigInteger 位集合后)。

最棘手的部分是有一个参数P,它指定结果是1的任意位的(独立的)可能性。

如果P = 0.5,那么我们就可以使用标准的随机数发生器。的P一些其它值也容易实现。下面是一个不完整的例子:

 随机随机=新的随机();// ...长nextLong(浮点P){
    如果(P = = 0.0)返回0L;
    否则,如果(P == 1.0F)返回-1L;
    否则,如果(P == 0.5F)返回random.nextLong();
    否则如果(第== 0.25f)返回nextLong(0.5F)及nextLong(0.5F);
    否则,如果(P == 0.75f​​)返回nextLong(0.5F)| nextLong(0.5F);
    否则如果(第== 0.375f)返回nextLong(0.5F)及nextLong(0.75f​​); //等
    其他{
      //善有善报这里?
      字符串消息=的String.format(P =%F尚未实现!,P);
      抛出新抛出:IllegalArgumentException(信息);
    }
}

有没有办法来概括本作的P 0.0和1.0之间的任意值?


解决方案

下面是我如何解决它到底。


  1. 生成一个整数n 0..16之间,继二项分布。这给出了1的位中的16位部分结果的数目。

  2. 随机生成索引到包含含有的1比特的期望数量的16位整数的查找表。

  3. 重复4次得到4个16位整数。

  4. 通联这四个16位整数合力得到一个64位整数。

这部分是由Ondra可以参观Žižka的回答启发。

的好处是,它减少了呼叫的数量来 Random.nextLong()来每输出的64比特8的呼叫。
为了进行比较,滚动每个单独的位将需要64调用。按位和/或使用电话2和32之间根据 P

的价值

当然计算二项式概率是一样昂贵,因此在另一查找表的走了。

这是一个很大code,但它的回报在性能方面。


更新 - 合并这与按位AND / OR解决方案。它现在使用该方法,如果它猜它会更有效率(在通话方面 Random.next()

I need a function to generate random integers. (assume Java long type for now, but this will be extended to BigInteger or BitSet later.)

The tricky part is there is a parameter P that specifies the (independent) probability of any bit in the result being 1.

If P = 0.5 then we can just use the standard random number generator. Some other values of P are also easy to implement. Here's an incomplete example:

Random random = new Random();

// ...

long nextLong(float p) {
    if      (p == 0.0f)   return 0L;
    else if (p == 1.0f)   return -1L;
    else if (p == 0.5f)   return random.nextLong();
    else if (p == 0.25f)  return nextLong(0.5f) & nextLong(0.5f);
    else if (p == 0.75f)  return nextLong(0.5f) | nextLong(0.5f);
    else if (p == 0.375f) return nextLong(0.5f) & nextLong(0.75f); // etc
    else {
      // What goes here??
      String message = String.format("P=%f not implemented yet!", p);
      throw new IllegalArgumentException(message);
    }
}

Is there a way to generalise this for any value of P between 0.0 and 1.0?

解决方案

Here's how I solved it in the end.

  1. Generate an integer N between 0..16, following the binomial distribution. This gives the number of '1' bits in the 16-bit partial result.
  2. Randomly generate an index into a lookup table that contains 16-bit integers containing the desired number of '1' bits.
  3. Repeat 4 times to get four 16-bit integers.
  4. Splice these four 16-bit integers together to get a 64-bit integer.

This was partly inspired by Ondra Žižka's answer.

The benefit is that it reduces the number of calls to Random.nextLong() to 8 calls per 64 bits of output. For comparison, rolling for each individual bit would require 64 calls. Bitwise AND/OR uses between 2 and 32 calls depending on the value of P

Of course calculating binomial probabilities is just as expensive, so those go in another lookup table.

It's a lot of code, but it's paying off in terms of performance.


Update - merged this with the bitwise AND/OR solution. It now uses that method if it guesses it will be more efficient (in terms of calls to Random.next().)

这篇关于生成一个随机的二进制数与“1”比特的可变比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆