如何生成从范围 0 到 m (m<n) 的均匀分布的 n 排列

how to generate evenly distributed n-permutation from range 0 to m (m<n)

本文关键字:排列 分布 范围 何生成 lt      更新时间:2023-10-16

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

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

一种相对万无一失的方法是拒绝采样。独立生成 25 个数字。如果任何数字出现超过 3 次,请将它们全部扔掉,然后重试。此方法的最坏情况性能较差,但它非常简单,您不必担心意外引入了不需要的相关性。

据我了解,您需要这样的东西(根据下面的评论进行了返工):

#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 根本不是最佳选择。