c++ - 生成具有差异约束的随机整数

标签 c++ algorithm random constraints unique

我有以下问题:

从 0-N 范围内生成 M 个均匀随机整数,其中 N >> M,并且没有对的差值小于 K。其中 M >> K

目前我能想到的最好的方法是维护一个排序列表,然后确定当前生成的整数的下界并用下界和上界元素进行测试,如果可以则在两者之间插入元素.这是复杂度 O(nlogn)。

会不会有更高效的算法?

问题示例:

生成1000个0到1亿之间的均匀随机整数,其中任意两个整数之差不小于1000

解决此问题的综合方法是:

  1. 确定满足约束条件的n-choose-m的所有组合,称其为集合X
  2. 选择[0,|X|]范围内的均匀随机整数i。
  3. 从 X 中选择第 i 个组合作为结果。

当 n-choose-m 很大时,此解决方案是有问题的,因为枚举和存储所有可能的组合将非常昂贵。因此寻求一种高效的在线生成解决方案。

注意:下面是pentadecagon提供的方案的C++实现

std::vector<int> generate_random(const int n, const int m, const int k)
{
   if ((n < m) || (m < k))
      return std::vector<int>();

   std::random_device source;
   std::mt19937 generator(source());
   std::uniform_int_distribution<> distribution(0, n - (m - 1) * k);

   std::vector<int> result_list;
   result_list.reserve(m);

   for (int i = 0; i < m; ++i)
   {
      result_list.push_back(distribution(generator));
   }

   std::sort(std::begin(result_list),std::end(result_list));

   for (int i = 0; i < m; ++i)
   {
      result_list[i] += (i * k);
   }

   return result_list;
}

http://ideone.com/KOeR4R

.

最佳答案

编辑:我根据创建有序序列的要求调整了文本,每个序列的概率都相同。

i=0..M-1 创建没有重复的随机数 a_i。对它们进行排序。然后创建数字

b_i=a_i + i*(K-1)

鉴于结构,这些数字 b_i 具有所需的间隙,因为 a_i 已经具有至少 1 的间隙。为了确保这些 b 值完全覆盖所需的范围 [1..N],您必须确保 a_i 是从范围中挑选的[1..N-(M-1)*(K-1)]。这样你就可以获得真正独立的数字。好吧,考虑到所需的差距,尽可能独立。由于排序,您再次获得 O(M log M) 性能,但这应该不会太糟糕。排序通常非常快。在 Python 中它看起来像这样:

import random
def random_list( N, M, K ):
    s = set()
    while len(s) < M:
        s.add( random.randint( 1, N-(M-1)*(K-1) ) )

    res = sorted( s )

    for i in range(M):
        res[i] += i * (K-1)

    return res

关于c++ - 生成具有差异约束的随机整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21980418/

相关文章:

c++ - X* x =dynamic_cast<Y*> 是什么意思?

python - 体面的数字 |帮助降低时间复杂度

java - 生成随机日期

c++ - 使用信号量的单 channel 桥同步

c++ - 使用 emscripten 编译结构时出错

c++ - 一个类的方法覆盖另一个类的所有方法

algorithm - 《地下城守护者 2》风格 map ,顶点压缩

r - 将转录矩阵转换为基因矩阵的任何智能解决方案?

swift - 根据用户数 "likes"根据分布随机找一个用户

random - 随机选择一组推特用户的好方法是什么?