LoginSignup
5
6

More than 5 years have passed since last update.

値をランダムに分配するにはどうすればいいのか

Last updated at Posted at 2015-07-02

ある値をn個に分割する方法がわからない。
多分、数学を学んでいると一発でわかるんだろうなぁ。
書いてみたけど果てしなく不安。

コード

distribute.php

$target = array(
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
);

$target_cnt = count($target);
$total = 123456789;
echo $total . "\n";
$result = array_fill(0, $target_cnt, 0);
$i = 0;

while ($total) {
    if (!($i %= $target_cnt)) {
        shuffle($result);
    }
    $rand = mt_rand(0, $total);
    $result[$i] += $rand;
    $total -= $rand;
    $i++;
}

var_dump(array_combine($target, $result));
echo $total . "\n";
echo array_sum($result) . "\n";

値が加算される順番はランダムだけど、回数は(途中で終わらない限り)等しい、としてみたけど意味はあるのかしらん。
順番固定だと後半が少なくなりそうだし、毎回ランダムで一つに加算だと偏りが出そう。
平均的にしようとしている時点でランダムでない?

出力

output
123456789
array(8) {
  ["A"]=>
  int(95557576)
  ["B"]=>
  int(313427)
  ["C"]=>
  int(2720550)
  ["D"]=>
  int(448420)
  ["E"]=>
  int(3296615)
  ["F"]=>
  int(73736)
  ["G"]=>
  int(172534)
  ["H"]=>
  int(20873931)
}
0
123456789

ゲームなどで余剰分をオートで振り分ける機能や、敵CPUのランダムな行動力割り当て、部隊分割とかをぼや~と考えていた。
これ自体の使い道はあるんですかね?
実際のゲームはもっと最適な行動をランダムに行うんですよね。
すごいなぁ。

:one: 追記1

やっぱり後半ほどランダム値がとる値の範囲が狭まるのはおかしい気がしてきた。
だから、1ループで加算される最大値を均等にしてみた。

distribute2.php

$target = array(
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
);

$target_cnt = count($target);
$total = 123456789;
echo $total . "\n";
$result = array_fill(0, $target_cnt, 0);
$remainder = 0; // IDE警告消し
while ($total) {

    $remainder = $total % $target_cnt;
    $quotient = (int)($total / $target_cnt);
    if ($quotient == 0) {
        break;
    }

    for ($i = 0; $i < $target_cnt; $i++) {
        $rand = mt_rand(0, $quotient);
        $result[$i] += $rand;
        $total -= $rand;
    }
}

// 余りの分配
$total -= $remainder;
$i = 0;
while ($remainder--) {
    $i %= $target_cnt;
    $result[$i++]++;
}

var_dump(array_combine($target, $result));
echo $total . "\n";
echo array_sum($result) . "\n";

output2

123456789
array(8) {
  ["A"]=>
  int(11087871)
  ["B"]=>
  int(13496825)
  ["C"]=>
  int(15902076)
  ["D"]=>
  int(17920329)
  ["E"]=>
  int(17281928)
  ["F"]=>
  int(21869953)
  ["G"]=>
  int(13350973)
  ["H"]=>
  int(12546834)
}
0
123456789

最初より値が均等ぎみになった気がする。
でも均等にすることが主目的ではないし…
逆に極端な値が出ないって欠点でもあるのかもしれない。
ランダムってなんだ(無知)

5
6
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6