背景 |
知人はそこで次のような問題を出しました。
「確率90%以上で全15種類を手にいれたいとき、何個買ったらよいで しょう?」
これについて、まとめることにします。
シミュレーションで答えを出そう |
そこで学生さんに相談して解いてもらうことにしました。彼は早速 シミュレーションをしてくれました。そうそう、問題を解 くときにはシミュレーションはいいですよね。つまりこうです。箱を n個買います。その中にはランダムで15種類のおまけが入っています。 箱を開けておまけをチェックして15種類全部あるか無いか調べます。 これを1000回、10000回くらいやって成功する回数と失敗する回数か ら成功確率を求めます。
簡単なプログラムで彼は「72個じゃないですか」と答えを出してくれ ました。私も別にプログラムを組んで 73個が正解 ではな いかという答えを出しました。
近似解が提出される |
知人が夜に「ふと思いついた式」というのは、
n 箱買って全15種類揃う確率 = 1 - 15 * (14/15)^n
でした。この式の考え方は、
n 箱買ってそろう確率 = 1 - n 箱買ってもそろわない確率 「あと1個がゲットできない」の「1個」の選びかたは15とおり。 その「1個」をはずしまくって n 個買う確率 = (14/15)^n
というものでした。
で、確かにこれで計算すると73個という答えが出てくるのですが、近 似式なので、nが小さくなるとだめで、40個とかだと破綻してきます。 さて次はどうするか。
大人買いと子供買い |
大人買い:一度にまるごと、つまり段ボールに箱がたくさん入ってい る状態で全部買込んで、やおら開けていく。
子供買い:一つ買っては開けて、また一つ買っては開けて、揃うまで頑張る。
これらって同じでしょうか。違うのでしょうか。同じだという意見で は大人買いしたところで、やっぱり一個一個開けていき、コンプリー トしたところで、オークションで売ってしまうから(笑)、ということ でした。
子供買いの時には、開けていってコンプリートしたところで買いませ んから、若干問題が異なっています。今回の解こうとしている問題の 場合には、きちんと言えば大人買いをした時に、ほしいおまけが揃っ ているかということになります。たとえば16個買って開けていって 15個開けたところで仮に全種類揃ったとしても、次の1個を開けると いう行為を入れて確率を計算しています。つまり16個買ったとして、 15個開けたところで揃う確率+16個目を開けて揃う確率が、16個開け て揃う確率になっています。
きちんとした漸化式の提案およびその解 |
おまけの種類 n種類 すでに手にいれている種類 m種類(<n) 残りの開けていない箱の数 l個 として、全種類ゲットできる確率fは n-m>l -> f=0これを解く、プログラムは以下の通りです。n-m=0 -> f=1
f(n,m,l)= (n-m)/n*f(n,m+1,l-1) + m/n*f(n,m,l-1)
当たときの確率 + はずした時の確率
#include私も、最初に思いついた自分の漸化式を解くプログラムを使って、学 生さんと同じ結果が出ることを確認しました。これで一応きちんとし た解析解を得ることができるようになりました。さて、こうなるとこ んなプログラムを使わなくても解析解が出る式が欲しくなってきます ね。#define N 15 #define L 100 double Data[N+1][N+1][L+1]; double f(int n,int m,int l) { if(Data[n][m][l]>=0)return Data[n][m][l]; if(n-m>l)return 0; if(n==m)return 1; Data[n][m][l]=(double)(f(n,m+1,l-1)*(n-m)/n+f(n,m,l-1)*m/n); return Data[n][m][l]; } int main() { int i,j,k; int l; for(i=0;i<=N;i++)for(j=0;j<=N;j++)for(k=0;k<=L;k++) Data[i][j][k]=-1; for(l=15;l<=L;l++){ printf("%2d %2d %f\n",N,l,f(N,0,l)); } return 0; }
初めての解析解発表 |

そのうち知人の許可をもらってその考え方を載せたいと思い ます。えーと、もらいました。 ここに導出過程を置きます。
解析解から近似解が導出されることが示される |

ちなみに解析解と近似解の関係は次のようなグラフになります。

さらなる一般化へ |
つまり先ほどまではN個の欲しいおまけがあって、n箱買ったときにど のくらいの確率で全種類が手にはいるかという問題でした。
これを次のように一般化しました。N種類のおまけがあってすでにa種 類持っている。これからn箱買ったときに手元にm種類になる確率pを 求める式。
最後にはここまできました。N種類のおまけのうち、b種類欲しいのが ある。今、手元には、b種類のうち、a種類そろっている。これから n個のおかしを買い増ししたとき、手元に揃った種類数がmとなる確率 はどうなるか?(N>0,n>=0,N>=b>=m>=a>=0)
この問題についてもきちんとした解析解が示されました。

この問題のかなり一般的な解になっているでしょうね。
みんなが使えるようにしよう |
さきほどの学生さんにたのんでJava Scriptを組んでもらいました。
たとえば、おまけの種類の数15、欲しい数15、すでに持っている数 0、これから買う数73を入力してもらうと手にはいる確率0.90556が出 てきます。ちなみに買う数72では0.89906となりまして、90%をほんの ちょっと切ります。さあ、みなさんこのページを利用して、コンプリートするまでの確率 を計算して、おまけをゲットしてください!!
いろいろな情報 |
結果は...5個買って2種類のみ手にいれました。;_;
食玩ではひどいめや天国にいる気分になった方は多いようで、そのリ ンクを教えてもらいました。
確率論を展開する人も多いようです。
店頭での商品シャッフル問題(アソート)は、「均等」ではなく「ランダム」の ようです。
そうそう、現実には、公表されていない種類のおまけがあったり偏り があったりするので、なかなかコンプリートできないですよね。
どうしても欲しいけど、そんなにお金をかけるのには躊躇する、とい うのであれば、
やオークションを使う手がありますね。
まとめ |
また今回の、問題があってそれを解く過程が、本当に研究のやり方の典 型例だったからです。シミュレーションでまずとにかく答えを手にい れる。厳密解をもとめる。さらに効率を上げる。一般化する。みんな が使えるようにする。そういう意味もあってまとめました。何かの役 に立てば幸いです。