ガチャポン・食玩の確率論(2)
山本弘の考察の要約 †
山本弘の考察
6種類の食玩が入っている箱を2つ選ぶ。1個目に選んだものとは違う種類の食玩を2個目に選びたい。客は箱を振って音を聞くことにより1/2の確率で同じものであるかを当てることができる。2個目をダブらずに選択可能な確率はいくつか?
2個目が1個目とダブらない確率は、
正しく判定 間違って判定
1個目とダブっていた場合 1/12 1/12
ダブっていなかった場合 10/12 -
1個目とダブっていると判断されれば棚に戻されますから、ダブらない確率は赤(1行目の右の項目と2行目の左の項目)で示された数字の分子の合計を分母にすることになり、10/11ということになります。
この方法がおかしいという指摘 †
この方法で正しい確率は求められない。仮に正しく音を聞き分けられる確率が1/6とすると、これは音を聞き分けられない場合と同じ結果になるはずで、6個の中から(ダブっていない)5個を選ぶ確率と等しいから5/6となるはず。
一方山本の方法だと
正しく判定 間違って判定
1個目とダブっていた場合 1/36 5/36
ダブっていなかった場合 30/36 -
このうち1行目の右の項目と2行目の左の項目で示された数字の分子の合計を分母とすると30/35=6/7となり、正しい結果と会わない。
山本弘がなぜこの方法で正しい結果が求まると考えたのか不思議である。
どちらが正しい? †
上記に対しては「山本弘の方法で正しい」という意見も出されており、下記で議論が行なわれている
こんなにヘンだよ山本弘(全般) 5
その他の参考サイト
小田部荘司のホームページ
シミュレーション †
プログラムを組んでシミュレーションしてみた。
手順は次の通り
1)先ず0~5の乱数を生成。これを「選んだアイテム」とする。
2)次に0~1の乱数を生成。
もし1なら、予測成功として、「予想したアイテム」を「選んだアイテム」とする。
もし0なら、予測失敗として、再度0~5の乱数を生成し、それを「予測したアイテム」とする。
つまり成功の場合は、選んだアイテムを予想したアイテムとし、失敗した場合はランダムなアイテムを予測したアイテムとする。
3)「予測したアイテム」がある番号(例えば3)なら「ダブリ」と判断し、
上記1)~3)の手順を繰り返す。これは再起呼び出しになっており、必要なら無限に繰り返される。
実際には無限にやったらスタックオーバーフローになるが、幸いそういうケースはなかった。
4)「選んだアイテム」を購入したと見なし、「購入数」カウンタを1増やす。
5)「選んだアイテム」がある番号(例えば3)でないなら、「購入成功」カウンタを1増やす。
6)上記1)~5)を一定回数繰り返す。
こんなプログラムを組んで36,000回「購入」してみた。その結果、
購入数は36,000個
購入成功は33,035個
手に取ったアイテムの個数は43,153個
となった。成功率は33/36=11/12。
一方、
2)次に0~1の乱数を生成。
もし1なら、予測成功として、「予想したアイテム」を「選んだアイテム」とする。
もし0なら、予測失敗として、「選んだアイテム」とは異なるアイテムを生成し、それを「予測したアイテム」とする。
とすべきという意見もある。これは「1/2で当てられる」を
1/2で正確に当てることができ、残り1/2ではデタラメになる(その中には偶然当たるケースが含まれる)
1/2で正確に当てることができ、残り1/2では常にはずれる
と解釈するかの違い。後者の場合のシミュレーション結果は
購入数 360,000,000
成功数 323,997,173
手に取った回数 432,015,866
となり、成功率は324/360=9/10となる。
いずれの解釈でも山本弘が示した10/11とは異なる結果となっている。
理論的に求める †
A~Fの6種類の食玩を1/2の確率で当てる事が出来る。(つまり1/2で間違う)
Aの食玩の場合、1/2の確率でAだと判定し、それぞれ1/10の確率でB~Fだと判定する。
(Aの確率50%、B:10%、C:10%、D:10%、E:10%、F:10% 合計100%)
Bの食玩の場合、1/2の確率でBだと判定し、それぞれ1/10の確率でA、C~Fだと判定する。
Cの食玩の場合、以下同様・・・
最初にAを引いたとして、2回目に
1.Aを引き(1/6)、Aではないと判断(1/2)=1/6×1/2(ダブル)
2.Aを引き(1/6)、Aだと判断(1/2)=1/6×1/2=1/12(引き直し)
3.A以外を引き(5/6)、Aだと判断(1/10)=1/12(引き直し)
4.A以外を引き(5/6)、A以外だと判断(9/10)=9/12(ダブらない)
1の場合はダブル(確率:1/12)(1回目でダブル確率)
2,3の場合は引き直し(確率:1/12+1/12=1/6)
4の場合は成功 となる。(確率:9/12)
2、3の場合(確率:1/6)、また引き直して
1.Aを引き(1/6)、Aではないと判断(1/2)=1/6×1/2(ダブル)
2.Aを引き(1/6)、Aだと判断(1/2)=1/6×1/2=1/12(引き直し)
3.A以外を引き(5/6)、Aだと判断(1/10)=1/12(引き直し)
4.A以外を引き(5/6)、A以外だと判断(9/10)=9/12(ダブらない)
1の場合はダブル(確率:1/12) トータル確率:1/6×1/12(2回目でダブル確率)
2,3の場合は引き直し(確率:1/6) トータル確率:1/6×1/6
4の場合は成功 となる。(確率:9/12) トータル確率:1/6×9/12
同様に、3回目でダブル確率は、1/6×1/6×1/12、4回目でダブル確率は、1/6×1/6×1/6×1/12
以下無限に計算して、無限等比数数の和の公式より
ダブル確率は、
1/12+1/12×1/6+1/12×1/6×1/6+1/12×1/6×1/6×1/6+・・・
=1/12〔1+(1/6)+(1/6)^2+(1/6)^3+・・・ 〕
=1/12×6/5=1/10
従って、2個目がダブらない確率 9/10
因みに1/x の確率で当てる事が出来るなら(食玩6種類)
ダブル確率は、(x-1)/5x
ダブらない確率は、(4x+1)/5x
山本弘はどこで間違えたか †
山本弘の誤りは
すでに持っている食玩をAとした場合
選択した食玩がAの場合
1/2の確率でそれをAと予想する。
1/2の確率でそれをAでないと予想する。
選択した食玩がAでない場合
常にそれをAでないと予想する。
として考えている点にある。「正しく予想できる確率」とは「同じものを同じものであると予想できる確率」と「違うものを違うと予想できる確率」がある。山本は前者を1/2、後者を100%として考えている。
しかし特別の理由がなければ両者は同じと考えるのが適切。もしまったく予想能力がなく、偶然の確率(1/6)でしか予想できないケースを考えれば分かりやすい。山本弘方式では
選択した食玩がAの場合
1/6の確率でそれをAと予想する。
5/6の確率でそれをAでないと予想する。
選択した食玩がAでない場合
常にそれをAでないと予想する。
となり、おかしなことになる。
山本弘の考察
正しく判定 間違って判定
1個目とダブっていた場合 1/12 1/12
ダブっていなかった場合 10/12 -
妥当な考察
正しく判定 間違って判定
1個目とダブっていた場合 1/12 1/12
ダブっていなかった場合 9/12 1/12
直感を信じるな †
しかしこの調子で5種類まで集めた状態を考えると奇妙なことになる。
最後の1枚は「ダブリ」と推測したものを選んだ方が、結果的にダブらない確率が高くなってしまう。
Fだと推測し、Fを選択できる確率
F以外を選択し、Fと推定する確率:5/6×1/2=15/36(ダブる)
F以外を選択し、Fでは無いと推定する確率:5/6×1/2=15/36(引き直し)
Fを選択し、Fと推定する確率:1/6×1/6=1/36(成功)
Fを選択し、Fでは無いと推定する確率:1/6×5/6=5/36(引き直し)
引き直しの確率は、15/36+5/36=20/36=5/9
よって、成功確率は
1/36+5/9×1/36+(5/9)^2×1/36+・・・
=1/36×9/4=1/16
Fでは無いと推測したものを選んだ結果、Fが選択できる確率
F以外を選択し、Fと推定する確率:5/6×1/2=15/36(引き直し)
F以外を選択し、Fでは無いと推定する確率:5/6×1/2=15/36(ダブる)
Fを選択し、Fと推定する確率:1/6×1/6=1/36(引き直し)
Fを選択し、Fでは無いと推定する確率:1/6×5/6=5/36(成功)
引き直しの確率は、15/36+1/36=16/36=4/9
よって、成功確率は
5/36+4/9×5/36+(4/9)^2×5/36+・・・
=5/36×9/5=9/36=1/4
ダブっていない(Fである)と推測したものを選らんで、ダブらない確率は1/16。
一方ダブっている(F以外である)と推測したものを選んで、ダブらない確率は1/4。
Fと推測したものを選ぼうとすると、必要以上に引き直しをしてしまい、結果的にFを選択できる確率が減ってしまう。
面白いのでわざと「ダブっている」と予想した方を選択してダブらない確率をシミュレーションしてみた。
have=0の場合は無意味だから除外
purchase= 36000000 success= 22498719 ( 1.6001) pickup= 162022274 ( 4.5006) have=1
purchase= 36000000 success= 20570171 ( 1.7501) pickup= 92543670 ( 2.5707) have=2
purchase= 36000000 success= 17998876 ( 2.0001) pickup= 72008258 ( 2.0002) have=3
purchase= 36000000 success= 14402461 ( 2.4996) pickup= 64804846 ( 1.8001) have=4
purchase= 36000000 success= 8998696 ( 4.0006) pickup= 64789798 ( 1.7997) have=5
あと残り2個、および1個になったら「ダブってる」方を選択した方がダブリが少ない。
シミュレーションプログラムのソース †
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MaxPurchaseCount (36000)
#define ItemNumber (6)
#define BadItem (3)
static int pickupCount;
int ItemSelect(void) {
int pickupItem;
int guessItem;
pickupCount++;
pickupItem = rand() % ItemNumber;
if ((rand() % 2) == 0) {
guessItem = pickupItem;
} else {
guessItem = rand() % ItemNumber;
// guessItem = (pickupItem + 1) % ItemNumber;
}
if (guessItem == BadItem) {
pickupItem = ItemSelect();
}
return pickupItem;
}
int main(int argc, const char* argv[]) {
int purchaseCount;
int successCount;
int pickupItem;
srand((unsigned)time(NULL));
successCount = 0;
pickupCount = 0;
for (purchaseCount = 0; purchaseCount < MaxPurchaseCount; purchaseCount++) {
pickupItem = ItemSelect();
if (pickupItem != BadItem) {
successCount++;
}
}
printf(
"purchase=%d success=%d pickup=%d\n",
purchaseCount, successCount, pickupCount
);
return 0;
}
6種類すべてを揃えるの確率を求めるプログラム †
注)処理速度の遅いCPUでは MaxPurchageCountを小さな値に
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MaxPurchaseCount (36000000)
#define ItemNumber (6)
#define IsSame(item) ((item) < haveItem)
#define PickupRandom(have) ((have) + (rand() % (ItemNumber - (have))))
static int pickupCount;
static int successCount;
static int haveItem;
static void ItemSelect(void) {
int pickupItem;
int guessItem;
do {
pickupCount++;
pickupItem = PickupRandom(0);
if (IsSame(pickupItem)) {
if ((rand() % 2) == 0) {
guessItem = pickupItem;
} else {
guessItem = PickupRandom(haveItem);
}
} else {
// guessItem = PickupRandom(haveItem);
guessItem = PickupRandom(0);
}
} while (IsSame(guessItem));
if (!IsSame(pickupItem)) {
successCount++;
}
}
int main(int argc, const char* argv[]) {
int purchaseCount;
srand((unsigned)time(NULL));
for (haveItem = 0; haveItem < ItemNumber; haveItem++) {
successCount = 0;
pickupCount = 0;
for (purchaseCount = 0; purchaseCount < MaxPurchaseCount; purchaseCount++) {
ItemSelect();
}
printf(
"purchase=%10d success=%10d (%7.4f) pickup=%10d (%7.4f) have=%d\n",
purchaseCount, successCount, (double)purchaseCount / (double)successCount,
pickupCount, (double)pickupCount / (double)purchaseCount, haveItem
);
}
return 0;
}
前提
選択した箱がすでに持っている食玩のいずれかと一致する場合
1/2の確率で、すでに持っている食玩と推測
1/2の確率で、まだ持っていない食玩のどれかと推測
選択した箱がすでに持っている食玩のどれとも一致しない場合
完全にランダムで食玩を推測
実行結果
purchase= 36000000 success= 36000000 ( 1.0000) pickup= 36000000 ( 1.0000) have=0
purchase= 36000000 success= 32145622 ( 1.1199) pickup= 46284311 ( 1.2857) have=1
purchase= 36000000 success= 26182538 ( 1.3750) pickup= 58912108 ( 1.6364) have=2
purchase= 36000000 success= 17999189 ( 2.0001) pickup= 71992976 ( 1.9998) have=3
purchase= 36000000 success= 8994936 ( 4.0023) pickup= 81026289 ( 2.2507) have=4
purchase= 36000000 success= 2251221 (15.9913) pickup= 81016501 ( 2.2505) have=5
山本弘の前提(上記プログラムの//の部分を入れ替える)
選択した箱がすでに持っている食玩のいずれかと一致する場合
1/2の確率で、すでに持っている食玩と推測
1/2の確率で、まだ持っていない食玩のどれかと推測
選択した箱がすでに持っている食玩のどれとも一致しない場合
100%の確率で、まだ持っていない食玩のどれかと推測
実行結果
purchase= 36000000 success= 36000000 ( 1.0000) pickup= 36000000 ( 1.0000) have=0
purchase= 36000000 success= 32725817 ( 1.1000) pickup= 39272074 ( 1.0909) have=1
purchase= 36000000 success= 28796271 ( 1.2502) pickup= 43198186 ( 1.1999) have=2
purchase= 36000000 success= 23998396 ( 1.5001) pickup= 47990614 ( 1.3331) have=3
purchase= 36000000 success= 17999420 ( 2.0001) pickup= 53994612 ( 1.4999) have=4
purchase= 36000000 success= 10285728 ( 3.5000) pickup= 61718889 ( 1.7144) have=5