如何获得具有固定总和和大小的随机数列表

2024-03-08

如何根据给定大小和期望总和获取随机数列表,完全支持

i hava a code sum-int.ts https://github.com/bluelovers/random/blob/master/src/distributions/sum-int.ts sum-float.ts https://github.com/bluelovers/random/blob/master/src/distributions/sum-float.ts internal/sum-num.ts https://github.com/bluelovers/random/blob/master/src/distributions/internal/sum-num.ts

我想做的事

  1. rN = min ~ max 之间的随机数( float 或 int )
  2. 大小 = [r1, r2, r3, ...rN]. 长度
  3. 总和 = r1 + r2 + r3 + ...rN
  4. 所有 rN 应 >= min,且
  5. 支持(唯一/非唯一)值

but now there has problem

  • 当 max
  • 当 max
  • 代码有逻辑bug,所以我来这里问一下如何用js制作它

好的,就在这里。让我们从整数问题开始。最简单的方法是使用统计分布,它是自然产生的一组数字总和为一个固定值。并且有这样的分布——多项分布 https://en.wikipedia.org/wiki/Multinomial_distribution。它的固定总和等于n,它提供从 0 到n。因为要求采样间隔是任意的,所以首先我们将间隔移动到最小值为0,采样然后将其移回。请注意,采样值可能高于所需的最大值,因此我们必须使用拒绝技术,其中任何高于最大值的样本都将被拒绝,并且将对下一次尝试进行采样。

我们使用 Python/Numpy 的多项式采样。除了拒绝之外,您还可以添加独特性测试。代码,Python 3.7

import numpy as np

def sample_sum_interval(n: int, p, maxv: int):
    while True:
        q = np.random.multinomial(n, p, size=1)[0]
        v = np.where(q > maxv)
        if len(v[0]) == 0: # if len(v) > 0, some values are outside the range, reject
            # test on unique if len(np.unique(q)) == len(q)
            return q
    return None

k = 6
min = -8
max = 13
sum = 13

n    = sum - k*min # redefined sum
maxv = max - min   # redefined max, min would be 0
p = np.full((k), np.float64(1.0)/np.float64(k), dtype=np.float64) # probabilities

q = sample_sum_interval(n, p, maxv) + min # back to original interval
print(q)
print(np.sum(q))
print(np.mean(q))

q = sample_sum_interval(n, p, maxv) + min
print(q)
print(np.sum(q))
print(np.mean(q))

q = sample_sum_interval(n, p, maxv) + min
print(q)
print(np.sum(q))
print(np.mean(q))

Output

[ 5  0 -2  3  3  4]
13
2.1666666666666665
[ 3  3 -1  2  1  5]   
13                    
2.1666666666666665    
[-4  0  0  3 10  4]   
13                    
2.1666666666666665    

为了将其转换为 JavaScript,您需要多项式采样或二项式采样,从二项式很容易转换为多项式。

UPDATE

好的,这是我不添加时的输出min结果,总和为 61 (13+6*8), 范围 [0...21]

[11  7  6  8  9 20]
61
10.166666666666666
[ 5 10 14 13 14  5]
61
10.166666666666666
[ 9 12  7 15  7 11]
61
10.166666666666666

显然,有一个具有多项式采样的 Javascript 库 https://github.com/R-js/libRmath.js,其仿照R, 谢谢你@bluelovers

应该像这样在循环中调用它:

v = rmultinom(1, n, p);

进而v应检查是否在范围 [0...maxv] 内,如果超出则接受或拒绝。

更新二

让我快速地(抱歉,真的没有时间,明天再说)描述一下我将如何为浮动做这件事的想法。在 [0...1] 范围内生成的一组数字也有类似的分布,称为狄利克雷分布 https://en.wikipedia.org/wiki/Dirichlet_distribution,并且它的总和始终为固定值 1。在 Python/Numpy 中,它是https://docs.scipy.org/doc/numpy-1.15.1/reference/ generated/numpy.random.dirichlet.html https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.dirichlet.html.

Suppose I sampled n numbers di from Dirichlet and then map them to [min...max] interval:

xi = min + di*(max-min)

Then I sum them all, using property that all di sums to 1:

总和 = n*min + (max - min) = (n-1)*min + max

If Sum is fixed, then it mean we have to redefine maximum value - lets call it sampling maxs.

So sampling procedure would be as following - sample n [0...1] numbers from Dirichlet, map them to [min...maxs] interval, and check if any of those numbers are below desired max (original, not redefined). If it is, you accept, otherwise reject, like in integer case.

代码如下

import numpy as np

def my_dirichlet(n: int):
    """
    This is equivalent to numpy.random.dirichlet when all alphas are equal to 1
    """
    q = np.random.exponential(scale = np.float64(1.0), size=n)
    norm = 1.0/np.sum(q)
    return norm * q

def sample_sum_interval(n: int, summa: np.float64, minv: np.float64, maxv: np.float64):
    maxs  = summa - np.float64(n-1)*minv # redefine maximum value of the interval is sum is fixed
    alpha = np.full(n, np.float64(1.0), dtype=np.float64)

    while True:
        q = my_dirichlet(n) # q = np.random.dirichlet(alpha)
        q = minv + q*(maxs - minv) # we map it to [minv...maxs]
        v = np.where(q > maxv)     # but we need it in the [minv...maxv], so accept or reject test
        if len(v[0]) == 0: # if len(v) > 0, some values are outside the range, reject, next sample
            return q
    return None

n = 5
min = np.float64(-2.0)
max = np.float64(3.0)
sum = np.float64(1.0)

q = sample_sum_interval(n, sum, min, max)
print(q)
print(np.sum(q))

q = sample_sum_interval(n, sum, min, max)
print(q)
print(np.sum(q))

q = sample_sum_interval(n, sum, min, max)
print(q)
print(np.sum(q))

我已经放置了标准 NumPy Dirichlet 采样以及自定义 Dirichlet 采样。显然,libRmath.js有指数分布采样,但没有狄利克雷,但可以用用户定义的代码和指数替换。请记住,NumPy 使用单个运算符对向量进行运算,循环是隐式的。

Output:

[-0.57390094 -1.80924001  0.47630282  0.80008638  2.10675174]
1.0000000000000013
[-1.12192892  1.18503129  0.97525135  0.69175429 -0.73010801]
0.9999999999999987
[-0.34803521  0.36499743 -1.165332    0.9433809   1.20498888]
0.9999999999999991
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获得具有固定总和和大小的随机数列表 的相关文章

随机推荐

  • 构建数据库项目时出现“不正确的 SET 选项”错误

    我们正在使用 Visual Studio 和数据库项目来生成我们的数据库 我刚刚做了一些数据库更改 包括添加一个名为Correspondence 将这些更改导入到数据库项目中 并尝试部署 重建 数据库 当我这样做时 我收到以下错误 正在创建
  • ImportError:没有名为“matplotlib.pyplot”的模块; matplotlib 不是一个包

    我正在尝试使用 matplotlib 对心电图信号进行实时分析 但问题甚至在此之前就开始了 我使用 PyCharm IDE 目前使用 Python 3 3 我的操作系统是 Windows 8 1 对于 Matplotlib 我从这里下载了
  • 在范围“no autodie”之后,程序在“*STDOUT”处终止

    这个节目 use warnings use strict use feature qw say use autodie all good when this is uncommented no autodie open my OLDSTD
  • 根据.config剥离Linux内核源代码

    是否有任何有效的方法 也许通过滥用 gcc 预处理器 来获取一组剥离的内核源代码 其中根据 config 不需要的所有代码都被省略 好吧 我们采取了一些解决方案 首先 可以通过以下方式获取所使用的编译器命令 make KBUILD VERB
  • 是否可以/推荐发送包含 Javascript 的 HTML 电子邮件? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Android Studio 中的 NDK 集成

    今天我将android studio更新到1 3 并在local properties中输入NDK android ndk r10e NDK版本 路径 ndk dir C AndroidNDK android ndk r10e androi
  • 在 AngularJs 中制作工厂模块的正确方法

    我有一个像这样的控制器功能 scope localTimezone function userTimezone datetime return data 使其成为工厂模块的正确方法是什么 我尝试了以下操作 但出现错误 angular mod
  • 已完成百分比的流

    我需要使用类似的方法将 base64 格式的文件流式传输到 http 端点request https github com mikeal request or 超级代理人 https github com visionmedia super
  • 如何将 UISearchController 搜索栏设置为不是 tableHeaderView 或 navigationItem.titleview 的视图?

    我试图在表格滚动时保持搜索栏可见 目前 我将其作为表视图中的标题 并且它按应有的方式工作 但是当然 当您沿着表格向下滚动时 搜索栏会滚动到屏幕之外 我想我可以简单地修改这个代码示例来做到这一点 如何在 iOS 8 中使用 UISearchC
  • Keycloak - 如何检查用户名和电子邮件是否存在

    我们希望以编程方式创建 Keycloak 用户 并检查用户名和 或电子邮件地址是否已存在于 Keycloak 中 我们正在使用的版本4 4 0 FINAL 当我们使用 Keycloak 管理客户端以编程方式创建用户时 如果用户名或电子邮件地
  • Laravel 路线带我去别的地方

    我正在尝试通过 Laravel 和 vue js 创建 CRUD 应用程序 但这里总是存在问题 当我运行该应用程序时 它会转到仪表板并且不会出现 CRUD 操作 以下是 Routes web app 代码
  • 基于 int 创建多个编号变量

    我将如何创建多个NSDictionary使用数组计数的变量 这基本上是我想到的 但我不确定如何使用 Objective C 语法来实现它 doesntContainAnother is an NSArray 我希望字典的名称使用当前值loo
  • CMD脚本:如何关闭CMD

    我创建了一个小命令 可以让我启动 Internet Explorer 但是 我希望关闭启动 IE 时显示的小命令提示符 我怎样才能做到这一点 这是我当前的代码 ProgramFiles Internet Explorer iexplore
  • 未知协议:c(JDOM 和 SAXBuilder)

    我正在使用 JDOM 和 SAXBuilder 来解析 XML 文件 但我遇到了一个抛出此错误的文件问题 java net MalformedURLException unknown protocol c at java net URL
  • Shell 命令适用于命令行,但不适用于 PHP exec

    我有一个命令 当直接在命令行上运行时 它可以按预期工作 它运行超过 30 秒并且没有抛出任何错误 当通过 PHP 函数 exec 包含在由 cron 调用的脚本中 通过 PHP 脚本调用相同的命令时 它会抛出以下错误 最长执行时间为 30
  • Windows 下以 cygwin 和 Github 结尾的行

    我希望能够使用 Windows 应用程序的 Github 以及使用 Cygwin 在 Windows 上 的命令行中的 git 来处理我的 git 项目 但当我从一种切换到另一种时 我不断遇到行尾问题 如果使用命令行工具存储库没有更改 它将
  • 如何模拟从不同模块导入的方法中导入的函数[重复]

    这个问题在这里已经有答案了 我有以下功能要测试 my package db engine db functions py from utils import execute cmd from my package db engine db
  • 使用jquery获取facebox div内元素的值

    我的页面上有两个 div 标签 如下所示 当我引用 itemName 元素的值时 使用 itemName val 我在两个 div 中都有 我总是得到第一个 div 中元素的值 即 空白 有没有办法使用 jquery 获取第二个 div 中
  • 在所有地址上运行我自己的用户脚本有风险吗?

    Tampermonkey 对于大多数浏览器 和 Greasemonkey 对于 Firefox 都支持 match and include指令 当我开始阅读它们之间的区别时 结果发现 match有点严格 用户脚本不会在某些地址上启动 这可能
  • 如何获得具有固定总和和大小的随机数列表

    如何根据给定大小和期望总和获取随机数列表 完全支持 i hava a code sum int ts https github com bluelovers random blob master src distributions sum