Habe mal alles in einem ausführbaren Progrämmchen zusammengetragen, was ich jemals bei Zufallszahlen in Codes geschrieben habe. Vielleicht kann das ja jemand gebrauchen.
Code: Alles auswählen
; PureBasic Visual Designer v3.95 build 1485 (PB4Code)
;Das folgende kleine Programm wurde in Vorbereitung eines größeren geschrieben, um die Einflussfaktoren der Variablen besser
;beurteilen zu können. Die erzeugten Zufallwerte werden dabei mit der Theorie verglichen. Erzeugt werden gleichverteilte
;und normalverteilte Zufallszahlen(nach drei Methoden). Alles weitere steht im Code.
;Interessant ist, dass bei der Erzeugung nach dem Grenzwertsatz (Zwölferregel) die Geauigkeit mit ungeraden "Anzahl-Werten"
;größer ist, was auch optisch sehr ins Auge fällt.
;Durch empirische Ermittlungen habe ich Korrekturfaktoren gefunden, die in dem von mir betrachteten Wertebereich gute Ergebnisse
;liefern. Inwieweit sie Mathematisch jedoch korrekt sind, kann ich nicht beurteilen, da mir das Wissen dazu fehlt.
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
;
Enumeration
#Button_0
#Button_1
#Button_2
#Button_3
#Text_0
#Text_1
#Text_2
#Text_3
#Text_4
#Text_5
#Text_6
#Text_7
#Text_8
#Text_9
#Text_10
#Text_2a
#Text_3a
#Text_5a
#Text_6a
#String_0
#String_1
#String_2
#String_3
#Frame_0
EndEnumeration
Dim Wert(99,1)
Procedure Open_Window_0()
If OpenWindow(#Window_0, 216, 0, 600, 300, "Zufall mit System", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
ButtonGadget(#Button_0, 10, 80, 160, 20, "Gleichverteilt")
ButtonGadget(#Button_1, 10, 104, 92, 20, "Grenzwertsatz")
ButtonGadget(#Button_2, 10, 128, 160, 20, "Polar-Methode")
ButtonGadget(#Button_3, 10, 152, 160, 20, "Box-Muller-Algorithmus")
TextGadget(#Text_0, 190, 284, 400, 20, "0 50 100")
StringGadget(#String_0, 134, 10, 36, 16, "4000",#PB_Text_Right|#PB_String_Numeric)
StringGadget(#String_1, 134, 30, 36, 16, "50",#PB_Text_Right)
StringGadget(#String_2, 134, 50, 36, 16, "16",#PB_Text_Right)
StringGadget(#String_3, 144, 106, 26, 16, "12",#PB_Text_Right)
TextGadget(#Text_1, 10, 10, 90, 16, "Anzahl der Werte")
TextGadget(#Text_2, 20, 216, 110, 16, "Erwartungswert")
TextGadget(#Text_3, 20, 236, 110, 16, "Standardabweichung")
TextGadget(#Text_4, 20, 196, 110, 16, "mittl. Abweichung (%)")
TextGadget(#Text_5, 20, 256, 110, 16, "Extreme < 0")
TextGadget(#Text_6, 20, 276, 110, 16, "Extreme > 99")
TextGadget(#Text_7, 10, 30, 110, 16, "Erwartungswert")
TextGadget(#Text_8, 10, 50, 110, 16, "Standardabweichung")
TextGadget(#Text_2a, 124, 216, 36, 16, "?",#PB_Text_Right)
TextGadget(#Text_3a, 124, 236, 36, 16, "?",#PB_Text_Right)
TextGadget(#Text_5a, 124, 256, 36, 16, "?",#PB_Text_Right)
TextGadget(#Text_6a, 124, 276, 36, 16, "?",#PB_Text_Right)
TextGadget(#Text_9, 90, 108, 50, 16, "Anzahl:",#PB_Text_Right)
TextGadget(#Text_10, 124, 196, 36, 16, "?",#PB_Text_Right)
Frame3DGadget(#Frame_0,10,176,160,120,"errechnete Werte")
StartDrawing(WindowOutput(0)) ;der Einfachheit halber, statt eines Image-Gadgets
Box(181,4,413,276,$000000)
Box(183,6,410,273,$FFFFFF)
StopDrawing()
EndIf
EndProcedure
Open_Window_0()
Repeat ; Start of the event loop
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadget() ; Is it a gadget event?
EventType = EventType() ; The event type
;You can place code here, and use the result as parameters for the procedures
If Event = #PB_Event_Gadget
If GadgetID = #Button_0
Gosub Gleichverteilt
ElseIf GadgetID = #String_0
ElseIf GadgetID = #Button_1
Gosub Zwoelf
ElseIf GadgetID = #Button_2
Gosub Polar
ElseIf GadgetID = #Button_3
Gosub BoxMuller
EndIf
EndIf
Until Event = #PB_Event_CloseWindow ; End of the event loop
End
Anzeige:
Mittel.f= Summe.l/z
For k=0 To 99
AbwQSu.f=AbwQSu+((k-Mittel)*(k-Mittel)*Wert(k,0)) ;Aufsummierung Quadrate der Abweichung für "Standardabweichung"
Next
StanAbw.f=Sqr(AbwQSu/z) ;Berechnung dewr Standardabweichung
StartDrawing(WindowOutput(0))
Box(181,4,413,276,$000000) ;Darstellungsfläche löschen
Box(183,6,410,273,$FFFFFF)
For i=0 To 99 ;Darstellungsschleife 1 bis 100
x= i*4+190 ;Darstellung der Häufigkeit der Zufallszahlen
y= -Wert(i,0)
xx=i*4+191
yy=-Wert(i,1) ;Darstellung des Idealverlaufes der Häufigkeit
Line(x,272,0,y)
Line(xx,272,0,yy,$4A50FC)
Next
DrawText(190,10,Bezeichnung$,Farbe) ;Bezeichnung des Verlaufs
StopDrawing()
SetGadgetText(#Text_2a,StrF(Mittel,2)) ;tatsächl. Mittelwert My eintragen
SetGadgetText(#Text_3a,StrF(StanAbw.f,2)) ;tatsächl. Standartabweichung Sigma eintragen
SetGadgetText(#Text_5a,Str(Extrem0)) ;Anzahl der Werte die kleiner als 1 sind
SetGadgetText(#Text_6a,Str(Extrem99)) ;Anzahl der Werte die größer als 99 sind
Summe =0 ;Rückstellung der Variblen
AbwQSu=0
Extrem0=0
Extrem99=0
Return
Gleichverteilt:
;gleichverteilte Zufallszahlen erzeugen
Bezeichnung$="gleichverteilte Zufallszahlen"
Farbe=$F70D08
z=Val(GetGadgetText(#String_0)) ;Anzahl der erzeugten gleichverteilten Zufallszahlen
DisableGadget(#String_1,1) ;Inaktivschaltung der nichtbenutzten String-Gadgets
DisableGadget(#String_2,1)
DisableGadget(#String_3,1)
For i=0 To 99 ;Werte der Feldvariblen auf "Null" setzen
Wert(i,0)=0
Next
For i= 1 To z-1 ;z gleichverteilte Zufallszahlen in 100 Kategorien erzeugen
a=Random(99)
Wert(a,0)=Wert(a,0)+1 ;Zufallswerte in Feldvariable eintragen
Summe=Summe+a ;Aufsummierung der erzeugen Zahlen
Next
Erw=z/100 ;Theoretische Anzahl pro Zahl berechnen
For i=0 To 99 ;Werte in Feldvarible einschreiben
Wert(i,1)=Erw
Next
Gosub Genau ;Genauigkeit der Zufallszahlen berechnen
Gosub Anzeige ;Werte anzeigen
Return
Zwoelf:
;normalverteilte Zufallszahlen nach dem Grenzwertsatz erzeugen, auch als Zwölferregel bekannt. In diesem Verfahren kann
;auch die Anzahl der gleichverteilten Zufallszahlen je normalverteilte Zufallszahl eingestellt werden. Wird "1" eingegeben,
;so ist die erzeugte Zufallszahl gleichverteilt. Eine Eingabe von "12" entspricht konkret der Zwölferregel.
Bezeichnung$="normalverteilte Zufallszahlen, Grenzwertsatz"
Farbe=$00A000
z=Val(GetGadgetText(#String_0)) ;Anzahl der erzeugten gleichverteilten Zufallszahlen
mit=Val(GetGadgetText(#String_1)) ;Mittelwert My vorgeben
sta=Val(GetGadgetText(#String_2)) ;Standardabweichung Sigma vorgeben
Anzahl=Val(GetGadgetText(#String_3)) ;Aus wievielen Werte soll normalverteilte Zahl errechnet werden?
DisableGadget(#String_1,0) ;Aktivierung der nötigen String-Gadgets
DisableGadget(#String_2,0)
DisableGadget(#String_3,0)
For i=0 To 99 ;Werte der Feldvariblen auf "Null" setzen
Wert(i,0)=0
Next
For i= 0 To z-1 ;Berechnung der "z" normalverteilten Zufallszahlen
For j= 0 To Anzahl-1 ;Erzeugung von "Anzahl" gleichverteilten Zufallszahlen
b.f= b+Random(99)
Next
Faktor.f=8.333/Sqr(Anzahl/12) ;Empirisch gefundene Berechnung auf Standardabweichung=1
a1.f=((b/Anzahl)-49.5)/Faktor
a=a1*sta+mit ;normalverteilte Zufallszahl mit Mittelwert und Standardabweichung
If a<0
Extrem0=Extrem0+1 ;extreme Werte < Null Mit dem Grenzwerverfahren erzielt man
ElseIf a>99 ; normalverteilte Zahlen, die alle im Bereich
Extrem99=Extrem99+1 ;extreme Werte > 99 der gleichverteilten Zahlen liegen!
Else
Wert(a,0)=Wert(a,0)+1 ;Werte in Feldvarible schreiben
EndIf
Summe.l=Summe+a ;Aufsummierung der Zufallszahlen
b=0
Next
Gosub Normalverteilung ;Normalverteilungskurve zum Vergleich erzeugen
Gosub Genau ;Genauigkeit der Zufallszahlen berechnen
Gosub Anzeige ;Werte anzeigen
Return
Polar:
;normalverteilte Zufallszahlen nach dem Polarverfahren erzeugen. Werte: - bis + unendlich
Bezeichnung$="normalverteilte Zufallszahlen, Polarmethode"
Farbe=$00A000
z=Val(GetGadgetText(#String_0)) ;Anzahl der erzeugten gleichverteilten Zufallszahlen
mit=Val(GetGadgetText(#String_1)) ;Mittelwert My vorgeben
sta=Val(GetGadgetText(#String_2)) ;Standardabweichung Sigma vorgeben
DisableGadget(#String_1,0) ;Aktivierung der nötigen String-Gadgets
DisableGadget(#String_2,0)
DisableGadget(#String_3,1)
For i=0 To 99 ;Werte der Feldvariblen auf "Null" setzen
Wert(i,0)=0
Next
For i= 1 To z/2-1 ;Berechnung der "z" normalverteilten Zufallszahlen
Sprung:
y1.f=(Random(999)+1)/1000 ;2 gleichverteilte Zufallszahlen erzeugen
y2.f=(Random(999)+1)/1000
q.f=(2*y1-1)*(2*y1-1) + (2*y2-1)*(2*y2-1)
If q>1
Goto Sprung ;Wenn "q.f" > 1, dann zwei neue gleichverteilte Zufallszahlen erzeugen
EndIf
p.f=Sqr((-2*Log(q))/q)
a=(2*y1-1)*p*sta+mit ;2 normalverteilte Zufallszahlen berechnen
c=(2*y2-1)*p*sta+mit
If a<0 Or c<0
Extrem0=Extrem0+1 ;extreme Werte < Null
ElseIf a>99 Or c>99
Extrem99=Extrem99+1 ;extreme Werte >99
Else
Wert(a,0)=Wert(a,0)+1 ;Werte a und c in Feldvariable schreiben
Wert(c,0)=Wert(c,0)+1
EndIf
Summe.l=Summe+a+c ;Aufsummierung der Zufallszahlen
Next
Gosub Normalverteilung ;Normalverteilungskurve zum Vergleich erzeugen
Gosub Genau ;Genauigkeit der Zufallszahlen berechnen
Gosub Anzeige ;Werte anzeigen
Return
BoxMuller:
;normalverteilte Zufallszahlen nach dem Box-Muller-Algorithmus erzeugen. Werte: - bis + unendlich
Bezeichnung$="normalverteilte Zufallszahlen, Box-Muller-Algorithmus"
Farbe=$00A000
z=Val(GetGadgetText(#String_0)) ;Anzahl der erzeugten gleichverteilten Zufallszahlen
mit=Val(GetGadgetText(#String_1)) ;Mittelwert My vorgeben
sta=Val(GetGadgetText(#String_2)) ;Standardabweichung Sigma vorgeben
DisableGadget(#String_1,0) ;Aktivierung der nötigen String-Gadgets
DisableGadget(#String_2,0)
DisableGadget(#String_3,1)
For i=0 To 99 ;Werte der Feldvariblen auf "Null" setzen
Wert(i,0)=0
Next
For i= 1 To z-1
u1.f=(Random(999)+1)/1000 ;2 gleichverteilte Zufallszahlen erzeugen
u2.f=(Random(999)+1)/1000
a=Cos(2*3.1416*u1)* Sqr(-2*Log(u2))*Sta+mit ;daraus eine normalverteilte Zufallszahl berechnen
If a<0
Extrem0=Extrem0+1 ;extreme Werte < Null
ElseIf a>99
Extrem99=Extrem99+1 ;extreme Werte >99
Else
Wert(a,0)=Wert(a,0)+1 ;Werte in Feldvarible schreiben
EndIf
Summe.l=Summe+a ;Aufsummierung der Zufallszahlen
Next
Gosub Normalverteilung ;Normalverteilungskurve zum Vergleich erzeugen
Gosub Genau ;Genauigkeit der Zufallszahlen berechnen
Gosub Anzeige ;Werte anzeigen
Return
Normalverteilung:
;Normalverteilungskurve mit vorgegebenen Werten für My und Sigma erzeugen. Vergl. Wikipedia
For k=0 To 99 ;Werte berechnen Korrekturfaktoren k1.f, h2.f und h3.f sind empirisch
k1.f=(k-mit)/10 ;ermittelt worden!
h2.f=z/sta/2.6 ;Höhe der Kurve
h3.f=50/Pow(sta,2) ;Breite der Kurve
h.f= h2*Pow(2.7182,-h3*k1*k1) ;Berechnung der 100 Werte
Wert(k,1)=h ;Werte für Vergleich in Feldvariable schreiben
Next
Return
Genau:
;Die Genauigkeit der Verteilung verdoppelt sich ca. mit dem Vierfachen der Anzahl z
For i=0 To 99
Gen.l=Gen+Abs(Wert(i,0)-Wert(i,1)) ;Abweichungen vom Idealverlauf absolut aufaddieren
Next
Prozent.f=Gen*100/z ;Reative durchscnittliche Abweichung in % berechnen
SetGadgetText(#Text_10,StrF(Prozent,2)) ;Anzeigen der Abweichung
Gen=0 ;Summierungsvariable auf "Null" setzen
Return