返回很大范围内的非重复随机值

2024-02-20

我想要一个函数,它可以从一组 n 个整数(0 到 n-1)中生成 k 个伪随机值,而不重复任何先前的结果。 k小于或等于n。O(n) 内存不可接受由于尺寸较大n以及我需要重新洗牌的频率。

这些是我到目前为止考虑过的方法:

Array: 通常,如果我想要无重复的随机值,我会打乱数组,但这是 O(n) 内存。 n 可能太大而无法正常工作。

long nextvalue(void) {
  static long array[4000000000];
  static int s = 0;
  if (s == 0) {
    for (int i = 0; i < 4000000000; i++) array[i] = i;
    shuffle(array, 4000000000);
  }
  return array[s++];
}

n态PRNG: 有多种随机数生成器,可以将其设计为具有以下周期:n并参观n那个时期的独特状态。最简单的例子是:

long nextvalue(void) {
static long s = 0;
static const long i = 1009; // assumed co-prime to n
  s = (s + i) % n;
  return s;
}

这样做的问题是,对于给定的情况,动态设计一个好的 PRNG 并不一定容易。n,如果 PRNG 没有很多可变参数(甚至更难设计),它就不太可能近似公平的洗牌。但也许有一个我不知道的好东西。

m位哈希: 如果集合的大小是 2 的幂,那么就有可能设计出完美的哈希函数f()它执行从范围内的任何值到范围内的某个其他值的 1:1 映射,其中每个输入都会产生唯一的输出。使用这个函数我可以简单地维护一个静态计数器s,并将生成器实现为:

long nextvalue(void) {
  static long s = 0;
  return f(s++);
}

这并不理想,因为结果的顺序由以下因素决定f(),而不是随机值,因此它会遇到与上述相同的问题。

NPOT 哈希: 原则上我可以使用与上面相同的设计原则来定义一个版本f()它可以在任意基础上工作,甚至可以在与所需范围兼容的复合基础上工作;但这可能很困难,而且我很可能会出错。相反,可以为大于或等于的下一个二的幂定义一个函数n,并在此结构中使用:

long nextvalue(void) {
  static long s = 0;
  long x = s++;
  do { x = f(x); } while (x >= n);
}

但是这个still有同样的问题(不太可能给出公平洗牌的良好近似值)。

有没有更好的方法来处理这种情况?或者也许我只需要一个好的功能f()高度参数化且易于设计以准确访问n离散状态。

我正在考虑的一件事是类似哈希的操作,我设法获得第一个j通过精心设计的映射,结果完全随机,然后之间的任何结果j and k会简单地推断该模式(尽管以可预测的方式)。价值j然后可以选择在公平洗牌和可容忍的内存占用之间找到折衷方案。


首先,对任何使用 O(n) 内存的东西打折扣,然后讨论引用底层数组的解决方案似乎是不合理的。你有一个数组。洗牌。如果这不起作用或不够快,请向我们提出相关问题。

您只需执行一次完整的随机播放。之后,从索引中提取n,将该元素与随机位于其之前的元素交换并增加n,模元素计数。例如,对于如此大的数据集,我会使用像这样的东西 https://gist.github.com/Sebbyastian/40be860d95f9df95f319a2f17dc74dde.

质数是哈希的一种选择,但可能与您想象的不同。使用两个梅森素数 (low and high, 也许0xefff and 0xefffffff)你应该能够想出一个更通用的哈希算法。

size_t hash(unsigned char *value, size_t value_size, size_t low, size_t high) {
    size_t x = 0;
    while (value_size--) {
        x += *value++;
        x *= low;
    }
    return x % high;
}
#define hash(value, value_size, low, high) (hash((void *) value, value_size, low, high))

例如,对于大于大约两个八位位组的所有输入,这应该产生相当好的分布,但零字节前缀有一个小麻烦的例外。您可能想以不同的方式对待它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

返回很大范围内的非重复随机值 的相关文章

  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • C++11 函数局部静态 const 对象的线程安全初始化

    这个问题已在 C 98 上下文中提出 并在该上下文中得到回答 但没有明确说明有关 C 11 的内容 const some type create const thingy lock my lock some mutex static con
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • std::bind 重载解析

    下面的代码工作正常 include
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 如何从 CouchDB 加载随机文档(高效且公平)?

    我想从存储在 CouchDB 数据库中的一组文档中加载随机文档 单据的取放方式应符合下列要求 效率 文档的查找应该高效 最重要的是加载文档的时间不能随文档总数线性增长 这意味着skip无法使用查询参数 均匀分布 选择应该是真正随机的 尽可能
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens

随机推荐