Wir nutzen Cookies, um das allgemeine Benutzerelebnis zu verbessern. Mit der Nutzung unseres Wikis stimmst du der Nutzung von Cookies zu.

Zufallszahl von () bis () (Block)

(Zufallszahl von () bis ())
(Zufallszahl von () bis ())
Kategorie: Operatoren
Typ: Werteblock
Eingeführt in: unbekannt
Eingaben: 2 Zahlen
Plugin-Code (Wiki): (Zufallszahl von () bis ())


Der Block Zufallszahl von () bis () ist ein Werteblock der Kategorie Operatoren-Blöcke.

Er wählt eine Zufallszahl zwischen den beiden eingegebenen Werten. Werden keine Kommas in den Eingaben benutzt, so ist auch das Ergebnis ohne Nachkommastellen. Wird jedoch ein Komma verwendet, so werden immer drei Nachkommastellen angegeben, egal wie viele Nachkommastellen die beiden Eingaben haben.

Eingaben

Es können direkt Zahlen eingegeben werden, oder man setzt andere Wertblöcke ein (z.B. Variablen, Lärmpegel etc.).

Beispiele:

(Zufallszahl von (Stoppuhr) bis (10))
(Zufallszahl von (b) bis (10))
(Zufallszahl von ((2) + (2)) bis (10))
(Zufallszahl von (Größe) bis (10))

Enthält einer der beiden Eingaben eine Kommazahl, so können auch Kommazahlen herausgegeben werden. Ein Beispiel:

(Zufallszahl von (0.1) bis (2.0))

Dier Block gibt nun auch Zahlen wie 0.5 oder 1.9, aber auch Zahlen wie 1.733 wieder. Unabhängig von der Zahl der Nachkommastellen der Eingaben werden immer Zahlen mit bis zu drei Nachkommastellen zurückgegeben.

Verwendung

  • zufällige Anzahl an Wiederholungen
wiederhole (zufallszahl von (1) bis (10)) mal
ändere [Farbe v]-Effekt um [10]
warte bis <(Stoppuhr) = (Zufallszahl von (1) bis (10))>
zeige dich
  • Erzeugen von zufälligen Werten
setze [x v] auf (Zufallszahl von (1) bis (10))

Gewichtete Zufallszahlen

Der Zufallsblock eignet sich nicht in allen Fällen, da alle möglichen Ausgaben die gleiche Eintrittswahrscheinlichkeit haben. Daher benutzt man oft verschiedene weitere Blöcke, um sogenannte "Gewichtete Zufallszahlen" zu bekommen, wobei einige Zufallsergebnisse häufiger auftreten als andere.


Symmetrische Verteilungen

Erfahrungsgemäß treten mit zwei Würfeln die Augensummen 2 und 12 seltener auf als die 6 und 7. Die Zahlen fallen also nicht mehr gleichverteilt. In Scratch lässt sich das leicht simulieren:

Augenzahl =

((Zufallszahl von (1) bis (6)) + (Zufallszahl von (1) bis (6))) 

Die Auszählung genügend häufiger Versuche zeigt im Diagramm eine dachförmige Verteilung. Die Anzahl der geworfenen Zahlen steigt von der 2 geradlinig bis zum Maximum bei 6 und 7 an und fällt dann wieder geradlinig bis zur 12 ab. Diese gewichtete Zufallsverteilung unterscheidet sich also auffällig von dem, was der Scratch-Block liefert. Manche Projekte Spiele, Simulationen und Grafik-Experimenten erfordern aber genau diese Verteilung. Sie lässt sich aber in Scratch leicht nachbilden z.B. die Zahlen 1 bis 100 dachförmig verteilt geht so:

Min = 1
Max = 100
Zufallszahl Dach-Typ =

(((Zufallszahl von (Min) bis (Max)) + (Zufallszahl von (Min) bis (Max))) / (2))

Interessant wird es, wenn ein dritter Würfel hinzu kommt: Die resultierende Verteilungskurve wird dann geschwungen glockenförmig.

Zufallszahl Glocken-Typ-3 =

((((Zufallszahl von (Min) bis (Max))+(Zufallszahl von (Min) bis (Max)))+(Zufallszahl von (Min) bis (Max)))/(3))

Diese glockenförmige Verteilung nennen Statistiker auch Normalverteilung. Sie erinnert an die Notenergebnisse einer Klassenarbeit. Bei einer Klassenstärke von 30 Schülern simuliert man das mit ebenso vielen Würfeln. Als Scratch-Lösung:

setze [Min v] auf [1]
setze [Max v] auf [6]
setze [Anzahl v] auf [30]
setze [Zufallszahl Glockentyp v] auf [0]
Wiederhole (Anzahl) mal
setze [Zufallszahl Glockentyp v] auf ((Zufallszahl Glockentyp)+(Zufallszahl von (Min) bis (Max)))
end
setze [Zufallszahl Glockentyp v] auf (round((Zufallszahl Glockentyp)/(Anzahl)))

Diese Funktion lässt sich universell in verschiedenen Projekten verwenden. Es lohnt sich, hierfür einen eigenen Block zu definieren und diesen in einer Funktionssammlung oder im Rucksack zu speichern:

Define Z = normalverteilte Zufallszahl (Min)(Max)(Würfelanzahl)
setze [Z v] auf [0]
Wiederhole (Würfelanzahl) mal
setze [Z v] auf ((Z)+(Zufallszahl von (Min) bis (Max)))
end
setze [Z v] auf (round((Z)/(Würfelanzahl)))


Mit Würfelanzahl lässt sich der Verlauf der Verteilungskurve flacher oder spitzer einstellen. Übrigens sprechen wir bisher nur von ganzen Zahlen. Wenn aber ein Projekt zufällige Dezimalwerte benötigt, lässt sich das mit einem kleinen Trick bewerkstelligen: Für Zufallswerte mit 2 Stellen hinter dem Komma multipliziert man z.B. Max zunächst mit 100 und dividiert die ermittelten Zufallszahlen Z dann wieder durch 100. Voilà !

Ein guter Generator für echte rationale Zufallszahlen braucht allerdings etwas mehr Mathematik (kommt vielleicht später). Wenn der Praktiker stärker gestreute Nachkommastellen benötigt, dann kommt er aber auch schon mit folgender Scratch-Programmierung weiter:

Z = normalverteilte Zufallszahl (Min)((Max)-(1))(Würfelanzahl)
setze [Z v] auf (verbinde(verbinde(Z)[.])(Zufallszahl von (1) bis (999999999999999)))

Urnenmodelle

Und wie ist es mit einer talförmigen Verteilung? Die mittleren Werte sollen nun selten, die Extremwerte dagegen häufiger kommen. Achtung Falle: Die intuitive Idee, hier einfach die Differenz zu bilden zwischen Max und Zufallszahl geht leider ins Leere. Probier es aus, es kommt exakt die selbe Verteilungskurve heraus!

Hier behilft sich der Scratcher mit einer einfachen Verteilungsliste, die er mit den Zahlen in der gewünschten Verteilungshäufigkeit füllt:

setze [L v] auf [11122344555]
setze [Z v] auf (Zeichen (Zufallszahl von (1) bis (Länge von (L))) von (L))

Das funktioniert ganz gut mit einstelligen Ziffern. Es dürfen übrigens beliebige Zeichen -also auch Buchstaben- sein, die sich so gewichtet würfeln lassen.

Für eine allgemeinere Lösung bietet sich eine listengestützte Verteilungsfunktion an. Damit lassen sich dann mehrstellige Zahlen oder gar ganze Worte würfeln. Jeder kennt die Losbude auf der Kirmes - eine Trommel voller Nieten, die gelegentlich mit einer winzigen Prise Gewinn gewürzt wird:

setze [Eimer voll v] auf [1000]
Wiederhole (Eimer voll) mal
füge [Niete] zu [Los-Trommel v]
end
füge [Hauptgewinn] zu [Los-Trommel v]
setze [Handvoll v] auf [10]
Wiederhole (Handvoll) mal
füge [Trostpreis] zu [Los-Trommel v]
end

setze [Los v] auf (Element (zufällig v) von [Los-Trommel v])

Ein echtes Los-Experiment unterscheidet sich zudem von unseren ersten Zufallsverteilungen, da die Wahrscheinlichkeiten nach jedem erhaltenen Wert gleich bleiben. Dies ist das erste Zufallsmodell. Es gibt aber auch dazu ein passendes Urnenmodell. Unser listenbasierendes Skript für die Lostrommel läst sich ganz leicht zu so einem umbauen:

setze [Z v] auf (Zufallszahl von (1) bis (Länge von [Los-Trommel v]))
setze [Los v] auf (Element (Z) von [Los-Trommel v])
entferne (Z) aus [Los-Trommel v]

So wird jedes gezogene Los auch wirklich aus der Lostrommel entfernt und nicht wieder zurückgelegt. Man unterscheid also zwischen zwei Urnenmodellen: "Ziehen mit zurücklegen" und "ziehen ohne zurücklegen", wobei letzteres etwas komplizierter in der Anwendung ist, da sich die Wahscheinlichkeiten nach jedem Zug ändern.

Reproduzierbare Zufallsergebnisse

Manchmal benötigt man mehr Kontrolle über den Zufall. Dies ist wichtig, um bestimmte Zufallsereignisse exakt zu reproduzieren. Ein gutes Beispiel dafür ist der Welten-Generator aus dem Spiel "Minecraft". Dort wird die Welt scheinbar zufällig generiert. Jedoch enthält jede Welt einen sogenannten "Seed" (engl. für Saatkorn, Samen). Dieser Zahlencode bestimmt, wie das Erschaffen der Welt abläuft. Gibt man mehrmals den selben Seed ein, so erhält man jedes mal das selbe Ergebnis.

Die Berechnungen innerhalb eines reproduzierbaren Zufallsereignisses laufen also komplett ohne Zufallsblöcke ab. Sie orientieren sich immer an einem festgelegten unveränderbarem Zahlencode. Dieser Zahlencode selbst kann aber mithilfe von Zufall erstellt werden. Dadurch entsteht also scheinbarer Zufall, welcher gezielt wiederholt werden kann, sofern man den Seed kennt.

Schräg gewichtete Zufallszahlen

Z.B. in einer Regen-Simulation ist eine gleichmäßige Verteilung der fallenden Tropfen auf dem Bildschirm wenig überzeugend. Gesucht wird eine Zufallsfunktion, deren Häufigkeitsverteilung an der Raumtiefe gekoppelt ist. Mit anderen Worten sollen große Zahlen häufiger auftreten, als kleine Zahlen. Ein erster Ansatz:

setze [Z v] auf ((Max)-([Wurzel v] von ((Zufallszahl von (Min) bis (Max))*(Zufallszahl von (Min) bis (Max)))))

Tatsächlich erzeugt dies hinten (also in der größeren Raumtiefe Z) mehr Tropfen, als im Vordergrund. Eine noch überzeugendere Verteilung erzeugt diese einfache Verschachtelung zweier Zufallsfunktionen.

setze [Z v] auf (Zufallszahl von (Zufallszahl von (Min) bis (Max)) bis (Max))

Weitere Verschachtelungen verschärft die Verteilung z.B. durch:

setze [Z v] auf (Zufallszahl von (Zufallszahl von (Zufallszahl von (Min) bis (Max)) bis (Max)) bis (Max))

Eine Umkehrung der Verteilung - die kleine Werte häufiger liefert - erreicht man durch folgende Formel:

setze [Z v] auf (Zufallszahl von (Min) bis (Zufallszahl von (Min) bis (Max)))

'schräg' gewichtete Zufallsfunktionen lassen sich allerdings auch durch Subtraktion vom Maximalwert umkehren:

setze [Z v] auf ((Max)-(Zufallszahl von (Zufallszahl von (Min) bis (Max)) bis (Max)))

Hinweis: die vorgestellte Lösung genügt visuell dem gesetzten Anspruch. Eine exakte mathematische Erörterung der perspektivischen Verkürzung bei räumlichen Simulationen gehört an anderer Stelle.


Also: Traue keiner Verteilungsfunktion, die Du nicht selbst getestet hast! Ich verwende hierzu das Zufalls-Labor: http://scratch.mit.edu/projects/21289848/



Zufallsfunktionen mit Listen

Listen zufällig mischen

Ein faires Kartenspiel beginnt stets mit dem Mischen. Für alle Spieler sollen die Luschen und Trümpfe ja gleichmäßig und gerecht in Stapel verteilt sein. Zur Simulation des Kartenstapels verwendet der erfahrene Scratcher zumeist eine Liste. Das vollständige Mischen einer Liste benötigt nur wenige Programm-Zeilen:

wiederhole (Länge von [Kartenspiel v]) mal
setze [Position v] auf (Zufallszahl von (1) bis (Länge von [Kartenspiel v]))
füge ((Position) Element von [Kartenspiel v]) zu [Kartenspiel v]
entferne (Position) aus [Kartenspiel v]
end

Eingebaute Zufallsfunktion

Eine wohl weniger bekannte Anwendung der Zufallsfunktion versteckt sich in einigen Listen-Blöcken. Wenn die Position eines Listenelementes anzugeben ist, bestehen folgende Auswahlmöglichkeiten:

   *erstes Element
   *letztes Element
   *ein zufälliges Element
   *oder es wird die Elementnummer als Zahl, Variable oder Werte-Block angegeben

Das Zufalls-Element ist kein zusätzliches Programmfeature, da man ja auch einen Zufalls-Block einsetzen kann. So wird aber das Scripting kürzer und vor allem lesbarer. Die folgenden beiden Anweisungen haben also exakt die selbe Wirkung - welcher Scratch-Stil spricht Dich mehr an?

setze [Los v] auf ((Zufallszahl von (1) bis (Länge von [Lostrommel v])) Element von [Lostrommel v])

setze [Los v] auf ((zufälliges v) Element von [Lostrommel v])

Die 4 Listenblöcke mit eingebauter Zufallsfunktion sind: Element einfügen, Element ändern, Element löschen und Element lesen:


Füge [etwas] als (zufälliges v) Element in [Liste v] ein
Ersetze (zufälliges v) Element von [Liste v] durch [etwas]
Entferne (zufälliges v) aus [Liste v]
((zufälliges v) Element von [Liste v]) 

Wahrscheinlichkeitsrechnungen

Oft hilft es die Wahrscheinlichkeiten von zufälligen Ereignissen zu kennen. Dazu benötigt man jedoch keine besondenren Blöcke sondern eher Mathematikkentnisse. Wichtige und nützliche Rechnungen und Methoden werden im Folgenden erklärt.

Wahrscheinlichkeiten berechnen

Wahrscheinlichkeiten werden oft in Prozentangaben dargestellt. Am leichtesten ist es jedoch diese erstmal als Bruch darzustellen. Der Wert des Nenners besträgt hierbei die Anzahl aller möglichen Ereignisse. Ein Würfel zum Beispiel hat sechs Seiten und es können auch nur diese sechs Ergebnisse auftauchen. Wenn man also die Wahrscheinlichkeit des Ereignisses "Eine 6 Würfeln" berechnen will, beträgt der Wert des Nenners 6. Dasselbe würde für alle anderen Ereignisse gelten, die etwas mit einem Würfel zu tun haben, da es ja immer sechs mögliche Ergebnise gibt. Die Augenzahl 6 ist hierbei nur ein einziges Ergebnis. Daher beträgt der Wert des Zählers 1. Die Wahrscheinlichkeit eine Sechs zu Würfeln beträgt also 1/6. Dies lässt sich auch in Scratch darstellen:

((1)/(6))

So lassen sich die Wahrscheinlichkeiten auch leicht in das Skript einbauen. Wenn man mehrere Ergebnisse eines Wurfes zulässt, so addiert man die Wahrscheinlichkeiten. Ein Beispiel wäre das Ereigniss "Eine 1,2 oder 3 würfeln". Die Wahscheinlichkeit dieses Ereignisses beträgt also 3/6, da man die drei Einzelwahrscheinlichkeiten (1/3 + 1/3 + 1/3) addiert.

Wenn das Ereignis von zwei Würfen abhängt, so muss man die Wahrscheinlichkeiten multiplizieren und nicht addieren. Ein Beipsiel: "Zweimal eine 6 würfeln". Dabei rechnet mal 1/6 * 1/6 und erhält so die Wahrscheinlich mit beiden Würfen eine sechs zu erhalten. Also 1/36.


Falls du dich mit Brüchen noch nicht gut auskennst, hier ein kleiner Einschnitt: In Scratch kannst du Brüche ganz leicht mit dem "Geteilt"-Operator darstellen. Die Namensgebung sieht wie folgt aus:

((Zähler)/(Nenner))

Da es sich um eine Geteiltrechnung handelt, kannst du schon durch das Ablesen anhand dieser Regeln wichtige Informationen erhalten:

  • Wenn der Nenner 1 beträgt, dann passiert mit dem Zähler nichts, da jede Zahl durch 1 wieder die Zahl ergibt.
  • Wenn der Zähler größer als der Nenner ist, dann ist das Ergebnis größer als 1.
  • Wenn der Zähler kleiner als der Nenner ist, dann ist das Ergebnis eine Kommezahl zwischen 0 und 1.
  • Wenn Zähler und Nenner gleich sind, ist das Ergebnis immer 1.

Bei Wahrscheinlichkeiten ist der Zähler nie größer als der Nenner, da der Nenner ja schon die Gesamtanzahl aller Möglichkeiten angibt. Oft musst du Wahrscheinlichkeiten addieren, subtrahieren oder auch multiplizieren. Dazu musst du folgende Regeln beachten: Das Multiplizieren ist am einfachsten. Dazu multiplizierst du einfach die beiden Zähler, welche dann den neuen Zähler ergeben. Dasselbe machst du dann mit dem Nenner. Ein Beispiel:
1/6 * 3/2 = 3/12
Beim addieren und subtrahieren funktioniert es eigentlich genauso, aber hierbei verrechnest du nur die Zähler. Der Nenner bleibt also unverändert, doch bevor du zwei Brüche addieren oder subtrahieren kannst, musst du beide auf den selben Nenner bringen:
1/3 + 1/6 Die Nenner sind nicht gleich!
Also versuchen wir den ersten Bruch zu erweitern. Um von 3 auf 6 zu kommen, müssen wir 3 mal 2 rechnen. Damit der ganze Bruch ohne Fehler erweitert wird, müssen wir beide Zahlen mal 2 rechenen:
1/3 * 2 = 2/6
2/6 + 1/6 = 3/6

Das sind die Grundkentnisse für die Bruchrechnung, die bei der einfachen Wahrscheinlichkeitsrechnung gebraucht werden. In Scratch kannst du Brüche jedoch viel leichter addieren:

(((1)/(3))+((1)/(6)))

Scratch wird das Ganze dann automatisch ausrechnen, es wird jedoch eine Zahl und kein Bruch zurückgegeben. Du kannst so einen Block auch anklicken, um die das Ergebnis in einer kleinen Sprechblase anzeigen zu lassen.

Erwartungswert

Wenn man ein Glücksspiel programmiert, ist es sehr nützlich zu wissen, ob das Spiel für den Spieler und den Betreiber fair ist oder einer der beiden Seiten einen Vorteil hat und häufiger gewinnt.

Dazu muss man zunächst alle Wahrscheinlichkeiten kennen. In unserem Beispiel handelt es sich um ein Kartenspiel, bei dem der Glücksspielbetreiber (in Scratch also der Computer) vier Karten mischt und uns alle verdeckt auf den Tisch legt. Eine davon ist ein Ass, die anderen drei sind Buben. Wenn wir ein Ass ziehen, bekommen wir 2€. Ziehen wir einen Buben bekommen wir gar nichts. Der Teilnahmepreis beträgt 1€. Lohnt sich dieses Spiel auf lange Sicht? Dazu benötigen wir zuerst die Wahrscheinlichkeiten:

  • Ein Ass ziehen = 1/4, also 0.25
  • Einen buben ziehen = 3/4 also 0.75

Nun müssen wir uns die Gewinnsituationen anschauen:

  • Ass = +1€
  • Bube = -1€

Hierbei darf man nicht den Teilnahmepreis vergessen! Bei einem Buben gewinnen wir nichts, aber der gesetzte Euro ist ja trotzdem weg. Beim Ass gewinnen wir zwar 2€, aber auch hier haben wir zunächst einen Euro investiert.

Nun verechnen wir die Wahrscheinlichkeiten mit den entsprechenden Gewinnen: 0.25 * 1 + 0.75 * (-1) = -0.5

Das Ergebnis ist unser Erwartungswert, welcher in diesem Fall -0.5 beträgt, was bedeutet, dass wir auf lange Sicht bei jedem Spiel durchschnittlich 50 cent verlieren. Es ist also uns gegenüber unfair. Wäre der Erwartungswert positiv, so würden wir auf lange Sicht bei jedem Spiel (durchschnittlich betrachtet) gewinnen und auf Dauer würde der Betreiber pleite gehen. Erst wenn der Erwartungswert null beträgt, ist das Spiel für beide Seiten fair. Man muss aber nicht stundenlang neue Zahlen ausprobieren, wenn man den Erwartungswert auf null bringen möchte. Dazu ersetzen wir einen Gewinn mit einer Variable. In den meisten Fällen wird dies der Hauptgewinn sein. Unsere Gleichung sieht also so aus:
0.25 * (x-1) + 0.75 * (-1) = 0 Das ganze ist = 0, da wir ja 0 für den Erwartungswert haben wollen. "X-1, da iwr ja in Wirklichkeit wegen dem Preis 1€ weniger verdienen, als auf der Gewinntafel steht"
0.25 * (x-1) + 0.75 * (-1) = 0
0.25x - 0.25 -0.75 = 0
0.25x - 1 = 0 | +1
0.25x = 1 | *4
x = 4

Damit das Spiel für beide Seiten fair ist, müssen wir bei einem gezogenen Ass also 4€ gewinnen, wenn der Einsatz 1€ beträgt und man bei einem Buben nichts gewinnt.




Code zum Einbinden ins Forum:
[wiki=de:Zufallszahl von () bis () (Block)]Zufallszahl von () bis () (Block)[/wiki]