如何从0到m(m的范围)生成均匀分布的n-置换

时间:2014-12-15 08:23:14

标签: c++ algorithm

允许重复一个数字,但概率是有限的

例如: 给出一个0-8的数字序列,我想生成一个25个数字的随机序列,一个数字的最大重复时间是3。

2 个答案:

答案 0 :(得分:-1)

据我所知,你需要这样的东西(根据下面的评论重写):

#include <stdlib.h>
#include <time.h>

#include <vector>
#include <iostream>

using std::vector;
using std::cout;

vector<int> Generate(const vector<int> & numbers, int generateN, int maxRepeatN)
{
    vector<int> longList(numbers.size() * maxRepeatN);

    for(int i = 0; i < numbers.size(); i++)
        for(int j = 0; j < maxRepeatN; j++)
            longList[i * maxRepeatN + j] = numbers[i];

    vector<int> result(generateN);

    for(int i = 0; i < generateN; i++)
    {
        int id = rand() % longList.size();
        result[i] = longList[id];
        longList.erase(longList.begin() + id);
    }

    return result;
}

int main()
{
    srand((unsigned)time(0));

    vector<int> numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8}

    vector<int> result = Generate(numbers, 25, 3);

    for(int i = 0; i < result.size(); i++)
        cout << result[i] << " ";          

    return 0;
}

算法的想法是你创建所有可能数字的长列表(它保证你不会得到超过一种类型的最大数字)。然后你从中逐个获得数字(从长列表保证分发后删除数字)。 *此代码仅供参考,std :: vector的使用根本不是最佳选择。

答案 1 :(得分:-1)

一种相对简单的方法是拒绝抽样。独立生成25个数字。如果任何数字出现超过3次,请将它们扔掉,然后再试一次。这种方法的最坏情况性能很差,但它很简单,你不必担心你不小心引入了不需要的相关性。