c# frage: zufallszahlen

NetzUnity und Informatik-forum wurden zusammengelegt. Eine entsprechende Ankündigung wird demnächst noch folgen. Für 2025 ist hier einiges geplant! Bei Fragen bitte per DM an Maximilian Rupp wenden.
  • Hallo! Habe folgendes Problem:

    Der Rechner soll aus einer Palette mit 8 Farben (repräsentiert durch 0..7) 4 zufällig auswählen. Dabei sollen diese wirklich halbwegs zufällig sein.

    Code
    [size=10][color=#008000]//Konstruktor für zufällige Farbe:[/color][/size]
    [color=#008000]//Weist der Klassenvariable color eine zufällig generierte Zahl zu:[/color]
    [size=10][color=#0000ff]public[/color][/size][size=10] Farbe()[/size]
    [size=10]{[/size]
    [size=10]Random rnd=[/size][size=10][color=#0000ff]new[/color][/size][size=10] Random();[/size]
    [size=10]System.Threading.Thread.Sleep(50*rnd.Next(0,20));[/size]
    [size=10][color=#0000ff]this[/color][/size][size=10].color=rnd.Next(0,7);[/size]
    [size=10]}
    [/size]



    das ist nun schon ziemlich zufällig. leider kommen die Farben zwischen 1 und 4 immer noch merkbar häufiger vor. 7 kommt überhaupt nie vor... hm.. mal bei Next nachschauen... [edit] das mit 7 hat sich erledigt... aus irgendeinem Grund ist das Intervall ein halboffenes, also Parameter auf 0,8 geändert). [/edit]

    hat jemand eine Idee wie man es noch zufälliger machen könnte?

    lg michi

  • Zitat von RupertK

    du könntest die funktion nextDouble verwenden (liefert zahl zwischen 0 und 1)
    und dann mal 8 rechnen


    aber ist es dann zufälliger? :)

    es ist schon merkwürdig.. auf anhieb fällt es gar nicht so auf, aber ich hab eine kleine statistik gemacht.. die farben zwischen 1 und 4 sind wirklich sehr häufig.

    Lg Michi

  • Zitat von michi204

    es ist schon merkwürdig.. auf anhieb fällt es gar nicht so auf, aber ich hab eine kleine statistik gemacht.. die farben zwischen 1 und 4 sind wirklich sehr häufig.

    das ist mir auch schon oft passiert -> das problem ist, dass diese zufalls-funktion(en) (nur ?!!) über die zeit realisiert sind und es dadurch zu wiederholungen kommen kann, speziell natürlich, wenn schnell nacheinander viele zufallszahlen verwendet werden.... was du probieren könntest (wenns wichtig ist) ist eine eigene funktion zur erstellung von zufälligen zahlen zu schreiben -> dafür gibt es viele algorithmen!!

    z.B. http://www.math.keio.ac.jp/matumoto/emt.html

    die wiederholgsrate dieses algorithmus liegt bei: 2^19937 (müsse für dein programm reichen ;)) und ist somit gerade für programme gut geignet, welche sehr viele zufallszahlen hintereinander brauchen ohne wiederholungen bestimmter reihen zu bekommen!

    mfg marX

  • Zitat von michi204

    [edit] das mit 7 hat sich erledigt... aus irgendeinem Grund ist das Intervall ein halboffenes, also Parameter auf 0,8 geändert). [/edit]


    Ich vermute, das hängt damit zusammen, dass bei normalen Randomizern immer eine Zahl von 0 bis 0.9999... rauskommt aber nie 1-> das mit 7 Malgenommen und immer abgerundet-> 7 kommt nicht
    mfg Zentor

  • also ich hab das jetzt mal ausprobiert und ich konnte keinen solchen effekt feststellen.

    alle zahlen kamen ungefähr gleichoft vor.
    hier das programm

    int []count = new int[10];

    for (int i=0;i<10;i++)
    count[i]=0;

    Random rand = new Random (Environment.TickCount);

    for(int i=0;i<1000;i++)
    count[rand.Next(10)]++;

    for (int i=0;i<10;i++)
    Console.WriteLine( i.ToString() +": "+count[i] );

    intelligenz * schönheit = const

  • danke für eure antworten, auch an marX für den link!


    Also vom Random-Aufruf her sollte das ungefähr gleich sein wie meine Variante.. ich werd mal eine umfangreichere Statistik machen vielleicht hab ich mir das alles nur eingebildet oder es war ein böser Traum :) Oder meine Clockticks sind irgendwie anders :) Vielleicht wollen mir die Außerirdischen damit was sagen? :D

    lg michi

  • Zitat von michi204

    Vielleicht wollen mir die Außerirdischen damit was sagen? :D

    hehe...nein, also es kann so sein (wie ich oben schon geschrieben habe) - wenn der algorithmus die zeitabfrage verwendet -, dass in seinem prgramm eine ausgeglichene zahlenverteilung entsteht und in deinem nicht! -> stell dir mal vor, dein zufallszahlen algorithmus (zur erklärung vereinfacht) verwendet die 100stel sekunden als zufallszahl.
    wenn du jetzt z.b. 10000 mal eine zufallszahl zwischen 0 und 100 (in einer schleife) generieren würdest, würde der code in der schleife (zeitabfrage, etc.) immer ca. (genau) gleich lange benötigen -> jede zufallszahl liegt nahe bei der nächsten !!
    -> theoretisch (ohne multitasking, etc.) könnte es sogar passieren, dass du immer die selbe zahl erhalten würdest ;)

    so ich hoffe jetzt, dass ich dich nicht zu sehr verwirrt habe, bzw. nicht einen zu brutalen stuss geschrieben habe -> nach meiner erfahrung stimmt das aber (so in etwa) wirklich! *gg*

    mfg marX

  • Ich denke das Problem ist dass der Zufallsgenerator (die Klasse Random) immer wieder neu mit einem neuen zeitabhängigen Seed initialisiert wird. Der Zufallsgenerator selber funktioniert nicht zeitabhängig, sondern beruht auf einen mehr oder weniger guten Algorithmus der als Input die zuvor generierten Zahlen hat.

    Also man sollte den Zufallsgenerator nur einmal initialisieren, das kann dann so aussehen

    Code
    private static rnd = new Random();
    
    
    public Farbe()
    {
    this.color=rnd.Next(0,7);
    }

    Alles nur IMHO, also einfach mal ausprobieren.

  • habe es jetzt so ähnlich wie in qmp's vorschlag gemacht, was das beste ergebnis bringt...

    danke noch einmal für die tipps!

    lg michi

    Code
    [/size][size=10][color=#0000ff]static[/color][/size][size=10] Random rnd=[/size][size=10][color=#0000ff]new[/color][/size][size=10] Random();[/size][size=10][color=#008000]//Konstruktor für zufällige Farbe:[/color][/size][size=10][color=#0000ff]public[/color][/size][size=10] Farbe()[/size][size=10]{   System.Threading.Thread.Sleep(5*rnd.Next(0,20));[/size][size=10][color=#008000]   //rnd=new Random();[/color][/size][size=10][color=#0000ff]   this[/color][/size][size=10].color=rnd.Next(0,8);[/size][size=10]}


    [/size]

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!