Arduino i pseudo-slučajni niz

Zvanični priručnik na https://www.arduino.cc/reference/en/ preporučuje da se za početnu vrednost (seed) generatora pseudo-slučajnih brojeva, funkcije random(), koristi rezultat očitavanja napona sa nepovezanog analognog ulaza. Na primer:

randomSeed(analogRead(0));

To će raditi, ali rezultati koje daje ADC sa nepovezanog analognog ulaza kreću se u vrlo malom rasponu i ponavljaju se prečesto. Ako se randomSeed(analogRead(0)); koristi ponovljeno, makar posle svakog reseta – velike su šanse da će kasniji “slučajni” brojevi činiti nizove koji se ponavljaju.

Pod uslovom da period između dve upotrebe funkcije ili od momenta reseta nije uvek jednak (tj. ako zavisi od dovoljno slučajnog unosa spolja, trenutka pritiska na taster ili sličnog), bolje je pustiti jedan tajmer-brojač da se što brže vrti, pa koristiti njegovo trenutno stanje kao osnovu za argument funkcije randomSeed(). Ponegde sam ovaj brojač (uz deljenje po modulu) može biti dobar izvor pseudo-slučajnih brojeva, bez upotrebe namenskih funkcija. Specifično Arduino: millis(), micros().

Takođe, važno je imati u vidu da funkcija random() ima “kuriozitet”, tj. “feature” 🙂 : ako je argument funkcije randomSeed() pozitivan i nije veći od 127773, a potom se pozove random() sa parametrom “max” koji ima vrednost deljivu sa sedam, dobiće se “slučajan” broj deljiv sa sedam. Na primer, prvo pozivanje random(14) dalo bi 0 ili 7. Samo prvo pozivanje.

A ako je argument funkcije randomSeed() pozitivan i manji od osam, a vrednost parametra “max” deljiva je sa sedam, najmanje prva dva “slučajna” broja biće celobrojni umnošci broja sedam.

Vrlo slično bude ako je argument funkcije randomSeed() negativan i veći od -127774, a vrednost parametra “max” deljiva sa sedam; samo što se, umesto umnožaka broja sedam, dobijaju brojevi koji pri deljenju sa sedam daju ostatak 1. (Za seed 5 ili -5, prvih pet “slučajnih” brojeva imaju istu i predvidivu deljivost u odnosu na broj 7.)

Nije “kriv” Arduino, nego AVR-Libc, jer je funkcija odatle.

Ako je argument funkcije randomSeed() jednak nuli, biće zanemaren, a seed će biti 123459876.

Dakle, funkciju  randomSeed() uvek treba koristiti sa argumentom većim od 127773, tip je unsigned long. Biće (pseudo-)OK.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s