输出可序列化的排序整数

时间:2017-06-10 00:58:19

标签: c++ c++11 random

我想按排序顺序生成一个随机选择的正整数的序列化列表,但是在给定的用例中,所需的整数数量和它可以选择的数字范围很容易达到数百万(或者有时甚至每个都在数十亿的范围内,如果正在使用64位整数),所以将数字存储到数组中然后可以由软件随机访问是不可行的。

因此,我想通过一个看起来像这样的简单循环来生成数字:

unsigned current = 0;
while(remaining>0) {
    if (find_next_to_output(current,max,remaining)) {
        // do stuff having output a value        
    }
}

其中remaining初始化为我打算输出的多个随机数,max是可能生成的数字的上限(加1)。可以假设remaining将始终初始化为小于或等于max的数字。

find_next_to_output函数看起来类似于:

/**
 * advance through the range of accepted values until all values have been output
 * @param current [in/out] integer to examine.   Advances to the next integer
 *   to consider for output
 * @param max one more than the largest integer to ever output
 * @param remaining [in/out] number of integers left to output.  
 * @return true if the function ouputted an integer, false otherwise
 */
bool find_next_to_output(unsigned &current, unsigned max, unsigned &remaining)
{
    bool result = false;
    if (remaining == 0) {
        return false;
    } if (rnd() * (max - current) < remaining) {
        // code to output 'current' goes here.
        remaining--;
        result = true;
    } 
    int x = ?;  // WHAT GOES HERE?
    current += x;
    return result;
}

注意,上面使用的函数rnd()将在[0..1]范围内返回一个随机生成的统一浮点数。

正如评论所强调的那样,我不确定如何计算x的合理值,以便函数跳过的current值的数量反映了没有一个被跳过的值会被选中(同时仍留下足够的数字,仍然可以选择所有剩余的数字)。我知道它需要是一个随机数(可能不是来自均匀分布),但我不知道如何为它计算一个好的值。在最坏的情况下,它每次只会增加current,但是当剩余输出的整数与剩余范围内的整数之间存在足够的差异时,这在统计上应该是不可能的。

我不想使用任何第三方库,例如boost,尽管我可以使用任何可能打包在C ++ 11标准库中的随机数生成器。

如果我的问题的任何部分不清楚,请在下面评论,我会尽力澄清。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您希望生成随机的升序数字。您正尝试通过创建随机大小的步骤来添加到上一个数字。

您担心的是,如果步骤太大,那么您将溢出并回绕,从而打破上升的要求。

x需要以防止溢出的方式进行约束,同时仍满足随机要求。

您需要modulo运算符(模数)。 %

const unsigned step = (max - current) / remaining;

x = unsigned(rnd() * max) % step;  // will never be larger than step