2009-10-31 4 views
47

To jest naprawdę dziwne i nie rozumiem, dlaczego tak się dzieje. W cyklu foreach przeprowadzam iterację przez kolekcję klasy A i dla każdej klasy nazywam metodę Count(), gdzie numery r1 i są generowane z zakresu [-1,1]. Problem polega na tym, że Random.Next zwraca te same "losowe" liczby dla każdej instancji. Gdy wyniki dla pierwszej instancji to 0 i -1, te same zostaną zwrócone z kolejnych instancji. Proszę, czy możesz mi powiedzieć, dlaczego tak się dzieje? Ponadto nie mogę uzyskać różnych wyników w każdej instancji klasy A. Jest to kod:Random.Next zwraca zawsze te same wartości.

class a 
{ 
Random rnd = new Random(); 
private void Count() 
{ 
    int r1 = rnd.Next(-1, 1); 
    int r2 = rnd.Next(-1, 1); 
} 
} 
class b 
{ 
List<a> listofA=new list<a>(); 
foreach (a ACLASS in listofA) 
{ 
    ACLASS.Count(); 
} 
} 

Odpowiedz

94

Problemem jest to, że podczas tworzenia instancji klasy Random zbyt blisko w czasie.

Po utworzeniu obiektu Random jest on obsiewany wartością z zegara systemowego. Jeśli utworzysz instancje Random zbyt blisko w czasie, wszystkie zostaną obsadzone tą samą losową sekwencją.

Utwórz pojedynczy obiekt Random i podaj jego odwołanie do konstruktora podczas tworzenia instancji klasy "a", zamiast tworzenia jednego obiektu Random dla każdej instancji "a".

+1

zapomniałem, jak również, Kiedyś miałem ten sam problem z powrotem w dniu dokonywania Bingo kartony klub, a wtedy użyłem najgorszego znanego mi sztuczki: Przerwanie wątku dla 2 panów Niedoświadczonych i zwariowanych ... Szalony, mam klasę, która tworzy losowe nazwy ze statyczną deklaracją losową na górze wszystkiego. –

5

Uwzględniasz losową instancję dla każdej instancji A. Wygląda na to, że wszyscy otrzymują tę samą domyślną wartość początkową. Prawdopodobnie chcesz utworzyć statyczny losowy dla wszystkich wystąpień A i używać go wielokrotnie, lub alternatywnie podać wartość początkową dla instancji Random() w konstruktorze A.

8

Tworzysz nowe wystąpienie Random bardzo blisko siebie (twoja pętla jest bardzo ciasna), więc każda instancja efektywnie używa tej samej wartości początkowej.

Lepszym rozwiązaniem byłoby utworzenie jednej instancji i przekazanie jej do metody Count.

Ty problably wiedzieć to następny kawałek, ale ja to tutaj dla kompletności:

MSDN ma szczegółów na ten temat, ale w zasadzie problem jest metoda Random.Next używasz generuje:

32-bitowa liczba całkowita ze znakiem jest większa niż lub równa wartości minimalnej i mniejsza niż wartość maksymalna; to znaczy, zakres wartości zwracanych zawiera wartość minValue, ale nie wartość maxValue. Jeśli minValue jest równy maxValue, zwracana jest wartość minimalna.

z tego powodu twoje wywołanie zwróci -1 lub 0.

7

Zastosowanie pojedynczy, statyczny generator liczb losowych dla wszystkich instancji klasy.

class a 
{ 
    private static Random rnd; 
    static a() { 
     rnd = new Random(); 
    } 
    private void Count() 
    { 
    int r1 = rnd.Next(-1, 2); 
    int r2 = rnd.Next(-1, 2); 
    } 
} 

Uwaga zmiana dać numery w przedziale -1,1 zamiast -1,0

+0

Myślę, że z tym zakresem może również zwrócić 1 i chcą tylko 0 i -1? – Lucas

+0

@Svante edytował pytanie, aby przerwa była otwarta, aby dopasować próbkę kodu.Pierwotne pytanie określało przedział zamknięty, ale nie używając precyzyjnego języka. Myślę, że kod był niepoprawny i zamierzam przywrócić pytanie, aby określić zamknięty interwał. – tvanfosson

+0

@tvanfosson Czy możesz mi powiedzieć, dlaczego to działa? Nie rozumiem, w jaki sposób tworzenie tej statystyki zapewnia losowość. Wiem, że to działa, ale nie dlaczego. Nadal są bardzo bliskie w czasie. Dzięki. – johnny