【问题标题】:Probability density function from a paper, implemented using C++, not working as intended论文中的概率密度函数,使用 C++ 实现,未按预期工作
【发布时间】:2010-11-05 03:51:52
【问题描述】:

所以我正在实现一个启发式算法,我遇到了这个函数。

我有一个 1 到 n 的数组(C 上的 0 到 n-1,w/e)。我想选择一些我将复制到另一个数组的元素。给定一个参数 y,(0

根据作者的说法,“l”是一个随机数:0

所以我编写了函数的第一部分,因为 y

这是 C 测试代码。 “x”是“l”参数。

//hate how code tag works, it's not even working now  
int n = 100;  
float y = 0.2;  
float n_copy;  

for(int i = 0 ; i < 20 ; i++)  
{  
    float x = (float) (rand()/(float)RAND_MAX);  // 0 <= x <= 1  
    x = x * n;                                // 0 <= x <= n  
    float p1 = (1 - y) / (n*y);  
    float p2 = (1 - ( x / n ));  
    float exp = (1 - (2*y)) / y;  
    p2 = pow(p2, exp);  
    n_copy = p1 * p2;  
    printf("%.5f\n", n_copy);  
}  

以下是一些结果(截断 5 位小数):

0.03354  
0.00484  
0.00003  
0.00029  
0.00020  
0.00028  
0.00263  
0.01619  
0.00032  
0.00000  
0.03598  
0.03975    
0.00704  
0.00176  
0.00001  
0.01333  
0.03396   
0.02795  
0.00005  
0.00860 

文章是:

http://www.scribd.com/doc/3097936/cAS-The-Cunning-Ant-System

第 6 和 7 页。

或在谷歌上搜索“cAS:狡猾的蚂蚁系统”。

那么我做错了什么?我不相信作者是错的,因为有超过 5 篇论文描述了相同的功能。

我所有的互联网给任何帮助我的人。这对我的工作很重要。

谢谢:)

【问题讨论】:

  • 不要使用代码标签。 SO 很奇怪,它使用 4 个空格来表示代码。只需复制代码,然后将其全部选中,然后按1010按钮使其成为代码。
  • 那是因为问答框使用 Markdown:daringfireball.net/projects/markdown/syntax

标签: c++ probability heuristics montecarlo ant-colony


【解决方案1】:

您可能会误解对您的期望。

给定一个(适当归一化的)PDF,并且想要抛出一个与之一致的随机分布,您通过积分 PDF 形成累积概率分布 (CDF),然后反转 CDF,并使用统一随机谓词作为参数倒置函数。


更多细节。

f_s(l) 是 PDF,已在 [0,n) 上进行了规范化。

现在您将其集成以形成 CDF

g_s(l') = \int_0^{l'} dl f_s(l)

请注意,这是我称之为l' 的未指定端点的明确组成部分。因此,CDF 是l' 的函数。假设我们有标准化的权利,g_s(N) = 1.0。如果不是这样,我们应用一个简单的系数来修复它。

接下来反转 CDF 并调用结果G^{-1}(x)。为此,您可能需要选择一个特定的 gamma 值。

然后在[0,n) 上抛出统一随机数,并将其用作x 的参数,以G^{-1}。结果应该在[0,1)之间,并且应该按照f_s分配。

就像贾斯汀所说,您可以使用计算机代数系统来计算数学。

【讨论】:

  • 那么f_s(l) 是CDF 吗?我应该怎么做才能得到 [0,n] 随机数?对不起,我不是很喜欢概率,实际上我在概率课上几乎被拒绝了(这个词听起来很奇怪......从谷歌翻译过来)。无论如何,我们也没有学过这样的东西。哦,谢谢你的解释:)
  • 所以获得我想要的数字([0, n] 和 avg y)的唯一方法是按照你说的做?我认为集成不是一个好主意,因为它不是那么简单/快速。我需要尽可能快,尽可能少的计算。如果我必须这样做,我想我会研究一些其他更简单的分布。
  • @polar:如果可能的话,您希望整合和反转符号化,并且只在代码中实现结果(G^{-1})。您当然不想在每次传递时都进行数字积分!如果您必须以数字方式积分,您将执行一次,并将反转结果存储为标准化直方图。关于如何根据直方图绘制数字的细节还有其他问题。您还可以在大多数数值分析文本中找到所有这些内容。
【解决方案2】:

dmckee 实际上是正确的,但我认为我会详细说明并尝试解释这里的一些混淆。我肯定会失败。 f_s(l),上面漂亮公式中的函数是概率分布函数。它告诉您,对于介于 0 和 n 之间的给定输入 ll 是段长度的概率。 0 到 n 之间所有值的总和(整数)应等于 1。

第 7 页顶部的图表混淆了这一点。它绘制了lf_s(l),但你必须注意它放在一边的杂散因素。您注意到底部的值从 0 变为 1,但侧面有一个因子 x n,这意味着 l 的值实际上是从 0 变为 n。此外,在 y 轴上有一个x 1/n,这意味着这些值实际上并没有上升到大约 3,而是上升到 3/n。

那你现在做什么?好吧,您需要通过在l 上积分概率分布函数来求解累积分布函数,这实际上结果还不错(我使用 Wolfram Mathematica 在线积分器通过使用 x 表示 l 并仅使用y l 进行积分。如果我们将结果方程设置为等于某个变量(例如 z),那么现在的目标是求解 l 作为 z 的函数。 z 这里是一个介于 0 和 1 之间的随机数。如果您愿意(我愿意),您可以尝试对这部分使用符号求解器。那么您不仅实现了能够从该分布中随机选择ls 的目标,还实现了涅槃。

还有一些工作要做

我会提供更多帮助。我尝试按照我所说的 y f_s(l) 中的l 更改为x,我会得到

y / n / (1 - y) * (x / n)^((2 * y - 1) / (1 - y))

将 x 从 0 积分到 l 我得到了(使用 Mathematica 的在线积分器):

(l / n)^(y / (1 - y))

没有比这更好的了。如果我将其设置为 z 并求解 l 我得到:

l = n * z^(1 / y - 1)      for .5 < y <= 1

快速检查 y = 1。在这种情况下,无论 z 是什么,我们都会得到 l = n。到目前为止,一切都很好。现在,您只需生成 z(一个介于 0 和 1 之间的随机数),您就会得到一个 l,它按照您的需要在 0.5 l -> n-ly -> 1-y 并得到

n - l = n * z^(1 / (1 - y) - 1)

l = n * (1 - z^(1 / (1 - y) - 1))      for 0 < y <= .5

无论如何,这应该可以解决您的问题,除非我在某处犯了错误。祝你好运。

【讨论】:

  • 谢谢,贾斯汀。根据直觉和帖子标题写下我的答案后,我实际上去读了这篇论文——我很高兴我这样做了,因为它充满了我以前从未见过的各种好东西。无论如何,我认为你在这里已经达到了几个重要的点。值得注意的是,归一化超过 [0,n),而我天真地期望它超过 [0,1)。
  • @dmckee,是的,我觉得这东西很酷。我读过一些关于这类算法的文章,但并不多。我想自己更深入地研究这些东西。
  • 天哪……我在图表上看到了这些因素,我确实理解了 x 轴,但我确实忽略了 x 1/n。所以我读了你的文字,我提醒了我两年的微积分,但我必须对你说点什么......它是英文的,我什么都听不懂(我是巴西人,所以我的课程是葡萄牙语)。你能帮我做这个最简单的方法吗?我会实现这个,我想要最好的性能,而不是太多的计算来获得一个正态分布的随机数。顺便说一句,这是我最后的学位作业,是关于 Ant Systems 和 QAP。
  • 天哪,我所有的互联网都给你!这真的解决了整个问题!我正在考虑放弃这个并使用两个参数来随机化一个数字,但这是完美的!我编写了一个测试程序来计算平均值,并且生成了 n = 100 和 3000 个数字,所需的平均值为 20,它弹出了 19 个平均值,最低值为 0,最高值为 84。所以它起作用了!这适用于 0 到 0.5 之间的 y,我可能只使用函数的这一部分,因为建议 y 介于 0.2 和 0.4 之间。谢谢大佬,大获成功!
【解决方案3】:

鉴于对于所描述的任何值 l、y、n,您称为 p1 和 p2 的术语都在 [0,1) 中,而 exp 在 [1,..) 中,因此 pow(p2, exp) 也在[0,1) 因此我不知道您如何获得范围为 [0,n) 的输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-11
    • 2012-06-06
    • 2018-04-10
    • 1970-01-01
    • 2012-11-21
    • 2019-08-21
    • 1970-01-01
    • 2019-04-19
    相关资源
    最近更新 更多