论文中的概率密度函数,使用 C++ 实现,未按预期工作
所以我正在实现一个启发式算法,并且我遇到了这个函数。
我有一个 1 到 n 的数组(C 上的 0 到 n-1,w/e)。我想选择一些要复制到另一个数组的元素。给定参数 y (0 < y <= 1),我希望得到平均值为 (y * n) 的数字分布。这意味着每当我调用这个函数时,它都会给我一个介于 0 和 n 之间的数字,这些数字的平均值是 y*n。
根据作者的说法,“l”是一个随机数:0 << l <名词在我的测试代码中,它当前生成 0 <= l <= n。我有正确的代码,但我已经搞乱了几个小时了,而且我懒得把它编码回来。
所以我编写了函数的第一部分,对于 y <= 0.5 我将 y 设置为 0.2,n 设置为 100。这意味着它必须返回 0 到 99 之间的数字,平均为 20。 而且结果不是在 0 到 n 之间,而是一些浮点数。 n 越大,这个浮点数就越小。
这是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:cunning ant system”。
那么我做错了什么?我不认为作者是错的,因为有超过 5 篇论文描述了这个相同的功能。
我所有的互联网给任何帮助我的人。这对我的工作很重要。
谢谢 :)
So i'm implementing a heuristic algorithm, and i've come across this function.
I have an array of 1 to n (0 to n-1 on C, w/e). I want to choose a number of elements i'll copy to another array. Given a parameter y, (0 < y <= 1), i want to have a distribution of numbers whose average is (y * n). That means that whenever i call this function, it gives me a number, between 0 and n, and the average of these numbers is y*n.
According to the author, "l" is a random number: 0 < l < n . On my test code its currently generating 0 <= l <= n. And i had the right code, but i'm messing with this for hours now, and i'm lazy to code it back.
So i coded the first part of the function, for y <= 0.5
I set y to 0.2, and n to 100. That means it had to return a number between 0 and 99, with average 20.
And the results aren't between 0 and n, but some floats. And the bigger n is, smaller this float is.
This is the C test code. "x" is the "l" parameter.
//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);
}
And here are some results (5 decimals truncated):
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
The article is:
http://www.scribd.com/doc/3097936/cAS-The-Cunning-Ant-System
pages 6 and 7.
or search "cAS: cunning ant system" on google.
So what am i doing wrong? i don't believe the author is wrong, because there are more than 5 papers describing this same function.
all my internets to whoever helps me. This is important to my work.
Thanks :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能会误解对您的期望。
给定一个(适当归一化的)PDF,并且想要抛出与其一致的随机分布,您可以通过积分 PDF 来形成累积概率分布 (CDF),然后反转 CDF,并使用均匀随机谓词作为反转的参数功能。
更详细一点。
f_s(l)
是 PDF,并已在[0,n)
上标准化。现在您将其积分以形成 CDF
请注意,这是对未指定端点的定积分,我将其称为
l'
。因此CDF是l'
的函数。假设我们有正确的标准化,g_s(N) = 1.0
。如果不是这样,我们应用一个简单的系数来修复它。接下来反转 CDF 并调用结果
G^{-1}(x)
。为此,您可能需要选择特定的伽玛值。然后在
[0,n)
上抛出统一随机数,并将它们用作G^{-1}
的参数x
。结果应位于[0,1)
之间,并应根据f_s
分布。就像贾斯汀说的,你可以使用计算机代数系统来进行数学计算。
You may misunderstand what is expected of you.
Given a (properly normalized) PDF, and wanting to throw a random distribution consistent with it, you form the Cumulative Probability Distribution (CDF) by integrating the PDF, then invert the CDF, and use a uniform random predicate as the argument of the inverted function.
A little more detail.
f_s(l)
is the PDF, and has been normalized on[0,n)
.Now you integrate it to form the CDF
Note that this is a definite integral to an unspecified endpoint which I have called
l'
. The CDF is accordingly a function ofl'
. Assuming we have the normalization right,g_s(N) = 1.0
. If this is not so we apply a simple coefficient to fix it.Next invert the CDF and call the result
G^{-1}(x)
. For this you'll probably want to choose a particular value of gamma.Then throw uniform random number on
[0,n)
, and use those as the argument,x
, toG^{-1}
. The result should lie between[0,1)
, and should be distributed according tof_s
.Like Justin said, you can use a computer algebra system for the math.
dmckee 实际上是正确的,但我想我应该详细说明一下,并尝试解释这里的一些混乱。我肯定会失败。
f_s(l)
,上面漂亮公式中的函数,是概率分布函数。它告诉您,对于 0 到 n 之间的给定输入l
,l
是段长度的概率。 0 到 n 之间所有值的总和(积分)应等于 1。第 7 页顶部的图表混淆了这一点。它绘制了
l
与f_s(l)
的关系图,但您必须注意它放在一边的杂散因素。您注意到底部的值从 0 到 1,但侧面有一个x n
因子,这意味着l
值实际上从 0 到名词另外,y 轴上有一个x 1/n
,这意味着这些值实际上不会达到 3 左右,而是达到 3/n。那你现在做什么?好吧,您需要通过在
l
上积分概率分布函数来求解累积分布函数,这实际上证明并不太糟糕(我通过使用 x 来使用 Wolfram Mathematica Online Integrator 来实现< code>l 并仅使用 y <= .5 的方程)。然而,这是使用不定积分,并且您实际上是沿着 x 从 0 到 l 进行积分。如果我们将所得方程设置为等于某个变量(例如 z),那么现在的目标是求解作为 z 函数的l
。 z 这里是 0 到 1 之间的随机数。如果您愿意(我愿意),您可以尝试在这部分使用符号求解器。那么您不仅实现了能够从该分布中随机选择l
的目标,而且还实现了涅槃。完成更多工作
我会提供更多帮助。我尝试按照我所说的 y <= .5 进行操作,但是我使用的符号代数系统无法进行反转(其他一些系统可能可以)。然而,后来我决定尝试使用 0.5 < 的方程。 y <= 1。事实证明这要容易得多。如果我将
f_s(l)
中的l
更改为 x,我得到Integrating this over x from 0 to
l
我得到(使用 Mathematica 的在线积分器) :对于这种事情来说,没有比这更好的了。如果我将其设置为等于 z 并求解
l
,我会得到:一次快速检查是 y = 1。在这种情况下,无论 z 是什么,我们都会得到
l = n
是。到目前为止,一切都很好。现在,您只需生成 z(0 到 1 之间的随机数),就会得到一个l
,它按照您的需要进行分布,即 0.5l
。 y <= 1。但是等等,查看第 7 页的图表,您会注意到概率分布函数是对称的。这意味着我们可以使用上面的结果来找到 0 << 的值。 y <= .5。我们只需更改l
->nl
和y
->1-y
并得到无论如何,这应该可以解决你的问题,除非我在某个地方犯了一些错误。祝你好运。
dmckee is actually correct, but I thought that I would elaborate more and try to explain away some of the confusion here. I could definitely fail.
f_s(l)
, the function you have in your pretty formula above, is the probability distribution function. It tells you, for a given inputl
between 0 and n, the probability thatl
is the segment length. The sum (integral) for all values between 0 and n should be equal to 1.The graph at the top of page 7 confuses this point. It plots
l
vs.f_s(l)
, but you have to watch out for the stray factors it puts on the side. You notice that the values on the bottom go from 0 to 1, but there is a factor ofx n
on the side, which means that thel
values actually go from 0 to n. Also, on the y-axis there is ax 1/n
which means these values don't actually go up to about 3, they go to 3/n.So what do you do now? Well, you need to solve for the cumulative distribution function by integrating the probability distribution function over
l
which actually turns out to be not too bad (I did it with the Wolfram Mathematica Online Integrator by using x forl
and using only the equation for y <= .5). That however was using an indefinite integral and you are really integration along x from 0 tol
. If we set the resulting equation equal to some variable (z for instance), the goal now is to solve forl
as a function of z. z here is a random number between 0 and 1. You can try using a symbolic solver for this part if you would like (I would). Then you have not only achieved your goal of being able to pick randoml
s from this distribution, you have also achieved nirvana.A little more work done
I'll help a little bit more. I tried doing what I said about for y <= .5, but the symbolic algebra system I was using wasn't able to do the inversion (some other system might be able to). However, then I decided to try using the equation for .5 < y <= 1. This turns out to be much easier. If I change
l
to x inf_s(l)
I getIntegrating this over x from 0 to
l
I got (using Mathematica's Online Integrator):It doesn't get much nicer than that with this sort of thing. If I set this equal to z and solve for
l
I get:One quick check is for y = 1. In this case, we get
l = n
no matter what z is. So far so good. Now, you just generate z (a random number between 0 and 1) and you get anl
that is distributed as you desired for .5 < y <= 1. But wait, looking at the graph on page 7 you notice that the probability distribution function is symmetric. That means that we can use the above result to find the value for 0 < y <= .5. We just changel
->n-l
andy
->1-y
and getAnyway, that should solve your problem unless I made some error somewhere. Good luck.
鉴于对于所描述的任何值 l、y、n,您称为 p1 和 p2 的术语都在 [0,1) 中,而 exp 在 [1,..) 中,使得 pow(p2, exp) 也在 [0,1) 中1)因此我不明白你如何获得范围为 [0,n) 的输出
Given that for any values l, y, n as described, the terms you call p1 and p2 are both in [0,1) and exp is in [1,..) making pow(p2, exp) also in [0,1) thus I don't see how you'd ever get an output with the range [0,n)