从链表中有效地选择一组随机元素

2023-11-22

假设我有一个长度为数字的链表N. N非常大,我事先不知道确切的值N.

我怎样才能最有效地编写一个将返回的函数k完全地随机数从列表中?


有一个非常好的且有效的算法,使用称为水库取样.

让我首先给你它history:

Knuth在 p 上调用该算法 R。他的 1997 年版《半数值算法》(《计算机编程艺术》第 2 卷)第 144 节,并在那里提供了一些代码。高德纳 (Knuth) 将算法归功于艾伦·G·沃特曼 (Alan G. Waterman)。尽管进行了长时间的搜索,我仍然无法找到 Waterman 的原始文档(如果存在),这可能就是为什么您最常看到 Knuth 被引用为该算法的来源。

麦克劳德和贝尔豪斯,1983(1) 提供了比 Knuth 更彻底的讨论以及该算法有效的第一个发布的证明(据我所知)。

维特 1985(2) 回顾算法 R,然后提出另外三种算法,它们提供相同的输出,但有所不同。他的算法不是选择包含或跳过每个传入元素,而是预先确定要跳过的传入元素的数量。在他的测试中(诚然,现在已经过时了),通过避免随机数生成和对每个传入数字的比较,大大减少了执行时间。

In 伪代码算法是:

Let R be the result array of size s
Let I be an input queue

> Fill the reservoir array
for j in the range [1,s]:
  R[j]=I.pop()

elements_seen=s
while I is not empty:
  elements_seen+=1
  j=random(1,elements_seen)       > This is inclusive
  if j<=s:
    R[j]=I.pop()
  else:
    I.pop()

请注意,我专门编写了代码以避免指定输入的大小。这是该算法的一个很酷的特性:您可以运行它而无需事先知道输入的大小still向您保证您遇到的每个元素都有相同的概率最终出现R(即没有偏见)。此外,R包含算法始终考虑的元素的公平且具有代表性的样本。这意味着您可以将其用作在线算法.

为什么这有效?

McLeod 和 Bellhouse (1983) 使用组合数学提供了证明。它很漂亮,但是在这里重建它会有点困难。因此,我生成了一个更容易解释的替代证明。

我们通过归纳法进行证明。

假设我们想要生成一组s元素以及我们已经看到的n>s元素。

假设我们当前的s每个元素都已被概率选择s/n.

根据算法的定义,我们选择元素n+1有概率s/(n+1).

已经属于结果集的每个元素都有一个概率1/s被替换。

一个元素从n-seen结果集被替换为n+1- 因此看到的结果集是(1/s)*s/(n+1)=1/(n+1)。反之,某个元素未被替换的概率为1-1/(n+1)=n/(n+1).

就这样n+1-seen 结果集包含一个元素,如果它是n- 看到结果集并且没有被替换---这个概率是(s/n)*n/(n+1)=s/(n+1)---或者如果选择了该元素---有概率s/(n+1).

算法的定义告诉我们,第一个s元素自动包含为第一个n=s结果集的成员。因此,n-seen结果集包含每个元素s/n(=1) 概率为我们提供了归纳所需的基本情况。

参考

  1. 麦克劳德、A. 伊恩和大卫 R. 贝尔豪斯。 “一种用于抽取简单随机样本的便捷算法。”皇家统计学会杂志。 C 系列(应用统计)32.2 (1983):182-184。 (Link)

  2. Vitter, Jeffrey S.“使用水库随机采样。” ACM 数学软件汇刊 (TOMS) 11.1 (1985):37-57。 (Link)

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

从链表中有效地选择一组随机元素 的相关文章

  • JasperReports:传入列表列表作为数据源

    我需要用不同对象的列表填充一些子报表 基本上可以说我有以下内容 二手车子报告新车子报告 我创建一个车辆 bean 类 其中变量作为字符串 并为其创建 getter 和 setter 方法 然后在我的数据源中我传入一个List
  • 将数字 n 拆分为 k 个不同数字的总和

    我有一个数字 n 我必须将它分成 k 个数字 使得所有 k 个数字都是不同的 k 个数字的总和等于 n 并且 k 最大 例如 如果 n 为 9 则答案应为 1 2 6 如果 n 为 15 则答案应为 1 2 3 4 5 这就是我尝试过的 v
  • 在哪里可以找到有关双三次插值和 Lanczos 重采样的好读物?

    我想用 C 实现上述两种图像重采样算法 双三次和 Lanczos 我知道现有的实现有几十种 但我仍然想制作自己的实现 我之所以这么做 部分原因是我想了解它们是如何工作的 部分原因是我想为它们提供一些主流实现中没有的功能 例如可配置的多 CP
  • 比较两棵树的伪代码

    这是我遇到过几次的问题 并且不确信我使用了最有效的逻辑 例如 假设我有两棵树 一棵是文件夹结构 另一棵是该文件夹结构的内存 模型 我希望比较两棵树 并生成一棵树中存在的节点列表 而不是另一棵树中存在的节点列表 反之亦然 是否有公认的算法来处
  • 带有元数据的 scipy kdtree

    我目前正在寻找一种方法来构建几个 kd 树以快速查询一些 n 维数据 但是 我对 scipy KD 树算法有一些问题 我的数据包括id gt data somedata coordinate x y 我希望能够基于坐标和 k 最近邻居的 i
  • Yegge 的原型模式示例如何处理实例变量?

    我喜欢史蒂夫 耶吉的原型模式示例 http steve yegge blogspot com 2008 10 universal design pattern html并决定快速制作一个概念验证示例 不过 我并没有真正考虑清楚 虽然它非常适
  • 加权图的 BFS 算法 - 寻找最短距离

    我看过很多帖子 即 post1 https stackoverflow com questions 30409493 using bfs for weighted graphs post2 https cs stackexchange co
  • 查找两个大小为 n 的数组中第 n 大数的算法

    我有这个问题 给定两个大小为 n 的排序列表 存储在数组中 找到 O log n 计算并集中第 n 大元素的算法 两个列表 我可以看到这里可能有一个技巧 因为它需要第 n 个最大的元素 并且数组的大小也是 n 但我不知道它是什么 我在想我可
  • 算法 - 树中所有节点的最大距离

    所以 找到树中两个节点之间的最长路径相当容易 但我想要的是找到从节点出发的最长路径x到树中的另一个节点 对于所有x 这个问题也可以用以下方式表达 计算从给定的树中可以生成的所有有根树的高度 One way of course is to j
  • SwiftUI 从一个列表拖动到另一个列表

    我正在尝试在列表之间拖放 我尝试过的 我找到了一个在 UIKIt 中执行此操作并使用 UIViewControllerRepresentable 的解决方案 但这不是我想要的 另一个解决方案是在列表上使用 onDrag 但这在 iPad 上
  • 类型错误:不支持的操作数类型 -:“int”和“list”

    我正在尝试用 python 创建一个程序 它会使用 Zeller 算法告诉你你出生在星期几http en wikipedia org wiki Zeller 27s congruence http en wikipedia org wiki
  • 替换 Python 列表/字典中的值?

    好的 我正在尝试过滤传递给我的列表 字典并稍微 清理 它 因为其中有某些值我需要删除 所以 如果它看起来像这样 records key1 AAA key2 BBB key3 CCC key4 AAA 我如何快速轻松地运行所有内容并将 AAA
  • 计算总和等于 k ​​的子集数量

    给定一个数组 我们需要找出总和恰好等于给定整数 k 的子集的数量 请针对这个问题提出一个最佳算法 这里不需要实际的子集 只需计数即可 该数组由整数组成 可以是负数也可以是非负数 例子 数组 gt 1 4 1 10 5 绝对值总和 gt 9
  • 存储整数列表的最有效方法

    我最近一直在做一个项目 其中一个目标是使用尽可能少的内存来使用 Python 3 存储一系列文件 除了一个整数列表之外 几乎所有文件都占用很少的空间 大致333 000整数长且整数可达约8000在尺寸方面 我目前正在使用pickle存储列表
  • 如何在大空间尺度上加速A*算法?

    From http ccl northwestern edu netlogo models community Astardemo http ccl northwestern edu netlogo models community Ast
  • 让电脑实现360度=0度,旋转炮塔

    我正在制作一个游戏 其中有一个计算机控制的炮塔 炮塔可360度旋转 它使用 trig 找出枪瞄准所需的角度 obj deg 并将枪的当前角度存储在 gun deg 下面的代码以设定的速度旋转枪 if objdeg gt gundeg gun
  • 广度优先搜索:检查访问状态的时机

    在有向图的广度优先搜索中 可能循环 当一个节点出队时 其所有尚未访问的子节点都会入队 并且该过程将继续 直到队列为空 有一次 我以相反的方式实现它 将节点的所有子节点排队 并在节点出队时检查访问状态 如果正在出队的节点之前已被访问过 则该节
  • 将字符串中的 i 个连续相同字符分组到列表中[重复]

    这个问题在这里已经有答案了 我希望以这样的方式分隔输入字符串 即所有连续的相同字符都分组在一个列表中 示例1 str aabbcccdeddgg output aa bb ccc d e dd 期望的输出 aa bb ccc d e dd
  • 创建将 n 个用户放入 k 个组的所有可能方法

    给定 n 个用户 u 1 u 2 u n 和 k 个组 g 1 g 2 g k 创建所有组的所有可能组合 基本上 最后每个组合都是一个Map 其中第一个Integer是用户ID 第二个Integer是组ID 例如 u 1 g 1 u 2 g
  • 如何为所有语言创建字母数字正则表达式?

    我今天遇到了这个问题 此正则表达式仅匹配英语 a zA Z0 9 如果我需要支持这个世界上的任何语言 我应该编写什么正则表达式 如果您使用字符类简写和 Unicode 识别正则表达式引擎 您就可以做到这一点 这 wclass 匹配 单词字符

随机推荐

  • ReactNative Flatlist onEndReached 不起作用

    我试图调用一个函数onEndReachedFlatList 的但它不起作用 我正在打电话this state pageNo最后 它没有更新 我想稍后在无限滚动中使用这个逻辑 但现在无法让它工作 import React Component
  • 使用 JSON 进行 XmlHttpRequest POST [重复]

    这个问题在这里已经有答案了 如何使用 vanilla JS 发出 AJAX POST 请求发送 JSON 数据 我知道内容类型是 url 形式编码的 并且不支持嵌套 JSON 有什么方法可以在普通的旧 JS 中使用嵌套 JSON 发出这样的
  • 将 python 列表传递给 django 模板

    我想在我的模板上显示内容列表 因此 我希望生成该列表并将其传递给模板 如下所示 newlinks try links urllib2 urlopen lt
  • 如何删除下拉列表的边框:CSS

    我想删除下拉列表之外的边框 我在尝试 select xyz option Border none 但对我不起作用 您无法设置下拉框本身的样式 只能设置输入字段的样式 该框由操作系统呈现 如果您想更好地控制输入字段的外观 您可以随时查看Jav
  • R裁剪栅格数据并设置轴限制

    在您在另一个线程中的帮助下 我成功绘制了一些全球地图 首先 我将气象 GRIB2 数据转换为 Netcdf 然后绘制全球地图 现在我只想绘制地图的一个子区域 我尝试了crop命令并成功提取了全局nc文件的子区域 但是在绘图时我找不到如何控制
  • 在 ExtJS 中加载 hasMany 数据

    我正在尝试将 嵌套 数据加载到hasManyExtJS4 中的关系 我的模型看起来像这样 Ext define Entrypage model Entrypage extend Ext data Model fields id title
  • Laravel 5.5 Axios POST 导致 419 错误

    我正在尝试从 Vue 向我的 Laravel API 发出 POST 请求 这X CSRF TOKEN标头设置正确 我在发送到服务器的 POST 包中看到这一点 路由有默认的web 中间件 Request Accept applicatio
  • System.out.println 和 System.err.println 乱序

    My System out println and System err println 呼叫不会按照我拨打的顺序打印到控制台 public static void main String args for int i 0 i lt 5 i
  • 将静态数据存储在数组中还是数据库中?

    我们总是有一些静态数据 它们可以作为数组存储在文件中 也可以存储在基于 Web 的项目中的数据库表中 那么应该优先选择哪一个呢 在我看来 数组有一些优点 更灵活 可以是任何结构 指定非常复杂的关系 更好的性能 会加载到内存中 与数据库的I
  • 使用 Capybara 进行 AJAX 集成测试

    我正在使用 Capybara 进行 Rails 集成测试 当涉及 AJAX 请求时 我收到以下错误 Capybara TimeoutError failed to resynchronize ajax request timed out 知
  • 解雇ModalViewControllerAnimated:(和解雇ViewControllerAnimated)在iOS 5中崩溃

    我找不到任何合乎逻辑的解释 但事实仍然是 在iOS 5 xCode 4 2 中 如果我presentModalView animated YES 我可以调用dismissModalViewAnimated 很好 但如果我调用presentM
  • jQuery Mobile 初始化列表视图的正确方法

    这是我的问题 我的索引中有一些硬编码的伪页面 有些填充了内容 有些是空的 只有通过 ajax 才能在用户交互时填充 此 ajax 内容包含 html 列表 当它们加载时 它们没有漂亮的 jquery 移动外观 所以我必须调用 listvie
  • 如何在 Spring WebFlux 中记录请求和响应主体

    我希望使用 Kotlin 在 Spring WebFlux 上的 REST API 中集中记录请求和响应 到目前为止我已经尝试过这种方法 Bean fun apiRouter router accept MediaType APPLICAT
  • Android Studio 不断向 GitHub 添加额外文件

    我正在使用 Android Studio 2 2 2 使用内置的 VCS 工具 由于某种原因 Android Studio 会自动添加一堆我没有添加或编辑的额外 xml 文件和文件夹 更具体地说 当我不希望它添加以下文件时 它会添加 win
  • Android 中的单例与应用程序上下文?

    回想起这个列举了使用单例的几个问题在看到几个使用单例模式的 Android 应用程序示例后 我想知道使用单例而不是通过全局应用程序状态共享的单个实例 子类化 android os Application 并通过 context getApp
  • webdriver.get() 和 webdriver.navigate() 之间的区别

    有什么区别get and navigate 方法 此方法或其他方法是否等待页面内容加载 我真正需要的是像 Selenium 1 0 这样的东西WaitForPageToLoad但对于使用viawebdriver 有什么建议么 导航 使用 W
  • 如何以编程方式重命名Google存储中的文件夹?

    我有一个谷歌存储java客户端 我想重命名云端的文件夹 有办法做到吗 我看到了更新帖子但我不知道如何更改名称元数据 这是我的尝试 但我不知道该填写什么 entity 并且没有oac setName public void renameDir
  • Access-Control-Allow-Headers 列表中不存在请求标头

    在我的 API 中 我有以下代码 public class CustomOAuthProvider OAuthAuthorizationServerProvider public override Task MatchEndpoint OA
  • SKSpriteNode,添加到父挂钩/从父挂钩中删除

    当 SKSpriteNode 或 SKNode 添加到父节点或从父节点中删除时 类中是否有任何 最佳实践 方法来挂钩事件 无需 Kobold Kit 您可以对 SKSpriteNode 或任何 SKNode 事实上 进行子类化并扩展remo
  • 从链表中有效地选择一组随机元素

    假设我有一个长度为数字的链表N N非常大 我事先不知道确切的值N 我怎样才能最有效地编写一个将返回的函数k完全地随机数从列表中 有一个非常好的且有效的算法 使用称为水库取样 让我首先给你它history Knuth在 p 上调用该算法 R