FUNCTION LOTTO, n, m, start, CUT=cut, SAME=same ;=============================================================================== ; (c) 1992 - khd c/o FU BERLIN. A l l r i g h t s r e s e r v e d. || ; No part of this software package may be reproduced, transmitted, || ; transcribed, stored in a retrieval system, or translated into || ; any form by any means without the w r i t t e n permission of || ; Karl-Heinz Dittberner-FU BERLIN, Arnimallee 22, D-1000 Berlin 33 || ;=============================================================================== ; PRO:LOTTO.PRO K.-H. Dittberner - 15.MRZ.1992 ; V 01.5 P 476/35 - 14.SEP.1992 ; ; IDL(V2.1)-Routine: Erzeugen einer Zufallszahlenfolge "n aus m" nach dem ; Lotto-Prinzip. Es wird eine Folge von n Zahlen aus dem ; Bereich [1..m] gezogen. ; ; HINWEISE: Ist im Aufruf die Output-VAR 'start' angegeben und bleibt ; diese im uebergeordneten Programm unveraendert, wird bei ; jedem Aufruf von LOTTO die beim 1. Aufruf begonnene Folge ; fortgesetzt und keine neue Zahlenfolge angefangen. ; ; Dieses Funktions-UP verwendet die IDL-Funktion "RandomU", ; die eine gleichverteilte Zufallszahlenfolge im Bereich ; [0..0,999...] erzeugt. ; Die Programmierung erfolgte nach Park and Miller: ; "Random Number Generators: Good ones are hard to find", ; Comm. ACM, Vol.31, No.10, 1192 (Okt.1988). ; ; KEYWORDS: ; ; /CUT = Zerlegung der erzeugten Zufallszahlen in 2 Komponenten; ; z.B. zur Bildung von Indizes (Index-Generator) fuer ein ; "Random Shuffling" von Datensaetzen (Versuchsperson und ; Reizart bzw. 'categorie'). ; /SAME = Damit kann fuer Tests eine immer identische Folge der ; Zufallszahlen erzeugt werden. Eine Angabe der VAR 'start' ; wird ignoriert. ; ; Quelle: Do-it-yourself! Merkposten: o ; C92 250 o Zerlegung statist. testen. ; o ; Aufruf: z = Lotto(16,64 [,start, /CUT]) o ; o ;=============================================================================== ; Aenderungen: [15/3/92-khd] => V 01.0: ; - Algorithmus formuliert + mit Mathematica vorgetestet. ; [14/4/92-khd] => V 01.1: ; - 1. Experimentalversion ist fertig. ; [16/4/92-khd] => V 01.2: (Copy => AG GRUE + PRZY) ; - Mit /CUT Algorithmus fuer die Zerlegung implementiert. ; [23/4/92-khd] => V 01.3: ; - Weitere Tests mit Mathematica (siehe Notebook vom 23/4/92). ; - Keyword /TEST => /SAME umbenannt. ; - Im Aufruf optionale VAR 'start' eingefuehrt. Damit ist nun ; ein Wiedereinstieg in die einmal begonnene Sequenz moeglich. ; - Kommentierung modifiziert und ergaenzt. ; [29/4/92-khd] => V 01.4: (Copy => PRZY + SEIDLER) ; - On_Error,2 aktiviert. ; [14/9/92-khd] => V 01.5: (Copy => FUHRY) ; - Multiplikation der erzeugten Zufallszahl [0..0,999...] ; statt mit (m-1) nunmehr richtig mit m, was dann auch fuer ; z Integer-Zahlen im Bereich [1..m] erzeugt. ; HINWEIS: Fix schneidet nur den ganzzahligen Teil einer Real- ; Zahl ab; es wird vorher nicht gerundet! ; - Vor der Trennung in Indices (Keyword /CUT gesetzt) muss nun ; daher die Korrektur z=z-1 erfolgen. ;=============================================================================== ; 1. Prolog, Variablen und Konstanten: ;=============================================================================== On_Error, 2 ; Return => Ruf. Programm. double = 0L ; Doubletten-Zaehler. z = IntArr(1) q = m/n ; Achtung! Reine Integer-Division. ; ;=============================================================================== ; 2. Behandlung der Keywords (Default-Werte): ;=============================================================================== ; If Keyword_Set(same) then start = 1.0 ; ;=============================================================================== ; 3. Zufallszahlen-Generator: ;=============================================================================== ; z(0) = Fix(m*RandomU(start)) + 1 ; Start des Generators. For i=1,n Do Begin Repeat Begin x = Fix(m*RandomU(start)) + 1 t = Where((z eq x), double) ; Feststellen ob's ne Doublette ist. EndRep Until (double eq 0) ; Keine Doublette. z = [z,x] ; Zufallszahl zufuegen. Endfor ; ;=============================================================================== ; 4. Schluss: ;=============================================================================== ; Ende: If Not Keyword_Set(cut) $ then Return, z(1:n) $ else Begin ; Zufallszahl zerlegen: z = z - 1 ; Indices sollen von 0 laufen. zz = IntArr(n+1,2) zz(*,0) = z/q ; Achtung! Reine Integer-Division. zz(*,1) = z mod q Return, zz(1:n,*) Endelse END ;===============================================================================