生成加权随机数

2024-04-15

我正在尝试设计一种(好的)方法从一系列可能的数字中选择一个随机数,其中该范围内的每个数字都被赋予一个权重。简单地说:给定数字范围 (0,1,2),选择一个数字,其中 0 有 80% 的概率被选中,1 有 10% 的概率,2 有 10% 的概率。

自从我上大学统计课以来已经过去了大约 8 年,所以你可以想象我现在忘记了正确的公式。

这是我想出的“廉价而肮脏”的方法。该解决方案使用 ColdFusion。您可以使用您想要的任何语言。我是一名程序员,我想我可以处理移植它。最终我的解决方案需要在 Groovy 中 - 我在 ColdFusion 中编写了这个解决方案,因为在 CF 中快速编写/测试很容易。

public function weightedRandom( Struct options ) {

    var tempArr = [];

    for( var o in arguments.options )
    {
        var weight = arguments.options[ o ] * 10;
        for ( var i = 1; i<= weight; i++ )
        {
            arrayAppend( tempArr, o );
        }
    }
    return tempArr[ randRange( 1, arrayLen( tempArr ) ) ];
}

// test it
opts = { 0=.8, 1=.1, 2=.1  };

for( x = 1; x<=10; x++ )
{
    writeDump( weightedRandom( opts ) );    
}

我正在寻找更好的解决方案,请提出改进​​或替代方案。


拒绝抽样 http://en.wikipedia.org/wiki/Rejection_sampling(例如在您的解决方案中)是首先想到的,您可以构建一个查找表,其中的元素按其权重分布填充,然后在表中选择一个随机位置并将其返回。作为一种实现选择,我将创建一个高阶函数,它接受一个规范并返回一个函数,该函数根据规范中的分布返回值,这样您就不必为每个调用构建表。缺点是构建表的算法性能与项目数量成线性关系,并且大规格(或具有非常小或精确权重的成员的规格,例如 {0:0.99999, 1 :0.00001})。优点是选择值的时间恒定,如果性能至关重要,这可能是可取的。在 JavaScript 中:

function weightedRand(spec) {
  var i, j, table=[];
  for (i in spec) {
    // The constant 10 below should be computed based on the
    // weights in the spec for a correct and optimal table size.
    // E.g. the spec {0:0.999, 1:0.001} will break this impl.
    for (j=0; j<spec[i]*10; j++) {
      table.push(i);
    }
  }
  return function() {
    return table[Math.floor(Math.random() * table.length)];
  }
}
var rand012 = weightedRand({0:0.8, 1:0.1, 2:0.1});
rand012(); // random in distribution...

另一种策略是在其中选择一个随机数[0,1)并迭代权重规范,对权重求和,如果随机数小于总和,则返回关联值。当然,这是假设权重之和为一。该解决方案没有前期成本,但平均算法性能与规范中的条目数量成线性关系。例如,在 JavaScript 中:

function weightedRand2(spec) {
  var i, sum=0, r=Math.random();
  for (i in spec) {
    sum += spec[i];
    if (r <= sum) return i;
  }
}
weightedRand2({0:0.8, 1:0.1, 2:0.1}); // random in distribution...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

生成加权随机数 的相关文章

随机推荐

  • mysql 查找多列重复项

    如何查找多列的重复记录 表有主键 自动递增 EG ID a id b id 1 34 23 2 34 23 3 35 25 例如我想查找具有相同a id和b id的记录 Thanks select t ID t a id t b id fr
  • 如何找到激活时打开给定 HMENU 的菜单项(如果有)?

    我想用原型实现一个功能 Locates the menu item of the application which caused the given menu mnu to show up return true if the given
  • 如何将事件处理程序分配给 JavaScript 中的多个元素?

    我知道如何使用 jQuery 来做到这一点 并且我知道如何使用事件委托来做到这一点 但是如何在纯 JavaScript 中做到这一点呢 例如 如何将事件处理程序分配给一堆lis 我看到var li document querySelecto
  • 代码高尔夫:弗罗贝尼乌斯数

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 编写最短的程序来计算给定正数集的弗罗贝尼乌斯数 弗罗贝尼乌斯数是不能写成集合中数字的正倍数之和
  • CKEditor 5 通过外部 url 插入图像

    我想知道如何仅通过 URL 插入图像 用户从其他网站获取它 我需要实现一个简单的img 源 在 CKEditor 5 中 问题是 默认情况下 编辑器要求我上传图像 而我需要插入外部 url 我读过很多相关主题 1 https stackov
  • 带正文的 HttpDelete

    我正在尝试使用 HttpDelete 对象来调用 Web 服务的删除方法 Web 服务的代码从消息正文中解析 JSON 但是 我无法理解如何将主体添加到 HttpDelete 对象 有没有办法做到这一点 使用 HttpPut 和 HttpP
  • Python 的“导入”内部是如何工作的?

    当您导入一个模块 然后再次重新导入它时 它会被重新导入 覆盖还是跳过 当您导入模块 a 和 b 并且还在模块 a 中导入模块 b 时 会发生什么 这样做安全吗 例如 如果该模块 b 中有一个实例化的类 您最终会实例化它两次吗 import加
  • 我在使用阴影效果时表现不佳

    我在滚动视图上放置了一些图像视图 当我拖动这个滚动视图时 我没有遇到任何问题 但是 当我对这些图像视图应用阴影效果后 拖动此滚动视图的性能很差 我使用了shadowOpacity shadowRadius 和shadowOffset 方法
  • 使用流迭代 n 次,而不是使用 for 循环创建 n 项

    假设我想创建 n 个项目 在 Java 8 之前 我会这样写 List
  • 如何构建特定函数调用的图表?

    我有一个项目 我想动态构建特定函数调用的图表 例如 如果我有 2 个模板类 A 和 B 其中 A 有一个跟踪方法 保存为图形节点 B 有 3 个方法 非跟踪方法 跟踪方法和调用 A 的跟踪方法的跟踪方法 那么我希望能够仅将跟踪的方法调用注册
  • PyAudio 输入溢出

    我正在尝试用 python 发出实时绘图声音 我需要从我的麦克风中获取数据块 使用 PyAudio 尝试使用 import pyaudio import wave import sys chunk 1024 FORMAT pyaudio p
  • 查找字符串的*最*常见前缀 - 更好的方法吗?

    我有一个钥匙列表 foo a foo b foo c fnord 这里所有类似的解决方案都假设您没有fnord在你的文字中 我有这个代码可以完成这项工作 def detect prefix keys PCT 0 70 cutof pre l
  • 获取“/”字符后的字符串

    我想在 PostgreSQL SELECT 查询中提取字符 后面的字符串 字段名称是source path 表名是movies history 数据示例 source path 的值 184738 file1 mov 194839 file
  • 将 MATLAB 绘图转换为图像

    我生成了一个类似的情节 figure hold axis 0 10 0 10 fill 1 1 5 5 5 1 1 5 b 现在我想将此图作为矩阵 以便我可以用高斯过滤博客 谷歌搜索我发现了这个线程将绘图光栅化为图像 http www ma
  • 如何在 Struts2 中检查 s:if 中的字符串不等式

    我在用
  • android OpenGL ES简单图块生成器性能问题

    遵循这个问题 老式 2D 类似塞尔达传说游戏的最佳方法 https stackoverflow com questions 2125354 best approach for oldschool 2d zelda like game 感谢之
  • 在 log(n) 时间内查找排序数组中至少出现 k 次的元素

    给定一个由 n 个元素和一个数字 k 组成的排序数组 是否有可能在 log n 时间内找到出现超过 k 次的元素 如果有多个数字出现超过 k 次 则其中任何一个都可以接受 如果是 怎么办 编辑 我能够在线性时间内解决这个问题 并且我很高兴在
  • 如何从命令行列出已安装的 MSI? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我们最近将 Windows 软件包从 RPM cygwin 切换到 MSI wix 拥有原生包装是一个非常受欢迎的变化 我们打算坚持下去 然而 MSI
  • 使用 JQuery 将事件处理程序添加到 iframe

    我想将 keydown 事件处理程序分配给 iframe 类似于纯JS的东西 document getElementById iframe id contentWindow addEventListener keydown funcName
  • 生成加权随机数

    我正在尝试设计一种 好的 方法从一系列可能的数字中选择一个随机数 其中该范围内的每个数字都被赋予一个权重 简单地说 给定数字范围 0 1 2 选择一个数字 其中 0 有 80 的概率被选中 1 有 10 的概率 2 有 10 的概率 自从我