![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
PHP Version 5.1.6を使っています。
例えば
$arr = array(
'key1' => array('name' => 'あ', 'weight' => 1),
'key2' => array('name' => 'い', 'weight' => 1),
'key3' => array('name' => 'う', 'weight' => 3),
);
という連想配列があった時に、
weightの値によってランダムに選ばれる時の差をつけたいのですが、
具体的には、1が最も選ばれ易くて値が大きくなるにつれて選ばれ難くなるようにしたいです。
上の場合だと、key1とkey2が選ばれ易くてkey3は選ばれ難くなります。
逆(1が最も選ばれ難くて、値が大きくなるに連れて選ばれ易い)の場合は
なんとかプログラムで表すことができたのですが、
この場合はどのような感じになるのでしょうか?
No.3ベストアンサー
- 回答日時:
そんなときこそ颯爽とソースを晒してcoolに逃げるに限ります。
[改定前]
$arr = array(
"k1"=>array("value"=>"a","seed"=>1)
,"k2"=>array("value"=>"b","seed"=>2)
,"k3"=>array("value"=>"c","seed"=>3)
);
$arr_child = array();
$keys = array();
foreach($arr as $key => $values)
{
$arr_child[] = $values["seed"];
$keys[] = $key;
}
$sum=0;
foreach($arr_child as $kk => $vv)
$sum = $sum + $vv;
$r = mt_rand(0,$sum);
$ii = 0;
$seed = 0;
$p = 0;
while($r > $seed) {
$p = $ii;
$seed = $seed + $arr_child[$ii];
$ii++;
}
echo $arr[$keys[$p]]["value"];
[改定後]
$arr = array(
"k1"=>array("value"=>"a","seed"=>1)
,"k2"=>array("value"=>"b","seed"=>2)
,"k3"=>array("value"=>"c","seed"=>3)
);
$arr_child = array();
$keys = array();
foreach($arr as $key => $values)
{
$arr_child_tmp[] = $values["seed"];
$keys[] = $key;
}
$sum_tmp=0;
foreach($arr_child_tmp as $kk => $vv)
$sum_tmp = $sum_tmp + $vv;
foreach($arr_child_tmp as $num => $seed_tmp)
{
if($seed_tmp != 0)
$arr_child[] = $sum_tmp / $seed_tmp;
else
$arr_child[] = 0;
}
$sum = 0;
foreach($arr_child as $kk => $vv)
$sum = $sum + $vv;
$r = mt_rand(0,$sum);
$ii = 0;
$seed = 0;
$p = 0;
while($r > $seed) {
$p = $ii;
$seed = $seed + $arr_child[$ii];
$ii++;
}
echo $arr[$keys[$p]]["value"];
つまるところ、逆数の比にしてランダムすれば良いです。
// 仕事しろ俺
No.2
- 回答日時:
選ばれやすいというのは1は3の3倍選ばれやすいということでしょうか?
逆ができたなら1/weightみたいなことで調整できるのでは?
その逆というソースを例示してみてはどうでしょうか?
ご返答ありがとうございます。
yambejpさんにもANo.1のお礼のサンプルを参考にして(全く違うやり方でも)
考えてもらえないでしょうか?
No.1
- 回答日時:
>なんとかプログラムで表すことができたのですが、
そのソースを示した方が回答しやすいと思います。
ご返答ありがとうございます。
すいません、汚いプログラムだったので自分的にはあまり表示したくなかったのですが、
これが逆(1が最も選ばれ難くて、値が大きくなるほど選ばれ易い)のプログラムです。
function random_choice($arr, $weight_key)
{
$cnt = 0;
$wk = array();
foreach ($arr as $key => $val){
if($cnt >= 1){
$wk['start'][$cnt] = $wk['end'][$cnt-1] + 1;
}else{
$wk['start'][$cnt] = 1;
}
$wk['end'][$cnt] = $wk['start'][$cnt] - 1 + $val[$weight_key];
$wk['key'][$cnt] = $key;
$cnt++;
}
//print_r($wk);
$max = count($arr);
$rr = rand($wk['start'][0], $wk['end'][$max-1]);
for ($j = 0; $j < $max; $j++){
if($wk['start'][$j] <= $rr && $rr <= $wk['end'][$j]){
$key = $wk['key'][$j];
break;
}
}
return $key;
}
$arr = array(
'key1' => array('name' => 'あ', 'weight' => 1),
'key2' => array('name' => 'い', 'weight' => 1),
'key3' => array('name' => 'う', 'weight' => 3),
);
$key = random_choice($arr, 'weight');
print "$key<br>\n";
これを(おそらく別のやり方かもしれませんが)どう改造すれば
1が最も選ばれ易くて、値が大きくなるほど選ばれ難くすることができるのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP PHPで画像の渡しが上手く行きません。 1 2023/02/02 09:39
- JavaScript java keyを配列で表記したい 10 2022/12/01 17:53
- JavaScript 電車の運賃を出すプログラムを作っています。 2 2022/06/22 09:36
- Java Java 南京錠 2 2023/02/04 11:46
- JavaScript sessionStorageを調べています。 1 2023/06/20 12:41
- PHP PHPのエラーの解消法について教えて下さい。 1 2023/02/06 10:48
- Visual Basic(VBA) エクセルVBAについて 8 2022/07/13 22:41
- JavaScript Json のキーと値の出力の違いについて 2 2022/06/14 20:22
- JavaScript 2段階プルダウンで1段階目の選択を終えた後に選択ボックスを見えなくしたい 2 2022/07/05 21:58
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
マッチング処理(1:N)
-
配列から順位を算出したい
-
PHPで連想配列のプルダウンメニ...
-
Excel VBAでフィルター後の対象...
-
PHPからCSVをアップロード後、m...
-
配列を回すとき、最後の要素だ...
-
配列の添え字が小数だとどうなる?
-
CSVデータの行数カウントをした...
-
別ファイルの構造体の値を読み...
-
配列の初期化
-
順位を付ける時のスコアの重複...
-
file_existsでファイル名の部分...
-
CSVファイルの最終行のデー...
-
foreachのなかで次のキーを参照...
-
チェックボックス複数選択 mys...
-
漢字のソートについて
-
配列の要素(value)に、変数を...
-
String だと「 ByRef引数の型が...
-
verilogで、配列の一部をタスク...
-
phpで、連想配列を普通の配列に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
重複確認
-
foreachで上限回数指定方法また...
-
マッチング処理(1:N)
-
Excel VBAでフィルター後の対象...
-
VB.NET で 二次元のハッシュは...
-
多次元配列を、1次元の配列にす...
-
SELECT 使用時の bindValue の...
-
Smartyでインクリメント
-
PHPでこのコード自体に意味は無...
-
PHP、{}記号の意味
-
配列を比較して同じものがあっ...
-
phpでforeachの中にforeachがあ...
-
多次元配列の中で条件に合う要...
-
sqlのデーターを『あ行』『か行...
-
ラジオボタンをランダムに表示...
-
キーが倍数の時の値の存在チェ...
-
三重県南部の温泉
-
foreachで配列を、左から縦3列...
-
ジャグ配列
-
構造体の中でユーザー定義型の...
おすすめ情報