各位,引用請指明出處,尊重勞動成果!!!
這幾天在做公司年會的一個抽獎軟件,開始做的的時候,認為算法是很簡單的,把員工的數據放進list里,把list的標號作為需要獲取的隨機數,根據得到的隨機數就確定是誰中獎。后來測試發現,隨機數的分布是非常不均勻的。后來才知道,原來計算機獲取的隨機數都是偽隨機數,當抽獎的速度非常快的時候,獲取的隨機數是非常不均勻的,所以在每次抽獎的時候要添加延時。后來重新設計算法,最終實現了。
算法原理跟二分查找的過程有點像。一枚硬幣抽中正、反面的概率是一樣,當抽樣的次數無限增多,抽中的概率是50%。
代碼如下:
public partial class MainWindow : Window { string s; int number; public MainWindow() { InitializeComponent(); } public int getRandom() { //string[] arr = new string[5] { "我們", "是", "一", "個","團隊" }; Random r = new Random(); int num = 2; int choose = r.Next(num); return choose; //MessageBox.Show(arr[choose].ToString()); } public string GRandom(int n) { //if() if (n == 0) { //s = getRandom() + s; //System.Threading.Thread.Sleep(1); return s; } if (n % 2 == 0) { n = n / 2; } else { n = (n - 1) / 2; //s = getRandom() + s; } s = getRandom() + s; System.Threading.Thread.Sleep(20); GRandom(n); //System.Threading.Thread.Sleep(1); return s; } public Int32 Estimate(int n) { string num = GRandom(n); number = Convert.ToInt32(num, 2); if (number > n - 1) { //num = ""; s = ""; Estimate(n); } //else return number; } private void Button_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < 100; i++) { label1.Content += Estimate(200) + ";"; s = ""; } } }
以上算法不是非常好,取消延時,將random對象設置為全局變量。修改版代碼如下:
string s; int number; Random r = new Random(); public int getRandom() { //string[] arr = new string[5] { "我們", "是", "一", "個","團隊" }; //Random r = new Random(); int num = 2; int choose = r.Next(num); return choose; //MessageBox.Show(arr[choose].ToString()); } public string GRandom(int n) { //if() if (n == 0) { //s = getRandom() + s; //System.Threading.Thread.Sleep(1); return s; } if (n % 2 == 0) { n = n / 2; } else { n = (n - 1) / 2; //s = getRandom() + s; } s = getRandom() + s; GRandom(n); return s; } public Int32 Estimate(int n) { string num = GRandom(n); number = Convert.ToInt32(num, 2); if (number > n - 1) { //num = ""; s = ""; Estimate(n); } //else return number; } private void Button_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < 1000; i++) { label1.Content = Estimate(200); s = ""; } //以下為測試 //int a = 0, b = 0, c = 0, d = 0, f = 0; //for (int i = 0; i < 1000; i++) //{ // //label1.Content = Estimate(2); // int content = Estimate(5); // s = ""; // switch (content) // { // case 0: // a ++; // break; // case 1: // b ++; // break; // case 2: // c ++; // break; // case 3: // d ++; // break; // case 4: // f ++; // break; // } // label1.Content = a; // label2.Content = b; // label3.Content = c; // label4.Content = d; // label5.Content = f; //} } } }