1

誰かがこれを手伝ってくれることを願っています。順序付けられた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にあるとは思いません。しかし、これをどのように達成できるか誰かが知っていますか?

4

2 に答える 2

6

shuffle()可能な限りシャッフルされた結果を取得するために最適化された、またはのような関数を使用する代わりにarray_shuffle()、独自のアルゴリズムを作成する必要があります。

「バブリング」戦略を試してみてください。

  • ペアを次々に交換することにより、配列の要素を交換します。
  • 常に配列から隣接する要素をペアとして選択します。
  • 反復ステップごとに選択する既存のペアをランダム化します。
  • 反復回数を制限して、結果の「シャッフルネス」の合計を制限できます。

これにより、要素は各反復中に1ステップしか移動できないため、厳密なランダム化よりも要素の大まかな位置が維持されます。したがって、一般的な傾向は維持されるべきです。どれだけ実行するかによって異なります。

(非常に単純な)実装例を次に示します。

#!/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
)
于 2012-11-24T11:00:25.623 に答える
1

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);
}

これには1回のパスのみが必要です。ジグリングの平均と標準偏差は、おおよそstats_rand_gen_normalのパラメータである必要があります。

于 2012-11-24T15:06:13.687 に答える