ZeRKoX Skrevet 7. desember 2010 Del Skrevet 7. desember 2010 Hei. Driver å lære meg C++ for tiden, og tenker å lage et program som trekker en tallrekke til et lotteri. En sentral funksjon i programmet skal ta inn intervallet den skal trekke fra, og hvor mange den skal trekke, og så lagre de numrene de har trukket i en array. Det skal også være slik at den ikke kan trekke to nummer samme gang. Jeg har laget funksjonen, og den fungerer, men lurer litt på om det er ting jeg burde gjort annerledes, og om den virkelig er random? Vil denne funksjonen ha like stor sjans til å trekke hvilket som helst tall? void lag_trekkeliste(int premier[], int min, int max, int ant_trekk){ //Funksjon som returnerer en array over bool lodd[MAXSOLGT * 1000]; //Bool array holder styr på hvem som har vunnet. // vinnerlodd, slik som spesifisert. int premie; //Premie: int til å holde et trukket tall. for(int i = 1; i <= ant_trekk; i++) { do { //Looper til den trekker et lodd premie = rand() % max; // som ikke allerede er trukket, } while (!lodd[premie] || premie < min); // og som er større enn minsteverdi. lodd[premie] = true; //Merker dette nummeret som trukket. premier[i] = premie; //Legger vinnernummer i premier-arrayen. } } Lenke til kommentar
Diskutant Skrevet 7. desember 2010 Del Skrevet 7. desember 2010 (endret) Ikke at jeg er vanvittig god på dette, men den virker random.. Ikke hør på meg. Hør på de faglærte! Endret 8. desember 2010 av Diskutant Lenke til kommentar
Sigdal Skrevet 7. desember 2010 Del Skrevet 7. desember 2010 (endret) Dette har jeg faktisk vært borti: Du bør bruke srand(time(0)) i main for å initialisere rand() - da vil du få vilkårlige tall om du ikke kjører funksjonen flere ganger pr sekund. Ellers kan du bruke mtrandom() som er en randomfunksjon med større periode enn rand(). Så har du vel en liten feil i loopen: du får bare 'antall_trekk - 1' iterasjoner. Endret 7. desember 2010 av Sigdal Lenke til kommentar
ZeRKoX Skrevet 7. desember 2010 Forfatter Del Skrevet 7. desember 2010 (endret) rand() vil i denne funksjonen kjøres mange ganger per sekund, da jeg kan trekke 500 nummer i slengen f.eks. Hva blir konsekvensen av at den kjøres for ofte? Like tall muligens? I så fall har jeg jo sikret meg mot det, med å sjekke om tallet er trukket før? Hva gjør srand(time(0))? Skal den bare legges inn som en egen linje under main? Til nå har jeg bare inkludert cstdlib for å få rand() til å virke. EDIT: Hva du mener er feil i loopen? Den gir rett antall trekk. Endret 7. desember 2010 av ZeRKoX Lenke til kommentar
Sigdal Skrevet 7. desember 2010 Del Skrevet 7. desember 2010 (endret) Om du kjører hovedprogrammet mer hyppigere enn hvert sekund så mener jeg du vil få samme tallrekke fra rand()-funksjonen, siden time(0) returnerer sekundverdier kun. Ville løst seg om det fantes en tidsfunksjon som returerer millisekunder... Noen som har det? Les litt om det på nettet mvh S Loopen: for(int i = 0; i <= ant_trekk; i++) Endret 7. desember 2010 av Sigdal Lenke til kommentar
ZeRKoX Skrevet 7. desember 2010 Forfatter Del Skrevet 7. desember 2010 Ahh. Jeg bruker ikke premier[0]. Gammel uvane... Men min loop kjører fremdeles ant_trekk ganger. Din loop går ant_trekk+1. Lenke til kommentar
GeirGrusom Skrevet 8. desember 2010 Del Skrevet 8. desember 2010 Hva gjør srand(time(0))? Skal den bare legges inn som en egen linje under main? Til nå har jeg bare inkludert cstdlib for å få rand() til å virke. Random funksjoner genererer ikke tilfeldige tall i utgangspunktet. Altså den tar et tall (en såkalt seed) og genererer et tall utifra det, og når algoritmen er ferdig, inkremeneteres seed med 1. Setter du seed til 0 hver gang programmet starter, vil programmet oppføre seg helt likt hver gang (dette er forøvrig grunnlaget for generering av brett i Minecraft) Det srand gjør, er å sette seed tallet. Idéen er at hvis du setter seed til nåværende klokkeslettet vil du få et så tilfeldig resultat som er mulig. Om det engang finnes tilfeldige tall er noe en kan diskutere i filosofi-kategorien, men datamaskinen er ihvertfall ikke istand til å generere et tilfeldig tall. Vi bruker istedet en algoritme som gir et resultat som virker tilfeldig over et stort interval. Lenke til kommentar
Dead_Rabbit Skrevet 8. desember 2010 Del Skrevet 8. desember 2010 Random-implementasjonene i standardbiblitoeket er pseudorandom. På UNIX-systemer (finnes sikkert noe tilsvarende på Windows), har man funksjoner som benytter /dev/random til å samle ekte tilfeldig data. Det vil normalt si støy som er samlet fra drivere, etc. Problemet med å bruke time(0) som seed, er at hvis du har et grovt estimat over når kallet blir gjort, så er det rimelig greit å gjette seg til den eksakte seeden, og dermed få den samme dataen fra pseudo-random number generatoren. I eksempelet ditt, så er jo ikke dette noe katastrofe, men hvis man trenger random data for å f.eks. generere kryptografiske nøkler, bør man sørge for å initialisere RNGen med random data fra /dev/random, og ikke bruke tiden som seed. Lenke til kommentar
GeirGrusom Skrevet 8. desember 2010 Del Skrevet 8. desember 2010 Random-implementasjonene i standardbiblitoeket er pseudorandom. På UNIX-systemer (finnes sikkert noe tilsvarende på Windows), har man funksjoner som benytter /dev/random til å samle ekte tilfeldig data. Det vil normalt si støy som er samlet fra drivere, etc. Problemet med å bruke time(0) som seed, er at hvis du har et grovt estimat over når kallet blir gjort, så er det rimelig greit å gjette seg til den eksakte seeden, og dermed få den samme dataen fra pseudo-random number generatoren. I eksempelet ditt, så er jo ikke dette noe katastrofe, men hvis man trenger random data for å f.eks. generere kryptografiske nøkler, bør man sørge for å initialisere RNGen med random data fra /dev/random, og ikke bruke tiden som seed. Men dette er ganske Unix spesifikt, så en vil måtte implementere dette to ganger. I Windows bruker man CryptGenRandom eller RltGenRandom. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå