![]() |
Zufallsfunktion
Hi,
ich suche eine Zufallsfunktion, die eine einigermassen gleichmaessige Verteilung ueber einem Intervall hat. Beispiel: Ich moechte, dass z.B. alle 30 bis 60 Tage ein bestimmtes Ereignis eintritt und dass nach 45 Tagen in 50% der Faelle das Ereignis eingetreten ist. Und nicht etwa dass in den Tagen 30-35 in 90% der Faelle das Ereignis eingetreten ist und sich die uebrigen 10% dann auf die Tage 35-60 aufteilen. Hat da jemand ne Idee? |
Re: Zufallsfunktion
Hallo,
als Zufallsfunktion würde ich "Random(x)", wobei das Ergebnis im Zahlenbereich von 0 bis x-1 liegt, empfehlen. Diese Funktion musst du aber erst mit Randomize irgendwo initialisieren.
Delphi-Quellcode:
Das müsste an und für sich gehen. Hoffe, es ist verständlich genug
if (tag > 30) and (tag < 60) then {Intervall von 30 Tagen}
x:= random(30) + 30; if tag = x then Ereignis; if tag = 45 then x2:= random(2); if x2 = 0 then tu_dies else tu_jenes; Gruß Stefan |
Re: Zufallsfunktion
Danke fuer deine Antwort. Aber leider hast du mich etwas missverstanden.
Die Tage sind die Zeit, die seit dem letzten "Ereignis" vergangen sind. Das Programm wird taeglich gestartet und wenn nun 30 Tage vergangen sind, wird mit einer bestimmten Wahrscheinlichkeit das "Ereignis" wieder eintreten und damit den Zaehler der vergangenen Tage wieder auf 0 setzen. Wurde das Ereignis am 30. Tag nicht ausgeloest, wird am 31. Tag wieder mit einer gewissen Wahrscheinlichkeit das Eintreten des Ereignisses bestimmt und so weiter. Die Wahrscheinlichkeit steigt hierbei weiter an, so dass spaetestens am 60. Tag das Ereignis ausgeloest wird. Wenn ich nun diesen Zyklus (30 * Faktor) durchlaufe, sollten am 30.Tag bei (1 * Faktor) der Durchlaeufe das Ereignis ausgeloest werden, am 31. Tag wiederum (1 * Faktor) etc. Wenn ich nun random(x)+y nehme, verteilt sich das dann beispielsweise so: Durchlaeufe: 10000 Intervall: 0-10 0: 945 1: 939 2: 849 3: 711 4: 424 5: 409 6: 371 7: 362 8: 351 9: 401 10: 4238 Die Verteilung sollte aber gleichmaessig bei ca. 1000 pro Tag liegen. |
Re: Zufallsfunktion
Hm, da kann ich dir leider nicht helfen, da hab ich gar keine Idee.
Tut mir leid. Vielleicht weiss ja jemand anders Bescheid. Gruß Stefan |
Re: Zufallsfunktion
a) Du berechnest schon am 30. Tag, wann das Ereignis das nächste Mal eintreten soll.
b) Falls das aus irgendwelchen Gründen nicht möglich sein sollte, benutzen wir eben unseren alten Freund Mathematik:
Delphi-Quellcode:
wird dir die gewünschte Gleichverteilung liefern.
Random(VerbleibendeTageInklusiveHeute) = 0
|
Re: Zufallsfunktion
Ich würde es so lösen:
Delphi-Quellcode:
Da die Wahrscheinlichkeit zwischen 1 und 0 50% ist, dürfte das den gewünschten Effekt erzielen.
function new_random(ugrenze, ogrenze: integer): integer;
var i: integer; begin Result := ugrenze; for i:=ugrenze to ogrenze do Inc(Result, Random(2)); end; // Edit: Stimmt, muss ja Random(2) heißen :oops: Flare |
Re: Zufallsfunktion
:gruebel: ? Willst du entweder 1 oder 0 generieren, musst du wie schon oben erwähnt Random(2) aufrufen. Wenn ich das richtig sehe, erzeugt deine Funktion allerdings eine Glockenkurve, also eine Normalverteilung.
|
Re: Zufallsfunktion
Zitat:
|
Re: Zufallsfunktion
nee:
Zitat:
|
Re: Zufallsfunktion
Kharlaki, Du musst einen Fehler gemacht haben. Weiterhin sind es 11 Ereignisse (0..10) und dann erwartet man bei 10000 Durchläufen 909 Treffer. Passiert mir aber auch immer wieder.
Hier, schau mal; 1x Button, 1x Memo, Doppelklick auf Button und dann;
Delphi-Quellcode:
Liefert
Procedure TForm1.Button1Click (Sender : TObject);
Const ccSamples = 1000000; Var Tage : Array [30..60] Of Integer; iZufallstag, iSumme, iZaehler : Integer; Begin FillChar (Tage, SizeOf (Tage), 0); For iZaehler:=1 to ccSamples do Begin iZufallsTag := 30 + Random (31); // <==== *blink* hier ist die magische Zufallsfunktion ;-) inc (Tage[iZufallsTag]); End; Memo.Lines.Clear; iSumme := 0; For iZaehler:= 30 to 60 do begin inc (iSumme, Tage[iZaehler]); memo.Lines.add(Format ('Tag %d: %d, %3.1f %% ',[iZaehler,Tage[iZaehler],iSumme*100/ccSamples])); End; End;
Was man aber nicht erwarten darf, das bei 31 Versuchen garantiert alle Tage getroffen werden. Wenn das erwünscht ist, dann bietet sich nur eine zufällige Permutation an. Dann ist das nur nicht mehr zufällig, sondern vermischt. Aber dafür nach jeweils 31 Durchläufen garantiert gleichverteilt. |
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Es scheint um Delphi zu gehen. |
Re: Zufallsfunktion
Danke fuer eure Beitraege! :)
Wenn ich den Tag vorrausberechne, an dem das Ereignis eintreten soll, reicht ein einfaches random(x)+y. Das waere ja simpel. ;) Ich muss aber an jedem Tag neu berechnen, ob das Ereignis eintreten soll und damit muss die Wahrscheinlichkeit mit jedem Tag ansteigen, so dass spaetestens am letzten Tag des Intervalls (ob Tag 30 bis Tag 60 oder Tag 31 bis Tag 60 ist egal, da im Programm-Setup einstellbar) das Ereignis eingetreten ist, ohne dass bei zig Durchlaeufen das Ereignis meistens schon in den ersten Tagen eingetreten ist oder in 90% der Durchlaeufe am letzten Tag eingetritt. Irgendwie scheine ich mich wohl unklar auszudruecken. %-) Sorry! P.S. Matze, kannst du den Fred bitte wieder zurueckschieben? Es geht hier ja nicht um Delphi spezifisches, sondern um einen speziellen Algoritmus. |
Re: Zufallsfunktion
Aha.
Also: Am 30.Tag : "If Random (31) = 0 then Ereignis_Ausloesen" Am 31.Tag : "If Random (30) = 0 then Ereignis_Ausloesen" ... Am 60.Tag : "If Random (1) = 0 then Ereignis_Ausloesen" So etwa, stimmts? Wenn dann 'Ereignis_Ausloesen' den Tageszähler wieder auf 0 setzt, dann solltest Du das doch hinbekommen... Weiterhin kannst Du dir einfach die Zahl '30+Random(31)' bzw. das Datum (Heute + Zufallszahl) in die Registry/eine INI-Datei/die EXE schreioben und dann jeden Tag schauen, ob dieses Datum erreicht wurde. Wenn ja, löst Du das Ereignis aus und schreibst ein neues Datum (30+Random(31) Tage in der Zukunft) in die Registry/INI-Datei/EXE. Hab ich's jetzt richtig verstanden? :zwinker: |
Re: Zufallsfunktion
Zitat:
[edit]Ah, Bestätigung tut immer gut ;) .[/edit] |
Re: Zufallsfunktion
Ehrlich gesagt, verstehe ich wirklich die Problematik nicht, Kharlanki.
Du hast also ein Programm, das täglich(?) oder ab und gestartet wird. Sei X der Tag, an dem das letzte Mal 'das Ereignis' aufgetreten ist. Ergo wird das nächste Ereignis zum Zeitpunkt "X + 30 + Random (31)" auftreten. Das ist doch wohl klar. Wieso kannst Du das nicht im Voraus berechnen, irgendwo abspeichern und beim Programmstart einfach fragen, ob der Zeitpunkt erreicht oder überschritten wurde? Ich kapier's nicht. :wall: Na ja, bin wohl zu alt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz