Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Painotettu arvonta

op.tutkija [29.01.2011 07:32:07]

#

Tiedän toki miten Basicissäni generoidaan (pseudo)satunnaislukuja, mutta nyt pitäisi tuottaa lukuja joissa suuret numerot ovat todennäköisempiä kuin pienet (numeroista 1-8). Esim. Veikkaus käyttää joskus painotettua arvontaa perutuissa otteluissa jolloin vaihtoehtojen 1 x 2 todennäköisyydet määräytyvät pelatuimmuusprosentin mukaan.

Ihan heti keksin vain kömpelön tavan näihin painotettuihin lukuihin data- lauseiden avulla, olisikohan niihin parempaa konstia ?

Chiman [29.01.2011 08:44:01]

#

Arvo raakaluku joltain väliltä, jolla on eripituisia alueita, joista jokainen edustaa yhtä halutuista kohdeluvuista.

Käytännön esimerkki:
122333444455555666666777777788888888
Tuossa on 36 merkin pituinen alue, josta arvot yhden merkin (kokonaisluku 1-36). Koska isompien lukujen alue on pidempi, ne ovat todennäköisempiä.

jutti [29.01.2011 09:41:05]

#

Olen unohtanut basicin kokonaan, mutta jos jossain uudessa basicissa on olio-ohjelmointimahdollisuus, sitä kannattaa yrittää. Tein joskus C++:lla olion, joka ratkaisi tämän. Ensin syötettiin olioon kaikki numerot, joita haluaa tuotta sekä niiden todennäköisyydet:

noppa.lisaa(1, 10);
noppa.lisaa(2, 20);
noppa.lisaa(3, 15);
noppa.lisaa(4, 12);
noppa.lisaa(5, 7);
noppa.lisaa(6, 5);

Eka argumentti on silmäluku, toka on luvun todennäköisyys - ei prosentteina vaan osuutena kaikista syötetyistä. (1, 10) tarkoittaa siis että ykkösen todennäköisyys on 10/69. Sitten vaan noppaa heittämään tyyliin:

tulos = noppa.heita();

Olioon pystyi milloin tahansa lisäämään muita silmälukuja tai muuttamaan jonkin silmäluvun todennäköisyyttä.

Arpominen tapahtuu suunnilleen Chimanin kuvaamalla tavalla. Olio pitää seuraavanlaista taulukkoa:

1 10 10
2 20 30
3 15 45
4 12 57
5 7  64
6 5  69

...jossa kolmannessa sarakkeessa on kumuloitu jokaisen silmäluvun todennäköisyys. Ensin arvotaan luku välillä 0-69. Sitten etsitään kolmannesta sarakkeesta ensimmäinen luku joka on suurempi tai yhtä suuri kuin arvottu luku. Siltä riviltä poimitaan ensimmäisen sarakkeen silmäluku.

op.tutkija [29.01.2011 14:16:34]

#

Kiitos vastauksista. Chimanin ehdotus oli samantapainen kuin itsekin pähkäilin, eli arvon normaaliin tapaan numeron merkkijonosta jossa suuria numeroita on sopivasti enemmän. Jos jonosta tulee liian pitkä luen numerot data- lauseista.

Käyttämässäni IBM:n Basicassa ei muistaakseni ole olio- ohjelmointimahdollisuutta mutta käytössäni on myös vanha Quick- Basic (Q-Basicin isoveli) jossa sellainen mahdollisuus saattaisi olla, jahka kielitaidottomana saan sen tarkistettua englanninkielisistä manuaaleista. Tapaan muuten koodata Basicalla ja ajaa Qb: llä koska se on joskus nopeampi, tulkkaavalla kielellä tehdyt ohjelmathan toimivat kääntäjässäkin kunhan ne ovat tallennettu tekstitiedostona esim. SAVE"X",A

User137 [29.01.2011 15:44:34]

#

Suuremmilla määrillä (50+) ei ole ehkä viisasta tallentaa pitkiä merkkirimpsuja jotka vain toistavat itseään.

Itsellä tulee mieleen tämän tapaista (pascal):

Joka luvulla on oma tietotyyppi

TLuku = record
  maara: integer;
  alku: integer;
end

var
  luvut: array[1..6] of TLuku;

function Arvo: integer;
var
  yht, i, satunn: integer;
begin
  yht:=0;
  for i:=1 to 6 do begin
    luvut[i].alku:=yht;
    yht:=yht+luvut[i].maara;
  end;
  satunn:=random(yht);
  for i:=6 downto 1 do
    if (satunn>=luvut[i].alku) and (luvut[i].maara>0) then begin
      result:=i;
      exit;
    end;
  result:=-1; // Tulee tälle riville vain jos kaikkien maara = 0
end;

op.tutkija [29.01.2011 16:41:33]

#

Kiitti, pascalia en tunne yhtään mutta tietotyyppilukuja voin sulatella. tämä painotettu arvonta on vain osa suurempaa kokonaisuutta joten kieltä en lähde vaihtamaan, ja arvelisin että merkkijonosta ei tule kovin pitkää.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta