如何根据数组对随机数进行加权

本文关键字:加权 随机数 何根 数组 | 更新日期: 2023-09-27 17:56:34

我一直在思考如何实现一些坦率地说超出了我的数学技能的东西。所以在这里,请随时尝试为我指出正确的方向,而不是完整的代码解决方案,我会感激任何帮助。

所以,假设我已经对文本进行了分析,并生成了一个不同双字符组合频率的表格。我将它们存储在 26x26 数组中。例如。

  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A 1 15 (frequency of AA, then frequency of AB etc.)
B 12 0 (freq of BA, BB etc..)
... etc.

所以我想随机选择这两个字符组合,但我想根据频率"加权"我的选择。 即上面的 AB 应该比 AA "更有可能"15 倍。而且,显然,选择永远不应该返回类似 BB 的东西(即频率为 0 - 在这个例子中,显然 BB 确实出现在像 Bubble 这样的单词中!!对于 0 的情况,我意识到我可以循环直到我得到一个非 0 频率,但这并不优雅,因为我有一种感觉/直觉,有一种方法可以扭曲我的平均值。

我想选择我配对中的第一个字符 - 即行 - (我最终生成一个 4 对序列)我可以使用系统随机函数(随机类。Next)然后使用"加权"随机算法选择第二个字符。

有什么想法吗?

如何根据数组对随机数进行加权

给定您的示例示例,我将首先创建所有数字(1、15、12、0 => 1、16、28、28)的累积序列。

然后我会生成一个介于 0 和 27 之间的随机数(假设 19)。

然后我会计算出 19 是>=16 但 <28,给我桶 3 (BA)。

对于您的特定问题,其他答案中有一些很好的建议。为了解决"我有一个符合均匀概率分布的随机数源,但我希望它符合给定的非均匀概率分布"的一般问题,那么你可以计算出分位数函数,它是执行该转换的函数。我做了一个温和的介绍,解释了为什么分位数函数是你想要的函数:

在 C# 中生成随机非一致性数据

如何对所有

频率求和,然后使用从 AA 到 ZZ 的频率来生成您的对。

假设您有一个配对的总频率,如果 rnd 返回 0,则得到 AA,如果它返回 1-14,则返回其 AB 等

使用频率矩阵生成一组完整的值。 按 Random.Next() 对集合进行排序。 将随机集存储在数组中。 然后,如果该数组基于 Random.Next(randomarray。长度)。

如果有数学方法来计算频率,你也可以这样做。 但是,如果重复调用,创建预编译和缓存集将减少计算时间。

请注意,根据最大频率,这可能需要大量的存储空间。 您还希望在循环构建集合之前创建随机实例。 这样您就不会重新设定随机生成器的种子。

另一种方法(类似于您在问题末尾建议的方法)是分两次执行此操作,第一次选择行,第二次使用加权频率选择列。 那只是限定在一个范围内的行频率的总和。 第一个建议应根据权重给出更均匀的分布。

取概率的总和。取一个介于零和该总和之间的随机数。将概率相加,直到它大于或等于您的随机数。然后使用你的项目。

例如伪代码:

b = getProbabilites()
s = sum(b)
r = randomInt() % s
i = 0
acc = 0
while (acc < r) {
    acc += b[i]
    i++
}
return i

如果效率不是问题,您可以创建键值>值哈希而不是数组。这样做的好处是(如果您在文本中格式化良好)在需要时更新值将非常容易。类似的东西

{
    AA => 5, AB => 2, AC => 4,
    BA => 6, BB => 5, BC => 9,
    CA => 2, CB => 7, CC => 8
}

这样,您可以轻松检索所需序列的值,并快速找到要更新的条目。如果表是自动生成的并且非常大,那么了解/熟悉 vim 对正则表达式的使用可能会有所帮助。