在PHP中如何将数组从线性分布排序到正态分布?
假设有一个原始数组:在PHP中如何将数组从线性分布排序到正态分布?,php,sorting,Php,Sorting,假设有一个原始数组: $array[] = array('name' => 'a', 'code'=>1); $array[] = array('name' => 'b', 'code'=>2); $array[] = array('name' => 'c', 'code'=>3); $array[] = array('name' => 'd', 'code'=>4); $array[] = array('name' => 'e',
$array[] = array('name' => 'a', 'code'=>1);
$array[] = array('name' => 'b', 'code'=>2);
$array[] = array('name' => 'c', 'code'=>3);
$array[] = array('name' => 'd', 'code'=>4);
$array[] = array('name' => 'e', 'code'=>5);
$array[] = array('name' => 'f', 'code'=>6);
$array[] = array('name' => 'g', 'code'=>7);
$array[] = array('name' => 'h', 'code'=>8);
$array[] = array('name' => 'i', 'code'=>9);
它是按code
线性排序的,如何按code
将其排序为正态分布,如下所示:
$array[] = array('name' => 'a', 'code'=>1);
$array[] = array('name' => 'c', 'code'=>3);
$array[] = array('name' => 'e', 'code'=>5);
$array[] = array('name' => 'g', 'code'=>7);
$array[] = array('name' => 'i', 'code'=>9);
$array[] = array('name' => 'h', 'code'=>8);
$array[] = array('name' => 'f', 'code'=>6);
$array[] = array('name' => 'd', 'code'=>4);
$array[] = array('name' => 'b', 'code'=>2);
也许usort能帮上忙
更新 当我说正态分布时,我的意思是像下图一样,最大的数字在中间: 是否有一些
常用的
方法可以做到这一点?也许这次是“正态分布”,下次我要另一个排序规则?
是否有类似于
usort
的方法来处理它 这样就可以了。下面的代码将数组拆分为两个新数组。任何带有偶数的元素都将添加到一个数组中,并在数组的开头添加新元素。任何带有奇数的内容都将添加到另一个新数组的末尾。然后,您只需合并它们
$array = [];
$array[] = array('name' => 'a', 'code'=>1);
$array[] = array('name' => 'b', 'code'=>2);
$array[] = array('name' => 'c', 'code'=>3);
$array[] = array('name' => 'd', 'code'=>4);
$array[] = array('name' => 'e', 'code'=>5);
$array[] = array('name' => 'f', 'code'=>6);
$array[] = array('name' => 'g', 'code'=>7);
$array[] = array('name' => 'h', 'code'=>8);
$array[] = array('name' => 'i', 'code'=>9);
$array1 = [];
$array2 = [];
foreach ($array as $item) {
$element = array_shift($array);
if ($element['code'] % 2 == 0) {
array_unshift($array1, $element);
} else {
$array2[] = $element;
}
}
$array = array_merge($array2, $array1);
所需阵列可按如下方式在O(n)中构建:
$r = [];
for ($i = count($array) - 1; $i >= 0; --$i) {
if ($i % 2) {
$r []= $array[$i];
} else {
array_unshift($r, $array[$i]);
}
}
/**
* @param float $x the value
* @param float $mean Mean or expectation of the distribution (median)
* @param float $stddev Standard deviation
* @return float Probability density of the normal distribution
*/
function dens_normal($x, $mean, $stddev) {
$z = ($x - $mean) / $stddev;
return (1 / ($stddev * sqrt(2.0 * pi()))) * exp(-0.5 * $z * $z);
}
// Calculate the mean code value
$mean = 0;
foreach ($array as $e) { $mean += $e['code']; }
$mean /= count($array);
echo "mean = $mean\n";
// Standard deviation for the code value
$stddev = 1;
usort($array, function ($a, $b) use ($mean, $stddev) {
$da = dens_normal($a['code'], $mean, $stddev);
$db = dens_normal($b['code'], $mean, $stddev);
return $da == $db ? 0 : ($da < $db ? -1 : 1);
});
foreach ($array as $e) {
printf("%s: %d\n", $e['name'], $e['code']);
}
代码从末尾开始迭代数组项。奇数索引下的项目(当$i%2
为非零时)添加到$r
的末尾,偶数索引下的项目添加到数组的开头
它是按
code
进行线性排序的,如何按code
上面的代码将生成所需的数组,但项目不是按code
按正态分布排序的!为了按code
对真实正态分布中的项目进行排序,您需要计算正态分布的平均值,如下所示:
$r = [];
for ($i = count($array) - 1; $i >= 0; --$i) {
if ($i % 2) {
$r []= $array[$i];
} else {
array_unshift($r, $array[$i]);
}
}
/**
* @param float $x the value
* @param float $mean Mean or expectation of the distribution (median)
* @param float $stddev Standard deviation
* @return float Probability density of the normal distribution
*/
function dens_normal($x, $mean, $stddev) {
$z = ($x - $mean) / $stddev;
return (1 / ($stddev * sqrt(2.0 * pi()))) * exp(-0.5 * $z * $z);
}
// Calculate the mean code value
$mean = 0;
foreach ($array as $e) { $mean += $e['code']; }
$mean /= count($array);
echo "mean = $mean\n";
// Standard deviation for the code value
$stddev = 1;
usort($array, function ($a, $b) use ($mean, $stddev) {
$da = dens_normal($a['code'], $mean, $stddev);
$db = dens_normal($b['code'], $mean, $stddev);
return $da == $db ? 0 : ($da < $db ? -1 : 1);
});
foreach ($array as $e) {
printf("%s: %d\n", $e['name'], $e['code']);
}
与平均值(
5
)的差值越大,数组索引越低。换言之,数组是按平均值(5
)的“接近度”降序排列的。谢谢你指出我对正态分布的误解,看起来你的答案现在是最好的。但是如果有更新中描述的一些通用方法?