08. maj 2003 - 20:58Der er
27 kommentarer og 1 løsning
Seeding af rand()
Ok, her er mit spm, jeg har skrevet en dice roller, mest fordi jeg glemte mine terninger da jeg flyttede, og så fordi jeg syntes det kunne være sjovt. Jeg bruger en funktion der kan outputte et tilfældigt tal mellem 1 og 10. Men mit problem er tallene er ikke tilfældige nok.
Jeg seeder med time(0), er der ikke en måde jeg kan gøre tallene mere tilfældige?
Hvis du bruger: rand() % 10 så kan du muligvis forbedre en smule ved: (rand() / 1000) % 10
[rand() er som del andre random generatorer mere tilfældige i high bits end i low bits - det har stor betydning hvis man bruger modulus af en potens af 2 - muligvis har det også betydning med 10]
Der er også nogle algoritmer i Knuths Art of Computer Programming om hvordan man tager en kendt (dårlig) tilfældighedstalgenerator, og laver om til en god tilfældighedstalgenerator. Jeg har brugt dem i forbindelse med generering af kunstig hvid støj til digital billedbehandling.
Fremragende bog (eller rettere, bøger, der er tre bind). Også selvom man må leve med at der er søgealgoritmer optimeret efter hvor mange båndstationer du har til rådighed :-).
Cool nok, det er meget godt i kan smide en masse navne i hovedet på mig :> Men jeg ser gerne eksembler eller links, ok? Og jeg er ikke lige frem hardcore programør, så gerne noget 'lite'stuff, matematikken i det behøver ikke at være simpel, bare koden.
Jeg har implementeret gsl_rng_mrg (L'Ecuyer m.fk. 1993) i C:
#include <stdio.h> #include <stdlib.h>
static unsigned long int seed[5];
void mysrand(unsigned long int ss[]) { seed[0]=ss[0]; seed[1]=ss[1]; seed[2]=ss[2]; seed[3]=ss[3]; seed[4]=ss[4]; return; }
unsigned long int myrand() { unsigned long int res; int i; res=(107374182*seed[0]+104480*seed[4])%2147483647; seed[4]=seed[3]; seed[3]=seed[2]; seed[2]=seed[1]; seed[1]=seed[0]; seed[0]=res; return res; }
int main(int argc,char *argv[]) { unsigned long int ss[5]; int i; ss[0]=1234567; ss[1]=123; ss[2]=4444; ss[3]=987; ss[4]=12321; mysrand(ss); for(i=0;i<10;i++) { printf("%ld\n",myrand()); } exit(0); }
Bemærk iøvrigt at også for denne algoritme gælder at man skal kund srand'e en gang. Hvis man srand'er for hver kald til rand, så ødelægger man det totalt. Ligesom for standard srand/rand.
unsigned long int ss[5]; ss[0]=time(0); ss[1]=5454758; ss[2]=545452; ss[3]=9807; ss[4]=24578; mysrand(ss); int diff = 0; int dices = 0; int succ = 0; int roll = 0; int ones = 0;
cout<<"Welcome to the WoD Dice roller!"<<endl <<"Please enter difficulty...:"; cin>>diff; cout<<"...And number of dice:"; cin>>dices;
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.