我有一个简单的PHP代码,可以从数组重定向到随机uri。 然而,过了一段时间后,我注意到它的负载平衡不均匀。 有人可以建议调整,以便在链接之间均匀重定向吗?
<?php
$urls = array('https://a.com',
'http://b.com',
'http://c.com',
'http://d.com',
'https://e.com',
'https://f.com'
);
shuffle($urls);
header('Location: ' . $urls[0]);
exit();
?>
由于
答案 0 :(得分:2)
均匀随意地是矛盾的。但是您可以使用堆栈而不是数组来限制随机性。缺点是你需要在脚本调用之间存储。例如:
std::cin >> count
std::vector<std::wstring> wstrArray(count);
for (int i = 0; i < count; i++)
{
// some logic to create different wstring on each iteration
wstrArray[i] = L"somerandomstuff";
}
std::vector<LPWSTR> lpwstrArray(count);
for (int i = 0; i < count; i++)
lpwstrArray[i] = const_cast<wchar_t*>(wstrArray[i].c_str());
// use lpwstrArray as needed. if you need to pass it where an
// LPWSTR* is expected, you can use &lpwstrArray[0] for that...
// lpwstrArray and wstrArray will be freed automatically
// when they go out of scope...
其中storeStack()和readStack()函数用于存储和检索来自持久存储的堆栈状态。这可以通过文件系统存储,数据库访问或内存缓存机制完成,......无论您掌握什么,并且应用程序的速度都足够快。以下是文件系统和序列化的基本示例:
<?php
$urls=readStack();
if(empty($urls)) {
$urls = shuffle(array('https://a.com',
'http://b.com',
'http://c.com',
'http://d.com',
'https://e.com',
'https://f.com'
));
$url=array_pop($urls);
storeStack($urls);
header('Location: ' . $url);
答案 1 :(得分:0)
问题:shuffle()
内部使用与rand()
相同的随机数生成器,它是有偏见的,可预测的,并且有一小组可能的序列(约2 ^ 32,如果我没记错的话。)
有两种方法可以解决这个问题:
Persist some information across requests保证分配均匀(这是Guillaume的回答)。
使用无偏的随机数生成器,例如random_int()
(PHP 7,虽然(currently experimental) polyfill for 5.x正在运行中),这将在总体上产生均匀的结果分布。< / p>
对于小样本量,解决方案#1可能是您想要的。超过数百万的请求,都应该解决问题。
如果您喜欢冒险,可以将两者结合起来。
/**
* An implementation of shuffle() that uses a CSPRNG to select indices
*
* @param reference $array (pass a reference to an array)
*/
function unbiased_shuffle(&$array)
{
$size = count($array);
for ($i = $size - 1; $i > 0; --$i) {
$r = random_int(0, $i);
if ($r !== $i) {
$temp = $array[$r];
$array[$r] = $array[$i];
$array[$i] = $temp;
}
}
// Reset indices:
$array = array_values($array);
}
答案 2 :(得分:-1)
更改%// 1+2+3+4+5 = 15
%// 4+5+6+7+8 = 30
%// 7+8+9+10+11 = 45
%// 10+11+12+13+14 = 60
行以选择随机索引:
header