1: 2016-02-06 (土) 22:54:09 osinko |
2: 2016-02-07 (日) 00:40:17 osinko |
| **確率の基礎2 [#x3e3c2d6] | | **確率の基礎2 [#x3e3c2d6] |
| | | |
| + | #jsmath |
| ***case2 [#sfdbb904] | | ***case2 [#sfdbb904] |
| | | |
- | 黒ボール10個、白ボール3個を一つの袋に入れてよく混ぜ、一つずつ取り出していく。どちらかのボールが袋の中から無くなったら | + | 白ボール10個、黒ボール3個を一つの袋に入れてよく混ぜ、一つずつ取り出していく。どちらかのボールが袋の中から無くなったら |
- | 取り出すのを終了して、袋の中の残りのボールの数を数える。平均何個残るか? | + | 取り出すのを終了して、袋の中の残りのボールの数を数える。平均何個残るか? |
| + | |
| + | 同じように白ボール100個、黒ボール2個を一つの袋に入れてよく混ぜ、一つずつ取り出していく。どちらかのボールが袋の中から無くなったら |
| + | 取り出すのを終了して、袋の中の残りのボールの数を数える。平均何個残るか? |
| + | |
| + | |
| + | 先に求める式を書いてしまうと以下になる |
| + | |
| + | \(\frac { 1 }{ 3+1 } \times 10+\frac { 1 }{ 10+1 } \times 3\quad =\quad \frac { 10 }{ 4 } +\frac { 3 }{ 11 } \quad =\quad \frac { 110+12 }{ 44 } \quad =\quad \frac { 122 }{ 44 } \quad =\quad 2.772...\) |
| + | |
| + | \(\frac { 1 }{ 2+1 } \times 100+\frac { 1 }{ 100+1 } \times 2\quad =\quad \frac { 100 }{ 3 } +\frac { 2 }{ 101 } \quad =\quad \frac { 10100+6 }{ 303 } \quad =\quad \frac { 10106 }{ 303 } \quad =\quad 33.353...\) |
| + | |
| + | 前者が2.772個。後者の問題が33.353個となる |
| + | では、unityでシミュレーションして、この求めた値が正しいか検証、体験、実感してみる |
| + | シミュレーションでは試行を10万回繰り返し平均値を求めている |
| + | |
| + | #code(csharp){{ |
| + | using UnityEngine; |
| + | using System.Collections; |
| + | using System.Collections.Generic; |
| + | using System.Linq; |
| + | |
| + | public class Test6 : MonoBehaviour |
| + | { |
| + | |
| + | void Start() |
| + | { |
| + | print("計算で求めた値:" + (10f / (3f + 1f) + 3f / (10f + 1f))); |
| + | print("シミュレーション値:"+Sampling(10, 3, 100000)); |
| + | |
| + | print("計算で求めた値:" + (100f / (2f + 1f) + 2f / (100f + 1f))); |
| + | print("シミュレーション値:" + Sampling(100, 2, 100000)); |
| + | |
| + | //Rest(10, 3,true); |
| + | } |
| + | |
| + | //サンプリングして平均値を返す |
| + | float Sampling(int whiteBall, int blackBall, int loopCount) |
| + | { |
| + | int rest = 0; |
| + | for (int i = 0; i < loopCount; i++) |
| + | { |
| + | rest += Rest(whiteBall, blackBall); |
| + | } |
| + | return (float)rest / (float)loopCount; |
| + | } |
| + | |
| + | //シミュレーション。残り個数を返す |
| + | int Rest(int whiteBall, int blackBall,bool debug=false) |
| + | { |
| + | int whiteCount = 0; |
| + | int blackCount = 0; |
| + | int pointer = 0; |
| + | |
| + | bool[] quary = ShuffleBall(whiteBall, blackBall); |
| + | for (int i = 0; i < quary.Length; i++) |
| + | { |
| + | pointer++; |
| + | if (quary[i] == true) whiteCount++; |
| + | else blackCount++; |
| + | |
| + | if (whiteCount >= whiteBall) break; |
| + | if (blackCount >= blackBall) break; |
| + | } |
| + | |
| + | //参考用(中身を視覚的に確認できる) |
| + | if (debug) |
| + | { |
| + | foreach (var item in quary) |
| + | { |
| + | print(item); |
| + | } |
| + | print(quary.Length); |
| + | print(pointer); |
| + | print(quary.Length - pointer); |
| + | } |
| + | |
| + | return quary.Length - pointer; |
| + | } |
| + | |
| + | //標本空間上のボールをシャッフル |
| + | bool[] ShuffleBall(int whiteBall, int blackBall) |
| + | { |
| + | bool[] query = GetBall(whiteBall, blackBall).ToArray(); |
| + | |
| + | //書籍「ゲームの作り方unityで覚える遊びのアルゴリズム」よりP114のシャッフルアルゴリズムの応用 |
| + | //念のため3回全体シャッフルしている |
| + | //(3回以下だとこのアルゴリズムでは偏りがあった) |
| + | for (int j = 0; j < 3; j++) |
| + | { |
| + | for (int i = 0; i < query.Length - 1; i++) |
| + | { |
| + | int pointer = Random.Range(i + 1, query.Length); |
| + | bool temp = query[pointer]; |
| + | query[pointer] = query[i]; |
| + | query[i] = temp; |
| + | } |
| + | } |
| + | |
| + | return query; |
| + | } |
| + | |
| + | //白玉と黒玉の標本空間を作成 |
| + | IEnumerable<bool> GetBall(int whiteBall, int blackBall) |
| + | { |
| + | for (int i = 0; i < whiteBall; i++) |
| + | { |
| + | yield return true; //trueが白玉 |
| + | } |
| + | |
| + | for (int i = 0; i < blackBall; i++) |
| + | { |
| + | yield return false; //falseが黒玉 |
| + | } |
| + | } |
| + | } |
| + | }} |
| + | |
| + | <実行値の一例> |
| + | 計算で求めた値:2.772727 |
| + | シミュレーション値:2.76931 |
| + | 計算で求めた値:33.35313 |
| + | シミュレーション値:33.3682 |
| + | |
| + | この様に値が正しい事が実際に体験し確認できた。では、これが何故正しい値になるのか理屈で考えてみる… |
| + | イデアとクオリアが現実でリンクしている事が知覚出来たのなら数学という哲学を学ぶことは無意味ではない筈だ |
| + | それはゲームを作る時強い武器となる |