[C#] Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von bur, 6. März 2009 .

  1. 6. März 2009
    Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

    Ich bin gerade dabei mich in C# einzuarbeiten und bin auf folgendes Ergebnis gestoßen, dass ich nicht ganz nachvollziehen kann.

    Ich habe eine Basisklasse, die mittels Random einem Array zwei Zufallswerte zuweist:

    Code:
     public class BaseClass
     {
    
     public int[] GetNumbers()
     {
     int[] arr = new int[2];
     Random rnd = new Random();
     for (int i = 0; i <= 1; i++)
     arr[i] = rnd.Next(11);
     return arr;
     }
     }
    Und eine davon abgeleitete Klasse, die sich das Ergebnis der ersten holt und zudem nach Wert ordnet:

    Code:
     public class DerivedClass : BaseClass
     {
    
     public new int[] GetNumbers()
     {
     int[] arr = base.GetNumbers();
     if (arr[0] > arr[1])
     {
     int temp = arr[1];
     arr[1] = arr[0];
     arr[0] = temp;
     }
     return arr;
     }
     }

    Im Hauptprogramm mache ich dann folgendes:
    Code:
    BaseClass bc = new BaseClass();
    DerivedClass dc = new DerivedClass();
    int[] arrBC = bc.GetNumbers();
    int[] arrDC = dc.GetNumbers();
    Console.WriteLine("Erstes Element (bc): {0}\nZweites Element (bc): {1}\n", arrBC[0], arrBC[1]);
    Console.WriteLine("Erstes Element (dc): {0}\nZweites Element (dc): {1}\n", arrDC[0], arrDC[1]);
    Was zu dieser Ausgabe führt:
    Code:
    Erstes Element (bc): 3
    Zweites Element (bc): 0
    
    Erstes Element (dc): 0
    Zweites Element (dc): 3
    Was ich nicht verstehe, wieso bekomme ich beim Aufruf von dc.GetNumbers() genau das gleiche (bis auf die Sortierung natürlich) Array wie beim Aufruf von bc.GetNumbers() eine Zeile zuvor? Ich hätte erwartet, dass bei jedem erneuten Aufruf von bc.GetNumbers() (ob direkt oder aus dc mittels base.GetNumbers()) die Methode neu ausgeführt also eine neue Zufallszahl ermittelt wird.

    So wirkt das als würde die Methode nur beim ersten Aufruf wirklich ausgeführt und danach nur noch eine Referenz auf das gespeicherte Ergebnis des ersten Aufrufs zugewiesen.

    Wenn ich eine Zeile arrBC2 = bc.GetNumbers() einfüge, dann steht in arrBC2 genau das gleiche wie in arrBC. Also egal wann und wie aufgerufen, bc.GetNumber liefert immer das gleiche...
     
  2. 6. März 2009
    AW: Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

    Hi!

    Es scheint irgendwie als würden die gleichen Zeiger, die beim ersten Aufruf von "GetNumbers()" (base-class) zurueckgegeben werden, auch beim zweiten Aufruf (in der derived-class) zurueckgegeben. Aber ehrlich gesagt erkenne ich nicht an welcher Stelle das passieren könnte. Der Code sieht eigentlich richtig aus (d.h. das 4 unterschiedliche Werte ausgegeben werden müssten). =/
    ist das der komplette code?

    mfg
     
  3. 6. März 2009
    AW: Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

    Das liegt daran, weil das Random-Objekt als Seed die Ticks der Systemzeit nimmt. Du initialisiert die Objekte bc und dc zur gleichen Zeit -> der Seed ist gleich -> es kommen die gleichen Zahlen raus. Außerdem soll man nicht für jede Zufallszahl ein neues Random-Objekt erstellen. Beides hier nachzulesen.

    Lösung: Du erstellst jeweils ein Random-Objekt im Konstruktor der Basis- und der abgeleiteten Klasse. In der abgeleiteten nimmst du als Seed wiederum eine Zufallszahl:

    Code:
     class Program
     {
     static void Main(string[] args)
     {
     BaseClass bc = new BaseClass();
     DerivedClass dc = new DerivedClass();
    
     int[] arrBC = bc.GetNumbers(); 
     int[] arrDC = dc.GetNumbers();
     Console.WriteLine("Erstes Element (bc): {0}\nZweites Element (bc): {1}\n", arrBC[0], arrBC[1]);
     Console.WriteLine("Erstes Element (dc): {0}\nZweites Element (dc): {1}\n", arrDC[0], arrDC[1]);
     Console.ReadLine();
     }
     }
    
     public class BaseClass
     {
     protected Random rnd;
    
     public BaseClass()
     {
     rnd = new Random();
     }
    
     public int[] GetNumbers()
     {
     int[] arr = new int[2];
     
     for (int i = 0; i <= 1; i++)
     arr[i] = rnd.Next(11);
     return arr;
     }
     }
    
     public class DerivedClass : BaseClass
     {
     public DerivedClass()
     {
     rnd = new Random(rnd.Next(1, 1000));
     }
    
     public new int[] GetNumbers()
     {
     int[] arr = base.GetNumbers();
     if (arr[0] > arr[1])
     {
     int temp = arr[1];
     arr[1] = arr[0];
     arr[0] = temp;
     }
     return arr;
     }
     }
    Tada
     
  4. 6. März 2009
    AW: Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

    Okay, also lag das Problem nicht an irgendwelchen Zeiger- statt Werteübergaben, sondern Random hat schlicht bei jedem Aufruf die gleichen Ergebnisse produziert, weil es innerhalb des gleichen Ticks aufgerufen wurde?

    Der Tipp nur ein Random-Objekt für die Klasse zu erstellen, statt jeweils eins pro Methodenaufruf ist auch gut.

    Danke
     
  5. 7. März 2009
    AW: Mehrfacher Methodenaufruf mir random, aber immer gleiches Ergebnis?

    richtig.
    random generiert nur "pseudozufällig" zahlen. dahinter steckt ein algorithmus, der mit einem startwert initialisiert wird.
    bei gleichem startwert, liefert der algo IMMER die gleiche zahlenfolge...
    => z.b. Linearer_Kongruenzgenerator

    achja... man kann zeigen, dass man aus wenigen aufeinanderfolgenden zahlen dieses zufallszahlengenerator den startwert berechnen und damit eben haargenau die gleiche zahlenfolge generieren kann.
     
  6. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.