Theo.Spengler
Anmeldungsdatum: 4. Januar 2019
Beiträge: 56
|
Ich möchte mit Bash Zufallszahlen erzeugen und das später vlt. noch mal visuell aus geben. Im Moment kann ich eine annähernd gleichverteilte Verteilung erzeugen. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #!/bin/bash
schleifendurchlaufanzahl=100 # wie oft die Schleife durch laufen soll
for i in $(seq $schleifendurchlaufanzahl)
do
min=1 # untere Bereichsgrenze der Zufallszahl
max=10 # obere Bereichsgrenze der Zufallszahl
zufallswert=$((RANDOM%($max-$min+1)+$min))
echo $zufallswert
done
read -p "Zum Beenden Enter drücken oder Ctl + C"
|
Wie kann man eine andere Verteilung erzeugen, wie z.B.: vom Bereichsanfang zum Bereichsende Abfallende E Funktion vom Bereichsanfang zum Bereichsende ansteigende E Funktion eine Normalverteilung oder irgend etwas anderes
Visualisierung:
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6339
Wohnort: Hamburg
|
Als ich damals eine Gaußverteilung brauchte, hatte ich nichts fertiges gefunden. Ich habe da nur Hinweise gefunden, wie man das in C machen kann. Falls sich niemand mit einer besseren Idee meldet, könntest du versuchen das mit dem Konsolenprogramm bc nachzubilden. Literatur:
Box-Muller-Methode Box–Muller transform (mit Beispiel)
Ich hatte damals folgenden Code verwendet (kann jetzt aber auch nicht mehr sagen was da die Vorlage war):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | /* random numbers 0...1 */
#define ranf() ((double)rand()/(1.0+(double)RAND_MAX))
/*
** mean m, standard deviation s
*/
float box_muller( float m, float s ) {
float x1, x2, w, y1;
static float y2;
static int use_last = 0;
if( use_last ) { /* use value from previous call */
y1 = y2;
use_last = 0;
} else {
do {
x1 = 2.0 * ranf() - 1.0;
x2 = 2.0 * ranf() - 1.0;
w = x1 * x1 + x2 * x2;
} while( w >= 1.0 );
w = sqrt( (-2.0 * log( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
use_last = 1;
}
return( m + y1 * s );
}
|
|
Theo.Spengler
(Themenstarter)
Anmeldungsdatum: 4. Januar 2019
Beiträge: 56
|
Dakuan schrieb: Als ich damals eine Gaußverteilung brauchte
Das scheint mir möglicher Weise so zu sein, das man vlt. einfach nur gleichverteilte Zufallszahlen, durch eine Mathe Funktion durch schicken muss. Und schon erhält man wohl möglich eine Verteilung entsprechend der nachgeschalteten Mathe Funktion. Quellen für Mathe Funktionen: * y = e hoch x https://www.wolframalpha.com/input/?i=e+hoch+x * y = 1/e hoch x https://www.wolframalpha.com/input/?i=1%2Fe+hoch+x * Normalverteilung https://www.wolframalpha.com/input/?i=normal%20distribution%20function So, dann muß ich mal gucken wie man mit bash rechnet: * https://www.linux-community.de/ausgaben/easylinux/2017/04/rechnen-in-der-shell/
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11176
Wohnort: München
|
Theo.Spengler schrieb: Ich möchte mit Bash Zufallszahlen erzeugen und das später vlt. noch mal visuell aus geben.
Warum ausgerechnet mit der Bash? Es gibt viel schönere Skriptsprachen - z.B. Python3, das im random-Modul schon einige Möglichkeiten für bestimmte Verteilungen von Zufallszahlen mitbringt, wobei man mit numpy auf eine effizientere Implementierung zurückgreifen kann (https://numpy.org/doc/stable/reference/random/legacy.html, https://numpy.org/doc/stable/reference/random/index.html) und mit Bibliotheken wie matplotlib, mit denen man bequem Ergebnisse plotten kann.
|
Theo.Spengler
(Themenstarter)
Anmeldungsdatum: 4. Januar 2019
Beiträge: 56
|
seahawk1986 schrieb: Warum ausgerechnet mit der Bash?
Ich schauen mir im Moment ein paar Sachen in Bash an. Danach schaue ich mir in etwa die selben Sachen in Python an.
Danach werde ich vorausichtlich zu dem Schluß kommen, das diese und jende Dinge sich an bieten in Bash zu lösen und jene eher in Python. Die allgemeine Meinung hierzu ist mir bereits bekannt. Ich muß dieses aber trotzdem in an ein paar Beispielen selbst erleben. Und nein, ich möchte mir zum jetzigen Zeitpunkt kein Python an sehen, auch wenn es verlockend ist.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Normalverteilung: Mir fiele da das Nagelbrettexperiment aus dem Schulunterricht ein. Am Anfang ist der Ausgangswert X, und dann folgen Y Schritte, und bei jedem Schritt wird X zufällig eins kleiner oder eins größer. Also etwa 10-9-10-9-8-7-8-7-8-7-6. Je nach Zahl der Schritte wird das Ergebnis entweder immer gerade oder immer ungerade sein. Mit einer Integerdivision durch 2 mit Abschneiden bekäme man so eine Verteilung von 0-10 und Mittelwert 5, wenn man das Experiment oft genug wiederholt.
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6339
Wohnort: Hamburg
|
Das Experiment finde ich auch interessant. Allerdings kenne ich es nicht aus dem Schulunterricht, sondern aus dem TV (könnte Planet Wissen gewesen sein). Der "offizielle" Name dafür ist Galtonbrett, oder meinst Du was anderes? Worauf ich aber eigentlich hinweisen will ist, dass die von Theo.Spengler verlinkten Funktionslösungen, nur den Verlauf dieser Funktionen berechnen und nichts mit der Erzeugung von Zufallszahlen zu tun hat.
|
Theo.Spengler
(Themenstarter)
Anmeldungsdatum: 4. Januar 2019
Beiträge: 56
|
Dakuan schrieb: Worauf ich aber eigentlich hinweisen will ist, dass die von Theo.Spengler verlinkten Funktionslösungen, nur den Verlauf dieser Funktionen berechnen und nichts mit der Erzeugung von Zufallszahlen zu tun hat.
Ich vermute busher das man die gewünschte Verteilung von Tufallszahlen erzeugt bekommt, in dem man gleichverteilte Zufallszahlen, durch eine Funktion mit der gewünschten Kurvenform durch schickt. Daher die Links zu nit für mich passenden Kurvenformen, wo man auch mit den Funktionen und den Werten uetwas spielen kann und sieht wie sich das in der Kurve aus wirkt.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Dakuan schrieb: Das Experiment finde ich auch interessant. Allerdings kenne ich es nicht aus dem Schulunterricht, sondern aus dem TV (könnte Planet Wissen gewesen sein). Der "offizielle" Name dafür ist Galtonbrett, oder meinst Du was anderes?
Nein, das meine ich.
Worauf ich aber eigentlich hinweisen will ist, dass die von Theo.Spengler verlinkten Funktionslösungen, nur den Verlauf dieser Funktionen berechnen und nichts mit der Erzeugung von Zufallszahlen zu tun hat.
Nun ja, wenn Du eine Funktion hast wie y=x² und Dich das Intervall von 0 bis 4 interessiert, dann berechnest Du die y:
0, 1, 4, 9, 16, (25). Die Summe ist 30. Summiert:
0, 1, 5, 14, 30 (55). Zufallszahlen, die quadratisch verteilt sind, kannst Du also für 5 Werte erzeugen in dem Du gleichverteilte Zufallswerte von 0 bis 54 mit RANDOM erzeugst. Ist der Wert 0 sagen wir 0. Ist er 1 bis 4 sagen wir 1. Ist er 5 bis 13 2 usw. Bzw. wir nehmen die inverse Funktion und erzeugen gleichverteilte Zufallszahlen von 0 bis 24 und ziehen die Wurzel - was mit Bordmitteln der Bash nicht ohne weiteres geht. Der abgerundete Wert wäre dann schon das Ergebnis, also für 17 erhalten wir beispielsweise 4. Man kann aber, um das Wurzelziehen zu umgehen, die Quadrate vorab berechnen und in einem Array speichern, so dass man leicht suchen kann, zwischen welchen Werten das Ergebnis liegt. Oder bc aufrufen.
Die e-Funktion und die inverse davon sind mir aber nicht so geläufig, daher habe ich zu Quadraten gegriffen. ☺
|
Theo.Spengler
(Themenstarter)
Anmeldungsdatum: 4. Januar 2019
Beiträge: 56
|
user_unknown schrieb: Worauf ich aber eigentlich hinweisen will ist, dass die von Theo.Spengler verlinkten Funktionslösungen, nur den Verlauf dieser Funktionen berechnen und nichts mit der Erzeugung von Zufallszahlen zu tun hat.
Zum Rechnen mit Funktionen unter Bash, habe ich erst einmal folgendes gefunden was BC möglich macht: "
s(x) berechnet den Sinus (sin x) einer Zahl x, c(x) den Kosinus (cos x), a(x) den Arkustangens (atan x), l(x) den Logarithmus (ln x) zur Basis e = 2,7182818… und e(x) die Exponentialfunktion e^x (exp x). Die Quadratwurzel ist über sqrt(x) erreichbar: Diese Funktion steht auch zur Verfügung, wenn Sie bc ohne die Option -l starten; auf die übrigen Funktionen müssen Sie dann aber verzichten. Versuchen Sie dennoch, eine davon aufzurufen, antwortet bc mit einer Fehlermeldung und kann kein Ergebnis berechnen: e(3)
Runtime error (func=(main), adr=5): Function e not defined. Das liegt daran, dass -l nicht nur die Genauigkeit auf 20 Nachkommastellen setzt, sondern auch eine mathematische Bibliothek einbindet, in der sich die Funktionen befinden." Quelle: https://www.linux-community.de/ausgaben/easylinux/2017/04/rechnen-in-der-shell/2/
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17548
Wohnort: Berlin
|
Theo.Spengler schrieb: user_unknown schrieb: Worauf ich aber eigentlich hinweisen will ist, dass die von Theo.Spengler verlinkten Funktionslösungen, nur den Verlauf dieser Funktionen berechnen und nichts mit der Erzeugung von Zufallszahlen zu tun hat.
Nein, das schrieb Dakuan, wie man oben überprüfen kann, ich habe es nur zitiert.
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6339
Wohnort: Hamburg
|
Soweit ich das bisher sehen kann, sind die notwendigen Funktionen in bc vorhanden. Ich selber würde das in der Bash aber wohl nur umsetzen, wenn es um eine Wette ginge, die ich keinesfalls verlieren will. Aber nochmal, die Kurve der Verteilungen (z.B. Gauß) hat nichts mit der Erzeugung der Zufallszahlen zu tun. Ich hatte ja schon einen (erprobten) C Code gepostet, der nach der Box-Muller Methode arbeitet. Den hatte ich seinerzeit verwendet um Morsezeichen zu "hunmanisieren". Du bekommst da bei jedem Aufruf eine Zufallszahl, die der Gaußverteilung entspricht. Also wenn du genügend viele Aufrufe machst, wirst du feststellen, das sich die Werte besonders gerne um den m Wert tummeln. Bei der Umsetzung in der Bash müsstest du allerdings das Macro ranf() von Hand auflösen, d.h. selber direkt in den eigentlichen Quelltext einbauen. Der Code für die Gauß-Kurve selber ist deutlich einfacher (hier allerdings für mu=0 fest codiert):
| double sigma = 0.50;
double gauss( double x ) {
double value;
if( sigma < 1e-6 )
return 0.0;
value = (1.0 / sqrt(2.0 * M_PI * sigma * sigma)) * exp( (-1.0 *x * x) / (2.0 * sigma * sigma) );
return value;
}
|
Ergebnis siehe Anhang.
- Bilder
|