Autor |
Beitrag |
jackie05
      
Beiträge: 357
|
Verfasst: Mo 08.08.11 20:37
Hallo,
gibt es eine möglichkeit 3 Zufallszahlen zu erzeugen die zusammen 50 ergeben?
Die Zufallszahlen sollen zwischen 5 und 50 liegen, z.B:
Zufallszahl 1: 7
Zufallszahl 2: 26
Zufallszahl 3: 17
oder so
Zufallszahl 1: 5
Zufallszahl 2: 37
Zufallszahl 3: 8
Die 3 Zufallszahlen sollen halt immer Zusammengerechnet 50 ergeben.
Wie könnte man das realisieren?
Ich bedanke mich schonmal im Voraus.
MfG
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 08.08.11 20:38
Moin!
Erzeuge zwei und bilde die Differenz.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
jackie05 
      
Beiträge: 357
|
Verfasst: Mo 08.08.11 20:42
Danke Dir.
Ich denke nicht das es so gehen könnte, weil wenn die 2 Zufallszahlen 25 oder mehr haben, dann sind es ja schon 50 oder mehr.
Wie soll ich die ambesten erzeugen?
MfG
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 08.08.11 21:08
Dann überlege einmal, wie du die Erzeugung der Zahlen anhand der bereits erzeugten einschränken musst, damit so etwas nicht auftritt. Die Tripel sind dann nicht mehr perfekt gleichverteilt, aber ich nehme mal an, das ist nicht ganz so wichtig?
_________________ >λ=
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mo 08.08.11 21:38
Wenn man Zufallszahlen einzuschränken versucht, dann schränkt man auch den Zufall ein.
Kha hat folgendes geschrieben : | Die Tripel sind dann nicht mehr perfekt gleichverteilt, aber ich nehme mal an, das ist nicht ganz so wichtig? |
Nicht nur "nicht perfekt", sondern gar nicht mehr. Bereits die Summe zweier Gleichverteilungen führt zu einer Dreiecksverteilung. Addiert man noch eine gleichverteilte Zufallsgröße dazu, wird die Verteilung noch schmaler, man entfernt sich vom gleichverteilten Zufall noch mehr.
|
|
gehstock
      
Beiträge: 19
Erhaltene Danke: 2
|
Verfasst: Mo 08.08.11 21:42
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mo 08.08.11 22:09
|
|
jackie05 
      
Beiträge: 357
|
Verfasst: Mo 08.08.11 22:17
Genau das hatte ich versucht gehabt und irgendwie hat es nicht so richtig funktioniert.
Vielen Dank für die Hilfe.
MfG
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mo 08.08.11 22:20
Was soll daran "irgendwie nicht richtig funktionieren"? Natürlich funktioniert so etwas! Mit der Addition wird die (gleichverteilte) Zufallsvariable auf dem Zahlenstrahl um eben 5 nach oben verschoben, also erhöht. Damit die andere, die obere Spitze auch korrekt ist, muß man den Zufallszahlenbereich eben um genau den gleichen Betag reduzieren.
Ohne Quellcode ist nicht ersichtlich, wo Dein Problem steckt.
|
|
jackie05 
      
Beiträge: 357
|
Verfasst: Mo 08.08.11 23:28
Danke Dir.
Ich bin dabei ein Spiel zu schreiben mit jeweils 3 Runden, jede Runde wird eine Zahl generiert und alle 3 Runden sollen dann dementsprechend mit den generierten Zahlen die Zahl 50 ergeben.
So hatte ich es testhalber versucht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| if (RundeNr = 1) then begin Zahl := random(40-5)+(5); tmpZahl := (50-Zahl); end; if (RundeNr = 2) then begin Zahl := random((tmpZahl div 2)-5)+(5); tmpZahl := (tmpZahl-Zahl); end; if (RundeNr = 3) then begin Zahl := tmpZahl; tmpZahl := (tmpZahl-Zahl); end; |
leider ohne erfolg.
Jetzt habe ich den vorschlag von @gehstock eingebaut und nun funktioniert es.
Vielen Dank.
MfG
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mo 08.08.11 23:46
Implementiere statt der drei Abfragen bezüglich der Rundennummer besser nur eine (1) case-Anweisung.
Daß gestocks Code funktioniert, mag schon sein, doch das widerlegt nicht, daß Zufallszahlen in einem bestimmten Zahlenbereich mit der Methode (nicht im objektorientierten Sinne gemeint), wie ich Sie zeigte, generierbar sind. Der Fehler muß also woanders stecken. Vielleicht zeigst Du auch noch Deinen nunmehr erfolgreichen Code, damit man vergleichen kann.
Postscriptum: Das @-Zeichen (at = an (... gerichtet)) vor gehstock ist wahrlich überflüssig, da Du ihn offensichtlich nicht ansprichst.
|
|
Blup
      
Beiträge: 174
Erhaltene Danke: 43
|
Verfasst: Fr 12.08.11 15:55
a:=5+random(35) liefert nur Zufallszahlen im Bereich 5..39, die 40 wird niemals geworfen.
Delphi-Quelltext 1: 2: 3: 4: 5:
| a := random(36); b := random(36 - a); a := a + 5; b := b + 5; c := 50 - (a + b); |
Dieser Ansatz kann aber keine gleichverteilte Zufallszahlen liefern:
Quelltext 1: 2: 3: 4:
| Wahrscheinlichkeit für die Zahl 40 a -> (1/36) // erster Wurf 40 b -> (1/36) * (1/36) // erster Wurf 5 + zweiter Wurf 40 c -> (1/36) * (1/36) // erster Wurf 5 + zweiter Wurf 5 |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Wahrscheinlichkeit für die Zahl 5 a -> (1/36) // erster Wurf 5 b -> (36/36) * (1/36) // erster Wurf beliebig + zweiter Wurf 5 c -> (1/36) * (1/36) + // erster Wurf 5 + zweiter Wurf 40 (1/36) * (1/35) + // erster Wurf 6 + zweiter Wurf 39 (1/36) * (1/34) + // erster Wurf 7 + zweiter Wurf 38 ... (1/36) * (1/1) // erster Wurf 40 + zweiter Wurf 5 . oder (1/36) * 36-te harmonische Zahl // "Harmonische Reihe" . n (1/36) * ( summe 1/k ) k = 1 |
--- Moderiert von Narses: Beiträge zusammengefasst---
Reihe der möglichen Kombinationen
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| a b c ------------- 5 5 40 -- 36 x 5 5 6 39 | 5 7 38 | 5 8 37 | 5 9 36 | ... | 5 40 5 - 6 5 39 -- 35 x 6 ... | 6 39 5 - 7 5 38 -- 34 x 7 ... | 7 38 5 - ... 38 5 7 -- 3 x 38 38 6 6 | 38 7 5 - 39 5 6 -- 2 x 39 39 6 5 - 40 5 5 -- 1 x 40 |
Betrachtet für die Werte der Variable a jeweils die Anzahl der Kombinationen, können diese so zu Pärchen zusammenfasst werden, daß die Summe der Kombinationen für jedes Pärchen konstant ist:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| 5 (36) 40 (1) 6 (35) 39 (2) 7 (34) 38 (3) ... 22 (19) 23 (18) . Gesamtanzahl der Kombinationen (36 / 2) * (36 + 1) = 666
Damit ergibt sich bei einer gleichmäßigen Verteilung die Wahrscheinlichkeit 5 -> 36/666 40 -> 1/666 |
Die einfachste Lösung des Problems ist, jeweils eine Kombination aus der Menge aller Kombinationen auszuwählen.
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: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| const ERROR_PARAMETER_RANGE = 'Paramter außerhalb des gültigen Bereichs'; . procedure GetDreierKomination50(n: Integer; out a, b, c: Integer); var x1, x2: Integer; begin if (n < 0) or (n > 665) then raise Exception.Create(ERROR_PARAMETER_RANGE); . x1 := (n div 37); x2 := (n mod 37); . if x2 < (36 - x1) then begin a := x1; b := x2; end else begin a := 35 - x1; b := x2 - (36 - x1); end; . a := a + 5; b := b + 5; c := 50 - (a + b); end; . procedure TForm1.ButtonTestClick(Sender: TObject); var n, a, b, c: Integer; begin Memo1.Lines.Clear; for n := 0 to 665 do begin GetDreierKomination50(n, a, b, c); Memo1.Lines.Add(Format('%2d %2d %2d', [a, b, c])); end; end; |
|
|