// *near* 50:50 chance of "Heads" vs. "Tails"
integer coin_toss()
{
if (llFrand(1.0) < 0.5) return TRUE;
return FALSE;
}
// 有时在给定的范围内得到一个随机整数是有用的。这是一个令人惊讶的棘手和情绪化的话题,并引起了无休止的讨论关于脚本编制组。在使用llFrand时,概率错误的主要原因是在范围的边缘有一个不同的箱子大小。
//
// 正如括号符号所示,[0.0,mag),该函数包含0.0,不包含输入的值。因为LSL浮点数只是实数的一个子集,并且没有无限的粒度,所以这个模式适用于任何大于float t = 1.175494351e-38的浮点数;在这个值上,函数将只返回0。当浮点数超过这个值时,就会出现数学错误。
// Random integer generator:
// Contributed by Mephistopheles Thalheimer,
// original function posted by Hg Beeks
// 返回一个最小到最大范围内的伪随机整数。
// 基本原理:
// 将范围扩展1.0,以确保两端相对于范围中部的间距相等,然后使用整数强制转换向零进行四舍五入。
// 注意:
// 此函数未检查范围,如果最大值<最小值,则会失败
integer random_integer(integer min, integer max)
{
return min + (integer)(llFrand(max - min + 1));
}
say(string message)
{
llSay(0, message);
}
default
{
touch_start(integer total_number)
{
// *near* 50:50 chance of "Heads" vs. "Tails"
if (coin_toss()) say("Heads");
else say("Tails");
integer n1 = random_integer(2, 8); // Return a random number between 2 and 8
say("I chose a " + (string)n1);
}
}
// 生成具有大于1600万可能值的均匀分布整数的例子;特别是,这段代码将生成500,000,000个可能的值,范围从0到499,999,999(包括499,999,999)。
//
// 该方法不针对大于16,777,216(2^24)的数使用llFrand(),而是使用(integer)llFrand(a)*b + (integer)llFrand(b)的格式将该范围划分为两个都小于该值的数,其中a*b给出了所需的范围。
//
// 对于质数范围,或者质数因子大于2^24的范围,应该使用拒绝方案(使用此方法生成略高于目标范围的数字,并拒绝它,如果它超过最大值,则生成一个新的数字)。
default
{
state_entry()
{
integer rand = (integer)llFrand(500)*1000000 + (integer)llFrand(1000000);
llOwnerSay("Here's a random number between 0 and 499,999,999 inclusive: " + (string)rand);
}
}
下面的代码为随机负整数提供了最大的可能性(例如,适合用作通道号)
integer rand = 0x80000000 | (integer)llFrand(65536) | ((integer)llFrand(65536) << 16);
// Simple integer random number tester
// Contributed by Mephistopheles Thalheimer
// 这是一个随机数测试器,旨在快速直观地解释和证明为什么一些随机整数函数不起作用。一般来说,对于任何随机数生成器,如果你能看到一个模式出现,那么很有可能,这个函数不是随机的。
// 给出的测试用例“silly_random_integer(..)”显示可能发生的陷阱类型。从表面上看,它似乎是一个不错的候选人。我认为是这样的,事实上在讨论中也提出过这个问题,但是,稍微考虑一下就会发现,第一个和最后一个bin只从浮动空间的一半收集四舍五入的结果,其余的是整数。因此,y在输出中表示不足,并且发生器有缺陷。
integer random_integer(integer min, integer max)
{
return min + (integer)llFrand(max - min + 1);
}
integer silly_random_integer(integer min, integer max)
{
return min + (integer)(llRound(llFrand(max - min))); // Looks good, but does not work
}
say(string message)
{
llSay(0, message);
}
// Simple integer random number tester
// Contributed by Mephistopheles Thalheimer
list bins;
integer MIN = 2; // The minimum integer you want
integer MAX = 5; // The maximum integer you want
integer NUMBER_OF_TRIES = 10000; // The bigger the better.. but slower
default
{
state_entry()
{
say("Bin tester ready.");
bins = [];
}
touch_start(integer total_number)
{
say("Started, be patient");
integer i;
integer r;
integer range = MAX - MIN;
for (i = 0; i <= range; ++i)
{
bins += [ 0 ];
}
integer v;
integer out_of_range;
for (i = 0; i < NUMBER_OF_TRIES; ++i)
{
// Replace the next line with the function you are testing
r = silly_random_integer(MIN, MAX);
// Note the output on the next line has about 0.5 expected hits on the first and last bin
// r = random_integer(MIN, MAX);
if (r > MAX || r < MIN)
{
out_of_range++;
}
else
{
v = llList2Integer(bins, r - MIN);
bins = llListReplaceList(bins, [++v], r - MIN, r - MIN);
}
}
for (i = 0; i <= range; ++i)
{
say("Bin #" + (string)(i + MIN) + " = " + (string)llList2Integer(bins, i));
}
say("Number out of range = " + (string)out_of_range);
}
}
//指数分布
//
// Contributed by Pat Perth on October 5th 2013
// No rights reserved
//
// 返回一个期望值为mean_value的指数分布随机数
//
// Reference: Wikipedia article "Exponential distribution", in particular the section
// entitled "Generating exponential variates" at
//
// http://en.wikipedia.org/wiki/Exponential_distribution (visited on October 5th 2013)
//
// 指数分布通常是模拟等待时间的一种合适方法类似于“x秒后< >发生”。例如,如果您想“大约每7天”触发一次阵雨,使用time_between_rain = random_exponent (7.0 * 24.0 * 60.0 * 60.0);在llSleep(…)或llSetTimerEvent(…)调用中。
//
// 请注意返回值中的负号
float random_exponential(float mean_value)
{
return -mean_value * llLog(llFrand(1.0));
}
|