乱数の信憑性

                             <p>ソースコード</p>
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/perl

#BEGIN{
#   print "Content-type: text/plainnn";
#   open(STDERR, ">&amp;STDOUT");
#   $|=1;
#}

$usr_title = 'テスト31';

require "tsenv.pl";
$G_image = "/x/nobu3/images/blue1.gif";

{
    printHeader($usr_title);
    printBodyHeader('<font face=times>Random Test</font>');

    srand(time()^($$+($$<<15)));

    randomTest(10, 2**4);
    randomTest(10, 2**8);
    randomTest(10, 2**12);

    printFooter();

    exit(0);
}

sub randomTest{
    my($len, $loopTimes) = @_;
    my @value = (); # 発生値格納用
    my @near = ();  # 発生値差格納用
    my $winH = 150; # 縦棒グラフの最大高さ
    my $eleW = 40;  # 縦棒グラフの各棒の幅
    my $winW = 400; # 横棒グラフの最大長さ
    my $eleH = 20;  # 横棒グラフの各棒の幅

# 配列初期化(無くても動くけど・・・)
    for($i=0;$i<$len;$i++){
        $value[$i] = 0;
        $near[$i]->[0] = 0;
    }

# 移動値用(上に同じ)
#   for($i=$len;$i<$len*2-1;$i++){
#       $near[$i]->[0] = 0;
#   }

# 乱数発生
# 1回目例外処理
    my $lst = int(rand(scalar(@value))); # 発生値比較用
    $value[$lst]++;
# 2回目以降処理
    for($i=1;$i<$loopTimes;$i++){
        my $now = int(rand(scalar(@value)));
        $value[$now]++;
        $near[abs($now-$lst)]->[0]++; # 前回との差をカウント
#       $near[$now-$lst+$len-1]->[0]++; # 前回との移動値をカウント
        $lst = $now;
    }

# 最小値、最大値
    my($min, $max) = ($loopTimes, 0);# 最小値、最大値初期化
    foreach(@value){
        $min = $_ if($_ < $min);
        $max = $_ if($max < $_);
    }

# 書式設定
    my $ws = $max / ($winW - 10); # 横グラフ表示用
    my $loopTimesN = divideNum($loopTimes);

    my $dif = $max - $min;
    my $difN = divideNum($dif);
    my $difP = sprintf "%.2f%%", $dif / $loopTimes * 100;

    my $maxN = divideNum($max);
    my $maxP = sprintf "%.2f%%", $max / $loopTimes * 100;

    my $minN = divideNum($min);
    my $minP = sprintf "%.2f%%", $min / $loopTimes * 100;

    foreach(@near){
        $_->[1] = divideNum($_->[0]);
        $_->[2] = sprintf "%.2f%%", $_->[0] / $loopTimes * 100;
    }

# まとめの出力
    Jprint(<<EOM);
<div class=box1>
<strong>データ数:$loopTimesN</strong>
<table border=1>
<tr><th>最大値<td align=right>$maxN<td align=right>$maxP
<tr><th>最小値<td align=right>$minN<td align=right>$minP
<tr><th>誤 差<td align=right>$difN<td align=right>$difP
</table>

<br>

EOM

# 各項目の出力
    Jprint(<<EOM);
<table border=1>
<caption>値の発生回数と比率</caption>
<tr>
<th>発生値
<th width=$winW>カウント数
<th>比率
<th>備考
EOM

    my $cnt = 0;
    foreach(@value){
        my $w = int($_ / $ws); # グラフ巾決定
        my $n = divideNum($_); # カウント数
        my $p = sprintf("%.2f%%", $_ / $loopTimes * 100); # 比率
        print <<EOM;
<tr><th>$cnt<td>
<img src="$G_image" width=$w height=$eleH alt="$n"><td align=right>
$p<td>
EOM
        if($min == $_){
            Jprint('最小');
        }elsif($max == $_){
            Jprint('最大');
        }else{
            print "<br>";
        }
        print "n";
        $cnt++;
    }
    print "</table>nn<br>nn";

# 発生値差
    print "<table border=1>n";
    Jprint("<caption>前回の発生値との差</caption>n<tr>n");
    my $nearmax = 0;
    foreach(@near){
        $nearmax = $_->[0] if $nearmax < $_->[0];
    }
    my $hs = $nearmax / ($winH - 10);
    Jprint("<th height=$winH>カウント数");
    foreach(@near){
        my $h = int($_->[0] / $hs);
        print qq(<td valign=bottom align=center><img src="$G_image" width=$eleW height=$h alt="$_->[1]">);
    }
    Jprint("<tr>n<th>前回との差");
    for($i=0;$i<$len;$i++){ print "<th>$i" }

# 移動値用
#   for($i=-($len-1);$i<$len;$i++){ print "<th>$i" }

    Jprint("n<tr>n<th>比率");
    print "<td align=right>$_->[2]" foreach(@near);
    print "n</table>nn<br>nn";

    print "</div>nn";
}

sub divideNum{
    my($num) = @_;
    1 while $num =~ s/(d+)(d{3})/$1,$2/;
    return $num;
}
                          </div>

Comments

comments powered by Disqus