なんちゃってSEの日々

数学嫌い、論理的思考が苦手なのにSE?の生き延びている生態

「array_rand」な宿題。

2006年09月17日 | 本業
とりあえず。インストールだけ終わったので、
ヨガにでかけて、VOICEを3コマうける(今日は池袋西口校)。

で、まぁせっかくインストールしたので何かしないと
あほやんなーと思いつつ、ちょっと宿題を思い出す。

宿題のほう、先考えてみようか。


/**
* hogeさんのお店では、5人の女の子がいます。
* それぞれランクがあって、ランク高い女の子ほど、よく登場します。
* そのランクは1から5までで設定されています。
* さて、ちゃんとランクに応じた女の子を登場させることができるでしょうか。
*
* 5段階評価
* weight = 5, 4, 3, 2, 1
**/


ほんでもって、考えた実装方法


/**
* 乱数発生させ乱数の剰余算で決定する
*
* 2の剰余算→結果が0となるのは50%の確率
* 2.5の剰余算で→結果が0となるのは40%の確率
* 3.33の剰余算で→結果が0となるのは30%の確率
* 5の剰余算で→結果が0となりのは20%の確率
* 10の剰余算で→結果が0となるのは10%の確率
**/


しかし、色々問題がありまして。
「乱数・・・何の法則性もない数字の羅列」を生み出すのは不可能なんですな。
コンピュータ内部では、何らかの公式によってこの数は導きだされているんでせう。

結局40ステップくらいになってしまった・・。
なんか、もっと他のアプローチが知りたい今日この頃。

作った関数はこんな感じ。
<code>
        function rand_array_weight($hoge)
        {
                $ret_val = "";
                $aryRetval = array();

                foreach($hoge as $key => $val)
                {
                        if($ret_val != ""){break;}

                        $name = $val["name"];
                        $weight = $val["weight"];

                        $rand_val = rand();

                        switch($weight)
                        {
                                case "1":
                                        if($rand_val % 10 == 0 ){ array_push($aryRetval, $val["name"]); }
                                        break;
                                case "2":
                                        if($rand_val % 5 == 0 ){ array_push($aryRetval, $val["name"]); }
                                        break;
                                case "3":
                                        if($rand_val % 3.33 == 0 ){ array_push($aryRetval, $val["name"]); }
                                        break;
                                case "4":
                                        if($rand_val % 2.5 == 0 ){ array_push($aryRetval, $val["name"]); }
                                        break;
                                case "5":
                                        if($rand_val % 2 == 0 ){ array_push($aryRetval, $val["name"]); }
                                        break;
                        }// end switch
                } //end for

                //すべての評価終了後にどの子をだすか、結局乱数で判定。むぅ。
                if(count($aryRetval > 0))
                {
                        $randval = rand();
                        $idx = $randval%count($aryRetval);
                        $ret_val = $aryRetval[$idx];
                }

                //あてはまらない場合は再帰しちゃうの;むぅ。
                if($ret_val == ""){$ret_val = rand_array_weight($hoge);}

                return $ret_val;

        } //end func
</code>


すべてのデータを評価したうえで、再度乱数発生に頼ってしまっている。
そして、どの剰余算にも引っかからない数の場合に、returnが空になってしまうので、再度評価しなおしをしている。
うーむ、ムダかなぁ・・・。

また、結局、case1・2・4・5に引っかかるような最大公約数の数がでることもままあるんです。だから、結果を配列にほりこんでいます。

で、デバックしてみる。
<code>
        $hoge = array( "A" => array("name" => "Asuka", "weight" => "5"),
               "B" => array("name" => "Bekey", "weight" => "4"),
               "C" => array("name" => "Carol", "weight" => "3"),
               "D" => array("name" => "Diana", "weight" => "2"),
               "E" => array("name" => "Edy", "weight" => "1"),
             );

        $hyouji = rand_array_weight($hoge);
        //print $hyouji;

        //DEBUG STRAT
        if($debug)
        {
                $cntLoop = 100;
                for($i=0; $i<$cntLoop; $i++)
{ $hyouji = rand_array_weight($hoge); //print $hyouji ."n"; if($hyouji == "Asuka"){ $cntA++; } if($hyouji == "Bekey"){ $cntB++; } if($hyouji == "Carol"){ $cntC++; } if($hyouji == "Diana"){ $cntD++; } if($hyouji == "Edy") { $cntE++; } } print "#### RESULT ####n"; print "Asuka ".$cntA." :". ($cntA / $cntLoop * 100)."% n"; print "Bekey ".$cntB." :". ($cntB / $cntLoop * 100)."% n"; print "Carol ".$cntC." :". ($cntC / $cntLoop * 100)."% n"; print "Diana ".$cntD." :". ($cntD / $cntLoop * 100)."% n"; print "Edy ".$cntE." :". ($cntE / $cntLoop * 100)."% n"; print "------------------n"; print "Total ".($cntA + $cntB + $cntC + $cntD + $cntE) ."n"; } //DEBUG END </code>


結果は、そこそこ安定しているような。

[ashibuya@homeserv htdocs]$ php ./rand_php.php
#### RESULT ####
Asuka 32 :32%
Bekey 31 :31%
Carol 20 :20%
Diana 14 :14%
Edy 3 :3%
------------------
Total 100
[ashibuya@homeserv htdocs]$ php ./rand_php.php
#### RESULT ####
Asuka 25 :25%
Bekey 33 :33%
Carol 23 :23%
Diana 10 :10%
Edy 9 :9%
------------------
Total 100
[ashibuya@homeserv htdocs]$ php ./rand_php.php
#### RESULT ####
Asuka 31 :31%
Bekey 35 :35%
Carol 16 :16%
Diana 14 :14%
Edy 4 :4%
------------------
Total 100
[ashibuya@homeserv htdocs]$ php ./rand_php.php
#### RESULT ####
Asuka 34 :34%
Bekey 37 :37%
Carol 15 :15%
Diana 11 :11%
Edy 3 :3%
------------------
Total 100

んー。

論理的思考は苦手です。
ふたたび、今日も睡眠不足です。夜があけちゃうよ。
んー。だから3連休なんだってば;;

他にいい方法教えてください。

最新の画像もっと見る

6 コメント

コメント日が  古い順  |   新しい順
まあ~ (テリー)
2006-09-17 13:33:18
すごいですね~! さっぱり分からないですけど~(^^;)
乱数 (katsu)
2006-09-17 13:55:12
乱数は、乱数にあらず。コンピュータの基本です。

乱数の初期値を自分で入力するようにすると、

新たな乱数が発生できるので、例えば、内蔵の時刻の変数を

初期値にしておくのが便利です。



私は、乱数で重み漬けをするときは、

その乱数に、実際の重みをかけて使っています。

例えば、0-100の乱数を出して、30以下ならTrueの

ような。ちょっと、議論がずれてますが、参考にならないかな?

おっと、レギュラーレッスンに行かなければ。
うまくいってないなぁ (ぼへぼへ)
2006-09-18 01:35:22
>テリーさん

いやーこれが、この業界では下っ端レベルなんです。

多分、私はNOVAでいうところのレベル6くらい。



>katsuさん

いやーkatsuさんのレス期待していましたw

これはphpで組んでいるのですが、phpのrand関数は、

内蔵の時刻の変数の初期化も同時にしてくれるみたいなんですね。



>例えば、0-100の乱数を出して、30以下ならTrueのような。



そうですね。それも考えました。

しかし、乱数は乱数にあらず。悩ましい・・・

きっと会社のレベル2プログラマー達が、週明けには

彼らのすばらしい作品を披露してくれると思われます。

私はとりあえず、自分の鍛錬のためにやっただけ?

でしょうか・・・。

興味が大切 (katsu)
2006-09-18 04:59:43
自分の鍛錬、大切です。

レベル2プログラマーに教えてもらうだけでなく、

自分で苦労してみた後に話しを聞くのが良いですよね。

すばらしい。頑張ってね。
コノハッソウハナカッタワ (q-zou)
2006-09-24 01:21:02
こーゆーのもあるのかー。



3秒で思いついたのはひとつ配列の階層を増やす方法とランダムにしちゃわない方法。



前者は以下のようなのを作ってarray_randして結果を取得。

A1=>元の配列 A2=>・・・・A5=>

B1=>・・・・B4=>

・・・馬鹿っぽいかつ遅そう。_。



後者はどこか静的な場所にカウンタを置いて順番に出しちゃう。

企画の言うランダムと技術の言うランダムって違うと思うんだよね。

楽しようぜー
意識の違いってあるよね (ぼへぼへ)
2006-10-29 23:59:46
>q-zouさん



>企画の言うランダムと技術の言うランダムって違うと思うんだよね。



なんだか、そうなんですねー。

技術で、あつまって、すっげーかっちょえーというものを作ったとしても、

企画や客に受けなかったり、

求められていなかったり、



ということはありますねー。

でも、頭ひねって、色々と実装方法を考えて

トライしている時間が一番楽しいですにゃ。