なんちゃって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連休なんだってば;;

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