婚姻成立数のシミュレーション
下記のツイートが面白かったので、記載の条件から、
男女ペアあたりの結婚が成立する確率を求めようとしました。
各10人の男女にそれぞれ1~10の年収があり、恋愛は男の告白から始まると仮定、競争力の高い男10から1に向かって順におっぱいの大きさ(ランダム)で告白、男の年収>女の年収となった場合に婚姻が成立して婚活から離脱していくとした場合の婚姻成立数の期待値 #とは
— 三河のあんちゃん (@aaannchang) 2015, 4月 1
しかし、、、
なかなかむずい。。。
私の数学力では
「結婚した場合、女性が婚活から離脱し、次の男性の選択肢から無くなる」場合を
一般化できませんでした。
なので、ひたすらシミュレーションして、答えっぽい値を求めるアプローチに切り替え。
10,000回、上記婚活をシミュレーションして、平均何組
結婚できるのか求めました。
※シミュレーターのソースコードは最下部
その結果
・
・
・
・
・
・
平均成婚数は、4.028組!(10組中)
少子化すぎます。
なお、男女100人ずついた場合、
平均成婚数:43.89組。
そして
男女1,000人ずついた場合
平均成婚数:442.08組
この条件だと、だいたい
「ペア数 ✕ 0.4強」の成婚数になりそうです。
一般解を出してすっきりしたいですが。。
やはり女性には、男の性格も見てほしいものです。
namespace marriageSim { class Program { static void Main(string[] args) { Console.WriteLine("男女の人数を入力してください"); int num = int.Parse(Console.ReadLine());//ユーザの入力した整数を読み込む Console.WriteLine("男女それぞれ、"+num+"人います。"); Console.WriteLine(""); Console.WriteLine("シミレーションする回数を入力してください"); int rep = int.Parse(Console.ReadLine()); int[] MArray = new int[num];//男性の配列 int[] FArray = new int[num];//女性の配列 int sum = 0;//結婚成立数(成婚数) float avr = 0 ;//平均成婚数 float avrn = 0;//人数あたりの成婚数 int[] SArray = new int[rep];//成婚数を格納する配列 //男性の配列を作成。順番通りの年収 for(int i = 0; i<=num-1;i++ ) { MArray[i] = i + 1; } Random randomNumber = new Random(); int rnd = 0;//ランダム数字が格納される。初期値0 //以下、シミュレーション数だけ実行 for (int r = 1; r <= rep; r++) { Console.WriteLine(""); Console.WriteLine("★"+r+"回目のシミュレーション★"); //女性の配列年収を初期化 //※結婚していた場合、年収は最大値+1になっているので for (int i = 0; i <= num - 1; i++) { FArray[i] = i + 1; } sum = 0;//成婚数を初期化 //男性から女性へプロポーズ for (int j = num - 1; j >= 0; j--) { do { rnd = randomNumber.Next(num);//0~(最大値-1)のランダム値+1 } while (FArray[rnd] >= num + 1); //num+1は、結婚し退場した女性。 //結婚した女性を選んでしまった場合、再度ランダムに選択 //男の年収が、女の年収を上回った場合 if (MArray[j] - FArray[rnd] > 0) { sum++; Console.WriteLine(MArray[j] + "," + FArray[rnd] + "男のほうが年収大。成婚"); FArray[rnd] = num + 1;//退場。num+1は、結婚し退場した女性とする } //男の年収が女の年収以下だった場合 else { Console.WriteLine(MArray[j] + "," + FArray[rnd] + "結婚不成立"); } } Console.WriteLine(r+"回目のシミュレーションでは"); Console.WriteLine("男女それぞれ" + num + "人いた場合、成婚数は" + sum + "組です"); SArray[r - 1] = sum;//成婚数を格納 } //最終結果 // for (int d = 0; d <= rep-1;d++ ) { avr += SArray[d]; } avr /= rep; avrn = avr/num; Console.WriteLine("平均成婚数は"+avr+"組です"); Console.WriteLine("男女ペアあたりの成婚率は" + avrn + "です"); Console.ReadLine(); } } }