Lisp »Tips 'n Tricks »Numeri casuali in AutoLISP »1 | 2 | 3 Un numero casuale è un numero estratto da un insieme di valori equiprobabili.
; Random number generator, from 0.000 to 0.999 (defun rn () (if (not sd) (setq sd (getvar "DATE"))) (setq md 65536 mx 25173 nc 13849 sd (rem (+ (* mx sd) nc) md) ) (setq nx (/ sd md)) ) (rn) applica, in modo parziale, il metodo x<-(a * x[i-1] + c) mod m (1) dove mod è l'operatore modulo che fornisce il resto della divisione (rem in Lisp), a c m sono numeri interi costanti e x è il "seme" (seed) della sequenza. Nell'esempio la x (sd) prende il valore della variabile DATE.
Il metodo completo è preso un numero intero arbitrario x lo si moltiplica per a (a * x), gli si aggiunge c (a * x + c) e si salva in x <- il resto della divisione per m (a * x + c) mod m, ripetendo n volte il procedimento x<-(a * x[i-1] + c) mod m.
Ecco un lisp che genera 100 numeri interi casuali compresi tra 0 e 99: ;;; rand.lsp - 15 Febbraio 2004 ;;; (C) by Claudio Piccini ;;; http://www.cg-cad.com/ ;;; ;;; Motore di numeri casuali ;;; (defun rn (sd) (setq m 100 b 25173 c 13849 sd (rem (+ (* b sd) c) m) ) ) (defun c:rand () (setq sd 1) (setq ls nil) (repeat 100 (setq sx (rn sd)) ; salva i numeri nella lista ls (setq ls (append ls (list sx))) (setq sd sx) ) ) ;;;eof Command: !ls
Con m=381 b=19 c=13849 e sd=0 il risultato è: Command: !ls
Con m=65521 b=15937 c=33503 e sd=0 (2) il risultato è: Command: !ls
Questo lisp migliora il motore di numeri casuali: ;;; rrand.lsp (ver. 1.0) - 15 Febbraio 2004 ;;; (C)2004 by Claudio Piccini ;;; http://www.cg-cad.com/ ;;; ;;; Motore di numeri casuali ;;; (defun rn (sd) (setq m 65521 b 15937 c 33503 sd (rem (+ (* b sd) c) m) ) (setq sd (* (/ sd m) 20)) ) (defun c:rrand () (setq sd 0.0) (setq ls nil) (repeat 100 (setq sx (rn sd)) ; salva i numeri nella lista ls (setq ls (append ls (list (fix sx)))) (setq sd sx) ) ) Command: !ls
Il numero 20 genera 100 numeri casuali compresi tra 0 e 19.
;;; rrand.lsp (ver. 1.1) - 15 Febbraio 2004 ;;; (C)2004 by Claudio Piccini ;;; http://www.cg-cad.com/ ;;; ;;; Motore di numeri casuali ;;; (defun rn (sd) (setq m 65521 b 15937 c 33503 sd (rem (+ (* b sd) c) m) ) (setq sd (* (/ sd m) r)) ) (defun c:rrand ( / f1 nomeDir nf) (setq sd 0.0) (setq nomeDir (getvar "dwgprefix")) (setq nf (strcat nomeDir "nc.txt")) (setq f1 (open nf "w")) (initget (+ 1 2 4)) (setq conta (getint "\nQuanti numeri? ")) (initget (+ 1 2 4)) (setq r (getint "\nIntervallo da 0 a? ")) (repeat conta (setq sx (rn sd)) ; salva la stringa sx (itoa sx) ; nel file NC.TXT (write-line (itoa (fix sx)) f1) (setq sd sx) ) (close f1) ) ;;;eof Con conta=20 e r=10 il risultato è: 5
(1) Algoritmi in C++, R. Sedgewick Ed. Addison-Wesley
Ultimo Aggiornamento_Last Update: 15 Febbraio 2004 |