Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

15.04.2013, 20:55

(C#) Pseudo-Zufallsgenerator: True und False unausgeglichen oft

Hey :)

Inzwischen bin ich mit C# vertraut geworden und bin auch noch fleißig am Herumprobieren^^
Ich hänge im Moment aber ziemlich an dem Versuch, eine Klasse zu schreiben, die mir mit einer statischen Methode (Objekte zu generieren, wäre hier m.M.n. sinnlos) einen "zufälligen" boolschen Wert zurückgibt.

Ich kopiere jetzt nur den relevanten Teil:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    class Zufall
    {

        //Benötigte Variablen für den Zufallsbool:
        static bool[] zufallsliste = new bool[52] { true, true, false, false, true, false, true, true, true, false, false, true, true, true, false, true, false, false, true, true, false, true, true, true, true, false, true, true, false, false, false, true, true, false, false, false, true, false, false, false, false, false, true, false, false, false, true, true, false, true, true, false };
        static int wo1 = 0;
        static int wo2 = 0;
        static bool zufallzurück;


        //Gibt mithilfe der obrigen Variablen einen Zufallswert (Bool) zurück.
        public static bool someBool()
        {
        //    Mix1(wo1 + wo2+1);
            wo1++;
            wo2 += 7;
            if (wo1 > 51) { wo1 = 0; }
            if (wo2 > 51) { wo2 -= 52; }
            zufallzurück = (zufallsliste[wo1] ^ zufallsliste[wo2]);
            return zufallzurück;
        }


Ich versuche es mit zwei Punkten in einer Array, die sich verschieden schnell bewegen und dem ^-Operator, der True zurückgibt, wenn genau ein Wert true ist. Da wo1 und wo2 unabhängig voneinander laufen und als solche bereits gleichoft True und False liefern sollten, müsste True in ungefähr 50% der Fälle am Ende herauskommen.
Aus einem Grund, den ich nicht kenne, kommt True jedoch wesentlich öfter heraus.
Bei 100 000 aufeinanderfolgenden Ausführungen der Methode, wurde True über siebentausendmal häufiger zurückgegeben, was eine viel zu starke Schwankung ist.

Ich weiß, dass ich mir die "zufallzurück"-Variable auch sparen könnte, aber so ist es mir lieber :)

Die Frage ist natürlich recht speziell, ich erwarte nicht wirklich, dass mir jemand helfen kann, aber fragen kann man ja (Wenn doch, natürlich umso besser).

Liebe Grüße!

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

15.04.2013, 21:10

Ich kann dir nicht sagen, woran das genau liegt. Wie groß ist der Unterschied bei mehr oder weniger Durchläufen?

Solltest du an einem möglichst schnellen Ergebnis interessiert sein, dann kannst du entweder mit dieser "Ungenauigkeit" leben oder im Hintergrund ein Random-Objekt verwenden. Von diesem könntest du dir eine Zahl im Bereich 0-1 liefern lassen und dann prüfen, ob sie 1 entspricht. (Man könnte das auch mit jedem anderen Zahlenbereich mit positiver Anzahl enthaltener Zahlen machen, auf dessen Zufallszahl man dann Modulo 2 anwendet, nur ist es so besser lesbar.)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

15.04.2013, 21:20

Das lässt sich sicher anhand Deines Arrays irgendwie ausrechnen, aber an Deiner Stelle würde ich lieber die Klasse "Random" verwenden und mich nicht weiter mit solch selbstgebauten Merkwürdigkeiten beschäftigen. Das wäre dann zusätzlich auch noch ein Einzeiler.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

4

15.04.2013, 21:48

Wie Kobold schon schrieb, einfach die bereits fertigen Lösungen verwenden. Zufallszahlen zu generieren ist eine Wissenschaft für sich, vor Allem weil es eigentlich keine wirklichen Zufallszahlen geben kann, da ein PC nicht frei entscheiden kann welche Zahl er nun nimmt.

5

15.04.2013, 22:01

Danke für die Antworten!

@Salcadur
Die Abweichung ist proportional zu den Durchläufen, bei doppelt so vielen Durchläufen gibt es doppelt so viele Abweichungen.

Von der Random-Klasse wusste ich soweit nichts, aber nun werde ich natürlich darauf zurückgreifen. Und natürlich gibt es keine "echten" Zufallszahlen, aber man kann es so verfeinern, dass es schon sehr unberechenbar wird.

LG

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

15.04.2013, 22:16

Unberechenbar ist ein sehr amüsantes Wort in diesem Zusammenhang, denn die Zufallszahlen werden ja berechnet :)
Random.org macht es hingegen sehr elegant - über atmosphärisches Rauschen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

15.04.2013, 22:45

Dein Algorithmus hat eine Periode von 52 (die Werte wiederholen sich also ab dem 53.).
Dabei erzeugst du 28 mal true und 24 mal false (http://ideone.com/4YQNiT).
Du wirst also immer mehr true als false bekommen.
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

16.04.2013, 09:41

Wenn du vor einem Problem stehst und du bestimmte Dinge benötigst (in diesem Fall "Ich hätte gerne Zufallszahlen"), dann such am besten einfach erst mal bei Google ob es das schon fertig gibt. Bei C# bekommt man da schon einiges geliefert. Irgendwann bekommst du ein Gefühldafür, was es schon geben wird und was du selbst machen musst.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

9

17.04.2013, 00:33

Man muss zwischen Zufallszahlen und Pseudozufallszahlen unterscheiden. Pseudezufallszahlen sind eigentlich total deterministisch und kommen aus Algorithmen wie deinem (nur sind die in der Regel viel besser :D), sehen aber total chaotisch und somit zufällig aus.
'Echte' Zufallszahlen kriegt man durch so etwas wie das angesprochene rauschen (kann halt auch aus einem normalen Mikrofon oder so kommen), lustig verrechnete Benutzereingaben, vielleicht auch aus Schwankungen in der Netzwerkverbindung, oder was auch immer gerade nicht vorhersehbar ist.
Lieber dumm fragen, als dumm bleiben!

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

10

17.04.2013, 00:50

Für dein Bool-Problem kannst du Zahlen verwenden, deren Bits du abackerst. Ein Bit stellt hierbei einen Bool dar. Also im Prinzip wie dein Array, bloß kompakter und nicht konstant. Das könnte so ähnlich aussehen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Pseudocode
bool random_bool() {
  // Das "Bool-Array"...
  static uint32_t lst = 0;
  // ... und das aktuell zu lesende Bool.
  static uint32_t bit = 32;
  // Alle Bools durch gearbeitet?
  if(bit>31) {
    bit=0;
    // Neue Liste!
    lst=get_some_random_int();
  } else {
    // Nächster Bool.
    lst >>= 1;
    ++bit;
  }
  // Und hier wird das aktuell niedrigste Bit gefiltert.
  return lst&1;
}
Eigentlich recht simpel. Musste mal schauen, was die C#-Entsprechungen sind. Der Vorteil dabei ist, dass ein bewehrter Zufallsgenerator recht gut verteilte Zahlen liefert und bei gut verteilten Zahlen im Mittel etwa gleich viele Einsen und Nullen vorkommen.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Werbeanzeige