Numeron arvonta php:llä

Antti

Administraattori
Ylläpitäjä
Liittynyt
27.12.1998
Viestit
1967
Sijainti
Suomi
Yhden numeron arpomiseen välillä 1-y olen käyttänyt seuraavaa riviä:

Koodi:
$number = rand (1, y);
toimii hyvin, mutta miten arvon viisi eri numeroa välillä 1-y niin ettei mitkään numerot ole keskenään samoja?

y on joku luku, vaikka 30. Eli arpoja antaisi esim. numerot 2, 12, 15, 20, 24.
 

vermula

Well-known member
Liittynyt
1.2.2001
Viestit
12921
Tee silmukka, jossa lisaat aina arvotun luvun taulukkoon, jos se ei jo esiinny taulukossa (tsekataan siis joka kerta). lopeta silmukka kun taulukkon koko on 5.
 

vermula

Well-known member
Liittynyt
1.2.2001
Viestit
12921
Meniskö jotenki näin
Koodi:
$luvut = array();
while( count($luvut)<5 )
{
  $luku = rand (1, y);
  $on_jo = false;
  for( $i=0; $i<count($luvut) && $on_jo==false; $i++)
  {
    if( luvut[$i]==$luku) on_jo = true;
  }
  if ( $on_jo == false ) array_push($luvut, $luku);
}
 

Antti

Administraattori
Ylläpitäjä
Liittynyt
27.12.1998
Viestit
1967
Sijainti
Suomi
Thanks, näyttää toimivan kunhan korjaa hieman syntaksia

Koodi:
$luvut = array();
while( count($luvut)<5 )
{
  $luku = rand (1, 30);
  $on_jo = false;
  for( $i=0; $i<count($luvut) && ($on_jo==false); $i++)
  {
    if($luvut[$i] == $luku): $on_jo = true; endif;
  }
  if ( $on_jo == false ): array_push($luvut, $luku); endif;
}

print "luku 1 on " . $luvut[0];
print "<br>";

print "luku 2 on " . $luvut[1];
print "<br>";

print "luku 3 on " . $luvut[2];
print "<br>";

print "luku 4 on " . $luvut[3];
print "<br>";

print "luku 5 on " . $luvut[4];
print "<br>";
 

Asko S.

Tonttu
Liittynyt
1.3.2002
Viestit
4146
Sijainti
Tampere
Tuota, tuota... Tuossa on periaattessa ikuisen silmukan vaara. No, eihän se tietenkään siihen jää, mutta voi se kuitenkin tehdä ohjelmasta tehottomamman...

Yleensä tuollaisissa ohjelmissa joka kierros (=yhden numeron arvonta) pienennätään ylärajaa yhdellä, ja jos arvottu numero sattuu olemaan taulukossa, arvottuun numeroon lisätään yksi.

Pseudoa:

numero1 = random(1-30)
numero2 = random(1-29)
jos numero2==numero1 -> numero2++
numero3 = random(1-28)
jos numero3==numero1 -> numero3++
jos numero3==numero2 -> numero3++
...

Ööö... No tossa kyllä oletettu, että numero1 on pienempi ku numero2... En muista enää miten ton aikoinaan oon toteuttanu, mutta idea varmaan selkis...
 

vermula

Well-known member
Liittynyt
1.2.2001
Viestit
12921
Asko S. sanoi:
Tuota, tuota... Tuossa on periaattessa ikuisen silmukan vaara. No, eihän se tietenkään siihen jää, mutta voi se kuitenkin tehdä ohjelmasta tehottomamman...
Ei kyllä ole ikuisen silmukan vaaraa.. ellei php:n random ole niin surkea että alkaa toistaa muutamaa numeroa ikuisesti. Eikä kovin tehotonkaan kun arvotaan vain viisi numeroa.

numero1 = random(1-30)
numero2 = random(1-29)
jos numero2==numero1 -> numero2++
Ööö.. en ihan ymmärrä, miksi vähennetään ydellä?
Mikä idea siinä oikein on, myöhemmät luvuthan ovat sitten pienemmällä välillä, mikä taas on tarkoituksen vastainen. Pitäisi numero2:nkin voida saada suurin mahdollinen luku, ellei se sitten ole jo numero1:llä.
 

abc

DNF
Liittynyt
14.2.2000
Viestit
12558
Askon algoritmi ei taida arpoa tasaisesti? Eikös tuolla tuu luonnottoman paljon peräkkäisiä lukuja?
 

H_Hihhuli

Well-known member
Liittynyt
23.2.2001
Viestit
1971
VJR sanoi:
Askon algoritmi ei taida arpoa tasaisesti? Eikös tuolla tuu luonnottoman paljon peräkkäisiä lukuja?
Näinhän siinä käy.

Arvottavat numerot voisi alustaa taulukkoon ja jokaisen arvonnan jälkeen poistetaan arvottu numero taulukosta.


Oletetaan että taulukossa ovat seuraavat numerot:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Jos ensimmäisellä kierroksella tulee esim. kolmonen, seuraavalla kierroksella arvotaan joukosta

1, 2, 10, 4, 5, 6, 7, 8, 9


Näin päästään minimimäärällä tasaisia arvontoja.
 

Dominic

Senior Member
Liittynyt
9.2.2000
Viestit
47813
Sijainti
Turku
Mä oisin varmaan tehny niinku vermula taikka sitten niin, jotta jos arvotaan jo taulukossa olevan luku ni lisätään siihen 1, ja katotaan vieläkö löytyy taulukosta, lisäillään sitä ykköstä siihen niin kauan että sitä lukua ei enää löydy taulukosta (jos menee rajojen yli ni pyöräytetään vaikka alarajannumeroksi ja jatketaan ykkösellä lisäilyä kunnes se vapaa numero löytyy.

Ja joo, ei varmastikaan tehoikkain mahdollinen tapa....
 

Dominic

Senior Member
Liittynyt
9.2.2000
Viestit
47813
Sijainti
Turku
H_Hihhuli sanoi:
Näinhän siinä käy.

Arvottavat numerot voisi alustaa taulukkoon ja jokaisen arvonnan jälkeen poistetaan arvottu numero taulukosta.


Oletetaan että taulukossa ovat seuraavat numerot:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Jos ensimmäisellä kierroksella tulee esim. kolmonen, seuraavalla kierroksella arvotaan joukosta

1, 2, 10, 4, 5, 6, 7, 8, 9


Näin päästään minimimäärällä tasaisia arvontoja.
Vaikuttais iha fiksulta, ainakin näin äkkiseltään.
 

vermula

Well-known member
Liittynyt
1.2.2001
Viestit
12921
Dominic sanoi:
Vaikuttais iha fiksulta, ainakin näin äkkiseltään.
Jep. Mutta saattaa olla tehoton, jos lukualue josta arvotaan, on suuri. Taulukosta poisto voi olla suhteellisen hidas. Eri algoritmit sopii eri tapauksiin :thumbup:
 

Wilpuri

Senile Member
Liittynyt
28.6.1999
Viestit
9041
Sijainti
hki
Dominic sanoi:
taikka sitten niin, jotta jos arvotaan jo taulukossa olevan luku ni lisätään siihen 1, ja katotaan vieläkö löytyy taulukosta, lisäillään sitä ykköstä siihen niin kauan että sitä lukua ei enää löydy taulukosta (jos menee rajojen yli ni pyöräytetään vaikka alarajannumeroksi ja jatketaan ykkösellä lisäilyä kunnes se vapaa numero löytyy.

Tuossa systeemissä esim. arvottaessa kaksi numeroa numeroista 1,2,3, jos eka numero sattuisi arpoutumaan kakkoseksi, toiseksi numeroksi olisi sen jälkeen kolmosella suurempi todennäköisyys, sehän nimittäin luvuksi tulisi jos random antaisi alunperin joko jo aiemmin tulleen kakkosen tai sitten vielä arpomattoman kolmosen. Ykkönen saataisiin vain silloin jos random todella ykkösen antaisi suoraan.
 

Asko S.

Tonttu
Liittynyt
1.3.2002
Viestit
4146
Sijainti
Tampere
VJR sanoi:
Askon algoritmi ei taida arpoa tasaisesti? Eikös tuolla tuu luonnottoman paljon peräkkäisiä lukuja?
No siis tuossa on se idea, että eka arvotaan koko joukosta, sitten seuraavalla kerralla "poistetetaan" yksi luku arvonnasta.

1) 1,2,3,4,5 -> arvonnasta 3
2) 1,2,4,5 -> arvonnasta 1
3) 2,4,5 -> arvonnasta 4
...

Eli tossa kolmoskohdassa arvotaan arvoalueella 1-3, ja lisätään yksi, koska arvottu numero on 1 tai suurempi. Sit lisätään vielä yksi koska numero on 3 tai suurempi.Tossa mun pseudossa olikin näppi/ajatusvirhe:

numero1 = random(1-30)
numero2 = random(1-29)
jos numero2>=numero1 -> numero2++
numero3 = random(1-28)
jos numero3>=numero1 -> numero3++
jos numero3>=numero2 -> numero3++
...

Edelleen tossa on oletettu, että numero1 on pienempi ku numero2...
 
Viimeksi muokattu:

Dominic

Senior Member
Liittynyt
9.2.2000
Viestit
47813
Sijainti
Turku
Wilpuri sanoi:
Tuossa systeemissä esim. arvottaessa kaksi numeroa numeroista 1,2,3, jos eka numero sattuisi arpoutumaan kakkoseksi, toiseksi numeroksi olisi sen jälkeen kolmosella suurempi todennäköisyys, sehän nimittäin luvuksi tulisi jos random antaisi alunperin joko jo aiemmin tulleen kakkosen tai sitten vielä arpomattoman kolmosen. Ykkönen saataisiin vain silloin jos random todella ykkösen antaisi suoraan.
Tuli tuossa mieleen että tietystihän voi generoida yhden ylim. random numeron joka on 0 tai 1, ja sen perusteella joko vähentää tai lisätä...
 

abc

DNF
Liittynyt
14.2.2000
Viestit
12558
Asko: Vaatiiko algoritmisi lukujen järjestelyä jokaisen numeron arpomisen jälkeen?
 

Dominic

Senior Member
Liittynyt
9.2.2000
Viestit
47813
Sijainti
Turku
Tuossa VJR:n kanssa tuumittiin, niin tuo hihhulin systeemi ois ainaki mun mielestä tosi hyvä... ja toteuttaa sen vois linkitetyllä listalla..

ts.

arvottavat_numerot on linkitetty lista.

lisäillään numerot 1-39 sisään listaan. (39 linkkiä)

arvotaan jokin linkeistä (1-linkkien määrä)

otetaan numero ulos linkistä ja poistetaan linkki. (linkkien määrä -1)

toistetaan 7 kertaa.
 

Asko S.

Tonttu
Liittynyt
1.3.2002
Viestit
4146
Sijainti
Tampere
VJR sanoi:
Asko: Vaatiiko algoritmisi lukujen järjestelyä jokaisen numeron arpomisen jälkeen?
Siltä näyttäisi... Tosin en muista että niin olisin aikoinaan tehnyt, mutta en nyt yht'äkkiä keksi mitään muutakaan ratkaisua.

Edit: Toi mitä domppari sano, kuulostais fiksulta.
 
Viimeksi muokattu:

Asko S.

Tonttu
Liittynyt
1.3.2002
Viestit
4146
Sijainti
Tampere
Ylös