normal verteilte Zufallszahlen
Verfasst: 20.02.2009 21:36
Hallo erstmal!
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.
P.S. Habe gerade gesehen, dass der Code nicht im Kasten angezeigt wird. Wie funktioniert das? Berti27
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