少ない試行回数だと偏りを感じる件を調査
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using System.IO; | |
public class RandomLessSampleTest : MonoBehaviour { | |
// サイコロの目を定義 | |
int[] dice = new int[] {1, 2, 3, 4, 5, 6}; | |
// 結果を記録するジャグ配列 | |
int[][] results = new int[userNum][]; | |
// 1ユーザーあたりの試行回数 | |
const int rollNum = 10; | |
// ユーザー数 | |
const int userNum = 10000; | |
// 達成状況を記録する辞書 | |
Dictionary<int, int> achievedResulst; | |
void Start(){ | |
OutputDiceResults(); | |
} | |
void InitializeArrays(){ | |
// 結果データを格納する配列を初期化 | |
for (int i = 0; i < userNum; i++){ | |
results[i] = new int[rollNum]; | |
} | |
// 達成状況を格納する辞書を初期化 | |
achievedResulst = new Dictionary<int, int>(); | |
foreach (int pips in dice){ | |
achievedResulst.Add(pips, 0); | |
} | |
} | |
void OutputDiceResults(){ | |
// 処理開始のメッセージ | |
Debug.Log("***** 少ない試行回数での確認を開始 *****"); | |
// CSVファイルのヘッダを出力 | |
StreamWriter sw; | |
FileInfo fi; | |
string fineName = Application.dataPath + "/Resources/Csv/RandomLessSample/dice_output.csv"; | |
fi = new FileInfo(fineName); | |
sw = fi.CreateText(); | |
InitializeArrays(); | |
for (int userIndex = 0; userIndex < results.Length; userIndex++){ | |
for (int rollIndex = 0; rollIndex < rollNum; rollIndex++){ | |
int pips = RollADice(); | |
results[userIndex][rollIndex] = pips; | |
} | |
// 結果の文字列を出力 | |
sw.WriteLine(OutPutLine(userIndex)); | |
} | |
// 達成人数を出力 | |
sw.WriteLine("***** summary *****"); | |
sw.WriteLine("ドロップアイテムの種類, 人数, 確率"); | |
foreach (KeyValuePair<int, int> pair in achievedResulst){ | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
// ドロップアイテムの種類 | |
sb.Append(pair.Key).Append("種類,"); | |
// 人数 | |
sb.Append(pair.Value).Append(","); | |
// 確率 | |
float prob = 1.0f * pair.Value / userNum; | |
sb.Append(prob); | |
sw.WriteLine(sb.ToString()); | |
} | |
string summary = "6種類のドロップを達成した人数は " + achievedResulst[dice.Length] + " 人でした。"; | |
sw.WriteLine(summary); | |
Debug.Log(summary); | |
// Streamを閉じて書き込み | |
sw.Flush(); | |
sw.Close(); | |
// 処理開始のメッセージ | |
Debug.Log("***** 乱数の偏りの確認を終了 *****"); | |
} | |
int RollADice(){ | |
// 乱数の範囲指定で配列のインデックスを取得する | |
int index = Random.Range(0, dice.Length); | |
// サイコロの目を取得する | |
int pips = dice[index]; | |
return pips; | |
} | |
string OutPutLine(int userIndex){ | |
// 各ユーザーの結果を出力する | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
sb.Append(userIndex).Append(","); | |
// 結果の数だけループ | |
for (int i = 0; i < results[userIndex].Length; i++){ | |
int pips = results[userIndex][i]; | |
sb.Append(pips).Append(","); | |
} | |
// ユーザーの達成状況を確認 | |
sb.Append(CheckAchieved(userIndex).ToString()); | |
return sb.ToString(); | |
} | |
bool CheckAchieved(int userIndex){ | |
bool isAchieved = false; | |
// 達成状況確認の辞書 | |
Dictionary<int, bool> achievedDict = new Dictionary<int, bool>(); | |
foreach (int pips in dice){ | |
achievedDict.Add(pips, false); | |
} | |
// 辞書に結果を格納 | |
foreach (int pips in results[userIndex]){ | |
// 各ユーザーの配列を確認し、辞書内で出た目に一致するキーの値をtrueにする | |
achievedDict[pips] = true; | |
} | |
// 辞書内全てのキーの値がtrueなら達成 | |
int trueCount = 0; | |
foreach (KeyValuePair<int, bool> pair in achievedDict){ | |
if (pair.Value){ | |
trueCount++; | |
} | |
} | |
if (achievedResulst.ContainsKey(trueCount)){ | |
achievedResulst[trueCount]++; | |
} | |
if (trueCount == dice.Length){ | |
isAchieved = true; | |
} | |
return isAchieved; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment