2011-10-05 158 views
2

所以,這是交易。隨機不是隨機的,在Windows Phone 7上隨機班級

我已經爲wp7設置了一個應用程序,其中有50個引號的數組。當用戶單擊按鈕時,會顯示陣列中的隨機引號。問題是,報價總是以相同的順序出現。例如,引號是1-50。訂單總是2,4,20,31,10,... 有沒有辦法解決這個問題?我希望每次使用應用程序時都會出現隨機和不同的引用。

下面的代碼:

string[] listaCantadas; 
    Random r1, r2; 

    public MainPage() 
    { 
     InitializeComponent(); 

     listaCantadas = new string[] 
     {"//set of quotes 
     }; 

     r1 = new Random(100); 
     r2 = new Random(r1.Next(0, 50)); 
    } 

    //click event for display a random quote 

      int Cantada = r2.Next(0, listaCantadas.Length - 1); 
      txtBlockCantada.Text = listaCantadas[Cantada]; 

     }); 
    } 

回答

14

你創建你的第一個實例RandomRandom(100)即恆定種子。所以它會一直返回相同的序列。這又意味着你的第二個實例Random的種子也將保持不變,並且它返回的所有值也是如此。

只需使用默認構造函數創建一個Random的單個實例,即new Random()。這是隨着時間的推移,因此在程序的不同運行之間可能會有所不同。

警告:由於時間只會每隔幾毫秒(在典型的Windows計算機上爲1-16毫秒)改變,如果您使用默認構造函數快速連續創建Random的幾個實例,它們很可能都會返回相同的序列。

另一個常見的缺陷是Random不是線程安全的。但看起來你不會遇到這個問題。

string[] listaCantadas; 
Random r;//No need for more than one instance 

public MainPage() 
{ 
    InitializeComponent(); 

    listaCantadas = new string[] 
    {"//set of quotes 
    }; 

    r = new Random(); 
} 

//click event for display a random quote 

     int Cantada = r.Next(0, listaCantadas.Length - 1); 
     txtBlockCantada.Text = listaCantadas[Cantada]; 

    }); 
} 
+0

非常感謝,現在它就像一個魅力! – Boga

+0

而** do **使其成爲一個靜態實例。 –

+3

@ClausJørgensen:好的,只有當你打算*確保你不會從多個線程調用它時。通常靜態成員預計是線程安全的。 'Random' *不是*線程安全的。 –

1

你每一次相同的種子播種了。只需使用new Random()即可。如果WP7上沒有此功能,請使用當前時間的派生作爲種子。

0

你有相同的種子。使用類似從當前日期

r1 = new Random(DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Second); // etc 
+3

或者只是調用'new Random()'它爲你做... –

1

種子生成的數字總是相同的,甚至從另一個隨機初始化!

播種嘗試另一種方式:

new Random(unchecked((int) (DateTime.Now.Ticks))); 
+0

這比使用'Random'的默認構造函數更糟糕。它受到與默認構造函數相同的問題,以及使用'Ticks'限制種子空間的額外問題。 – CodesInChaos

2

你不應該有種子的固定種子隨機發生器,除非你想重複序列:

new Random(100); 

應該

new Random(); 
4

您正在明確說明種子:

r1 = new Random(100); 
r2 = new Random(r1.Next(0, 50)); 

r1將始終使用相同的種子(100),所以r1.Next(0, 50)將總是得到相同的種子,所以r2將始終使用相同的種子。你沒有真正的隨機性。

您應該創建一個Random的實例並重用它 - 同時注意Random不是線程安全的。 (如果你只打算從UI線程使用你的實例,那很好。)

有關更多信息,請參閱我的article on random number generation in .NET

2

那麼你初始化的種子總是在你的r1隨機數上是100。這當然意味着根據種子你總會得到相同的數字。這意味着你的r2總是用相同的種子初始化的,所以r1和r2總是相同的。

隨機數對於個人電腦來說是不可能的,這聽起來很奇怪。所以你需要一個「隨機」數字來初始化你的隨機生成器。

長話短說。第二個刪除第一個隨機對象並使用空的constructor

默認種子值被從系統時鐘導出,並且具有有限的分辨率

0

只需使用下面的代碼;

Random r = new Random(); 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      string[] listaCantadas = 
      { 
       "q1", 
       "q2", 
       "q3", 
       "q4", 
       "q5" 
      }; 

      //click event for display a random quote 
      txtBlockCantada.Text = listaCantadas[r.Next(0, listaCantadas.Length)]; 
     }