hfi*_*ler 6 c++ heuristics probability montecarlo ant-colony
所以我正在实现一个启发式算法,我遇到过这个功能.
我有一个1到n的数组(C,0到n-1,w/e).我想选择一些我将复制到另一个数组的元素.给定参数y,(0 <y <= 1),我希望得到平均值为(y*n)的数字分布.这意味着每当我调用此函数时,它会给出一个介于0和n之间的数字,这些数字的平均值为y*n.
根据作者,"l"是一个随机数:0 <l <n.在我的测试代码中,它当前生成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);
}
Run Code Online (Sandbox Code Playgroud)
这里有一些结果(截断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
Run Code Online (Sandbox Code Playgroud)
文章是:
http://www.scribd.com/doc/3097936/cAS-The-Cunning-Ant-System
第6页和第7页.
或者在谷歌上搜索"cAS:cunning ant system".
那我做错了什么?我不相信作者是错的,因为有超过5篇论文描述了这个相同的功能.
我帮助我的所有互联网.这对我的工作很重要.
谢谢 :)
您可能会误解对您的期望.
给定一个(正确标准化)PDF,并希望抛出与它一致的随机分布,您在PDF整合形成的累积概率分布(CDF),然后倒置的CDF,并使用统一的随机谓语倒的说法功能.
更多细节.
f_s(l)是PDF,并已标准化[0,n).
现在,您将其集成以形成CDF
g_s(l') = \int_0^{l'} dl f_s(l)
Run Code Online (Sandbox Code Playgroud)
请注意,这是我调用的未指定端点的一个明确的组成部分l'.因此CDF是一个功能l'.假设我们有正常化权利,g_s(N) = 1.0.如果不是这样,我们应用一个简单的系数来修复它.
接下来反转CDF并调用结果G^{-1}(x).为此,您可能希望选择特定的伽玛值.
然后打开统一的随机数[0,n),并使用那些作为参数x,to G^{-1}.结果应介于两者之间[0,1),并应按照分配f_s.
就像Justin说的那样,你可以使用计算机代数系统进行数学计算.
dmckee 实际上是正确的,但我想我应该详细说明一下,并尝试解释这里的一些混乱。我肯定会失败。f_s(l),上面漂亮公式中的函数是概率分布函数。它告诉您,对于 0 到 n 之间的给定输入,段长度的l概率。l0 到 n 之间所有值的总和(积分)应等于 1。
第 7 页顶部的图表混淆了这一点。它绘制了lvs. 的图f_s(l),但你必须留意它放在一边的杂散因素。您会注意到底部的值从 0 到 1,但x n侧面有一个因子 ,这意味着这些l值实际上是从 0 到 n。另外,y 轴上有一个x 1/n,这意味着这些值实际上不会达到 3 左右,而是达到 3/n。
那你现在做什么?好吧,您需要通过对概率分布函数进行积分来求解累积分布函数,l结果实际上结果还不错(我使用 Wolfram Mathematica Online Integrator 通过使用 xl并仅使用 y <= 的方程来完成此操作.5). 然而,这是使用不定积分,并且您实际上是沿着 x 从 0 到 进行积分l。如果我们将所得方程设置为等于某个变量(例如 z),那么现在的目标是求解lz 的函数。z 这里是 0 到 1 之间的随机数。如果您愿意(我愿意),您可以尝试在这部分使用符号求解器。那么你不仅实现了能够l从这个分布中选择随机 s 的目标,而且还实现了涅槃。
还完成了一些工作
我会多帮忙一点。我尝试按照我所说的 y <= .5 进行操作,但是我使用的符号代数系统无法进行反转(其他一些系统可能可以)。然而,后来我决定尝试使用 0.5 < y <= 1 的方程。事实证明这要容易得多。如果我更改l为 xf_s(l)我得到
y / n / (1 - y) * (x / n)^((2 * y - 1) / (1 - y))
Run Code Online (Sandbox Code Playgroud)
对 x 从 0 积分到l我得到(使用 Mathematica 的在线积分器):
(l / n)^(y / (1 - y))
Run Code Online (Sandbox Code Playgroud)
对于这种事情来说,没有比这更好的了。如果我将其设置为 z 并求解,l我会得到:
l = n * z^(1 / y - 1) for .5 < y <= 1
Run Code Online (Sandbox Code Playgroud)
快速检查一下 y = 1。在这种情况下,l = n无论 z 是什么,我们都会得到。到目前为止,一切都很好。现在,您只需生成 z(0 到 1 之间的随机数),您就会得到一个l按照您的期望分布的 0.5 < y <= 1。但是等等,查看第 7 页上的图表,您会注意到概率分布函数是对称的。这意味着我们可以使用上面的结果来找到 0 < y <= .5 的值。我们只需更改l->n-l和y->1-y即可得到
n - l = n * z^(1 / (1 - y) - 1)
l = n * (1 - z^(1 / (1 - y) - 1)) for 0 < y <= .5
Run Code Online (Sandbox Code Playgroud)
不管怎样,这应该可以解决你的问题,除非我在某个地方犯了一些错误。祝你好运。