【问题标题】:Partial randomization of php arrayphp数组的部分随机化
【发布时间】:2012-11-24 10:53:35
【问题描述】:

我希望有人可以帮助我解决这个问题。我想采用一个有序的 php 数组并随机“摇晃”它一点点以更改顺序但保留一些原始的整体结构。

想象一下,你有一盘彩色亮片,组成了一幅房子的照片。如果你稍微晃动托盘,亮片就会移动,但是,根据你晃动的程度,你仍然会保留一些房子的原始结构——它会更模糊。这就是我想用 php 数组做的事情。

让我举个例子。假设我有以下数组:

$Array=Array(
  1=>15,
  2=>14,
  3=>13,
  4=>12,
  5=>11,
  6=>10,
  7=>9,
  8=>8,
  9=>7,
  10=>6,
  11=>5,
  12=>4,
  13=>3,
  14=>2,
  15=>1);

我希望能够稍微调整一下以提供如下内容:

$Array=Array(
  1=>13,
  2=>15,
  3=>12,
  4=>14,
  5=>11,
  6=>8,
  7=>7,
  8=>10,
  9=>5,
  10=>6,
  11=>9,
  12=>4,
  13=>2,
  14=>1,
  15=>3);

订单已部分随机化,但从 15 到 1 的总体下降趋势仍然存在。我希望这是有道理的。

除非我弄错了,否则我认为 php 中没有本机函数可以做到这一点。但是有谁知道这是如何实现的吗?

【问题讨论】:

  • 也许你可以用array_shufflearray_values做点什么

标签: php arrays sorting random


【解决方案1】:

您应该编写自己的算法,而不是使用像 shuffle()array_shuffle() 这样经过优化以获得尽可能多的结果的函数:

尝试“冒泡”策略:

  • 通过一对接着一对交换数组元素。
  • 始终从数组中选择相邻元素成对。
  • 随机化您为每个迭代步骤选择的现有配对。
  • 您可以限制迭代次数,从而限制结果的总“混洗”。

这应该比严格随机化更好地保留元素的粗略位置,因为元素在每次迭代期间只能移动一步。所以应该保留大势。多少取决于您执行的迭代次数。

这是一个(非常简单的)示例实现:

#!/usr/bin/php
<?php

// the input array, just as you specified it
$input=array(
  1=>15,
  2=>14,
  3=>13,
  4=>12,
  5=>11,
  6=>10,
  7=>9,
  8=>8,
  9=>7,
  10=>6,
  11=>5,
  12=>4,
  13=>3,
  14=>2,
  15=>1
);

// the algorithm itself, a 'bubbling' function
function array_bubble (&$collection, $limit) {
    for ($i=1; $i<=$limit; $i++) {
        $pos=rand(min(1,sizeof($collection)-1);
        $help=$collection[$pos];
        $collection[$pos]  =$collection[$pos+1];
        $collection[$pos+1]=$help;
    }
    return $collection;
} // function array_bubble

// here the algorithm is called and the result printed
// note that the '20' in there is the number of iterations. Try changing it!
print_r(array_bubble($input,20));

?>

该脚本产生如下输出:

Array
(
    [1] => 11
    [2] => 15
    [3] => 13
    [4] => 8
    [5] => 14
    [6] => 12
    [7] => 9
    [8] => 10
    [9] => 5
    [10] => 6
    [11] => 7
    [12] => 4
    [13] => 1
    [14] => 3
    [15] => 2
)

【讨论】:

  • 谢谢。看起来不错。我要试试这个。
  • 经过一些调整,我已经完全按照我的需要做了。谢谢你的时间。非常感谢。
  • 你喜欢分享,让别人也可以学习?你“调整”了什么?
【解决方案2】:

arkascha 提到的冒泡策略的替代方案,您可以遍历数组,并生成具有高斯/正态分布的随机数来交换当前元素。也许在代码中更好地描述(未经测试):

function swap (&$arr, $a, $b) {
    $tmp=$arr[$a];
    $arr[$a]=$arr[$b];
    $arr[$b]=$tmp; 
}
for ($i = 0; $i < count($arr); $i++) {
    $diff = round(stats_rand_gen_normal(0, 3));
    $j = max(0, min(count($arr), $i + $diff));
    swap($arr, $i, $j);
}

这应该只需要一次通过; jiggling 的均值和标准差应该大致是stats_rand_gen_normal 的参数。

【讨论】:

  • 聪明的方法。感谢您花时间回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
相关资源
最近更新 更多