3

坦率地说,我一直在考虑如何实现超出我数学技能的东西。因此,请随时尝试为我指明正确的方向,而不是完整的代码解决方案,我将不胜感激。

所以,假设我已经对文本进行了分析,并生成了一个不同的两个字符组合的频率表。我已将这些存储在 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.

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

我正在考虑选择我的第一个字符 - 即。该行 - (我最终生成一个 4 对序列)我可以只使用系统随机函数(Random class.Next)然后使用“加权”随机算法来选择第二个字符。

有任何想法吗?

4

6 回答 6

5

鉴于您的示例样本,我将首先创建所有数字的累积系列(1、15、12、0 => 1、16、28、28)。

然后我会产生一个介于 0 和 27 之间的随机数(比如说 19)。

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

于 2013-01-30T12:18:22.297 回答
5

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

在 C# 中生成随机非均匀数据

于 2013-01-30T15:14:51.070 回答
1

如何将所有频率相加并使用从 AA 到 ZZ 的频率来生成您的频率对。

可以说,如果 rnd 返回 0,您将获得 AA,如果它返回 1-14,那么您将获得对的总频率,然后是 AB 等

于 2013-01-30T12:23:16.290 回答
1

使用您的频率矩阵生成一组完整的值。通过 Random.Next() 对集合进行排序。将随机集存储在数组中。然后,如果该数组基于 Random.Next(randomarray.Length),您可以只选择一个元素。

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

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

...

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

于 2013-01-30T12:28:44.160 回答
0

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

例如伪代码:

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

return i
于 2013-01-30T12:36:45.197 回答
0

如果效率不是问题,您可以创建一个 key->value 散列而不是一个数组。这样做的好处是(如果您在文本中很好地格式化它)如果需要更新值将非常容易。就像是

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

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

于 2014-05-16T14:15:39.383 回答