Trädvy Permalänk
Medlem
Registrerad
Jul 2018

Sannolikhet

Låt oss säga att iag spelar ett lotto med 8% chans att vinna, hur skriver jag ett program som testar det låt säga hundra gånger, och visar hur många gånger programmet vann.

Är det möjligt?

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

I vilket språk? Vilken slags erfarenhet har du?
Det är hur som helst ett enkelt program att skriva. Går att få fram på 1-2 rader i vissa språk.

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 2x8 GB 3200 MHz CL16 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Registrerad
Aug 2011
Skrivet av Dissociativ:

Låt oss säga att iag spelar ett lotto med 8% chans att vinna, hur skriver jag ett program som testar det låt säga hundra gånger, och visar hur många gånger programmet vann.

Är det möjligt?

Öppna en ny flik i Chrome, tryck F12.

(function () { var count = 0; for (var i = 0; i <= 100; i++) { if (Math.floor(Math.random() * 100 + 1) <= 8) { count++; } } console.log("Program won " + count + " times!"); })();

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av Dissociativ:

Låt oss säga att iag spelar ett lotto med 8% chans att vinna, hur skriver jag ett program som testar det låt säga hundra gånger, och visar hur många gånger programmet vann.

Är det möjligt?

C++ är väl en av det enklaste, vi säger att jag inte har särskilt stor erfarenhet, bara lite baskunskaper var ju typ 10 år eller mer jag provade på programmering, provade även python.

En färdig kod för operationen skulle verkligen uppskattas, eller hur jag ska formulera det.

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av kronwalled:

Öppna en ny flik i Chrome, tryck F12.

(function () { var count = 0; for (var i = 0; i <= 100; i++) { if (Math.floor(Math.random() * 100 + 1) <= 8) { count++; } } console.log("Program won " + count + " times!"); })();

Tack så mycket jag kan bara lägga in det i C++? Vet att olika program kan skilja lite om jag kom ihåg, sen kompilera?

Trädvy Permalänk
Medlem
Registrerad
Jul 2018

Jag änvänder fortfarande xp så jag behövde använda en äldre version till compilern jag hittade, men det står "Please remember to use the '-X' option when running setup" men det är jag ska skriva in -X i kommand promten när man högerklickar?

Men om ni vet än annan compiler som stöder xp, tar jag gärna en länk, om det inte går att använda koden i andra språk som stöder xp tar jag gärna dem, vet inte om scriptet är specifickt till ett visst språk

Trädvy Permalänk
Medlem
Registrerad
Jul 2017
Skrivet av Dissociativ:

Jag änvänder fortfarande xp så jag behövde använda en äldre version till compilern jag hittade, men det står "Please remember to use the '-X' option when running setup" men det är jag ska skriva in -X i kommand promten när man högerklickar?

Men om ni vet än annan compiler som stöder xp, tar jag gärna en länk, om det inte går att använda koden i andra språk som stöder xp tar jag gärna dem, vet inte om scriptet är specifickt till ett visst språk

Han gav dig en javascript kod du kan ha i webbläsaren.

Förenklade för dig:

http://jsfiddle.net/gpryc27f/7/

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av JeanC:

Han gav dig en javascript kod du kan ha i webbläsaren.

Förenklade för dig:

http://jsfiddle.net/gpryc27f/7/

Tack så mycket.

Trädvy Permalänk
Medlem
Registrerad
Jul 2018

Om jag vill lära mig ett språk, vilket ska jag börja med? Och vars hittar jag en bra Introduktion/guide.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

@JeanC: Det var schysst att du gjorde en egen sida åt TS, men ditt program räknar fel. Kör 1% vinstchans och 1000000 varv.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008
Skrivet av Dissociativ:

Om jag vill lära mig ett språk, vilket ska jag börja med? Och vars hittar jag en bra Introduktion/guide.

Du ställer fel fråga. Eller rättare sagt, du har fel inställning. Du vill lära dig programmera och det är det som är det viktiga, inte vilket språk du använder. När du fått lite rutin är det inte svårt att lära sig ett nytt språk.

Jag brukar rekommendera Python för nybörjaren. Det är lätt att komma igång och det är enkelt att använda strängar, listor och tupler. Sök bara på "Python MOOC" och du hittar massor med kurser som kör Python.

Trädvy Permalänk
Medlem
Registrerad
Jul 2017
Skrivet av Ingetledigtnamn:

@JeanC: Det var schysst att du gjorde en egen sida åt TS, men ditt program räknar fel. Kör 1% vinstchans och 1000000 varv.

Ah jag såg fel och skrev fel med slump-metoden.

http://jsfiddle.net/gpryc27f/22/

så. Men håller med; är bättre att han lär sig själv.

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av Ingetledigtnamn:

@JeanC: Det var schysst att du gjorde en egen sida åt TS, men ditt program räknar fel. Kör 1% vinstchans och 1000000 varv.

Kan du elaborera? Du kan använda matematiska uttryck, och skriva ett bevis om du vill. Sannolikhetsteori, var ju längesen och Matte A (Matte 1 nu, tror jag.) Jag gjorde bättre ifrån mig på C och D (3 och 4?).

För många år sedan nu, för att komma ihåg det. Jag vet att man ska multiplicera sannolikheten för varje gång, eller det kanske beror på, kom ihåg att exemplet var kasta en tärning.

Typ, sannolikheten att slå en sexa är 1/6, att slå den igen är (1/6) x (1/6) = 1/36, ingen aning om det stämmer, eller en kan appliceras i det här fallet.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

@Dissociativ: Det var bara JeanCs program som räknade fel. Om du angivit 8% vinstchans så fick man run 70000 vinster när man körde 1000000 varv. Det var extra tydligt om man körde med 1% för då fick man 0 vinster. Skulle gissa på att en test som borde gjorts med <= gjordes med < och då ligger man 1% fel i vinstchans.

Trädvy Permalänk
Medlem
Registrerad
Aug 2011
Skrivet av Dissociativ:

Kan du elaborera? Du kan använda matematiska uttryck, och skriva ett bevis om du vill. Sannolikhetsteori, var ju längesen och Matte A (Matte 1 nu, tror jag.) Jag gjorde bättre ifrån mig på C och D (3 och 4?).

För många år sedan nu, för att komma ihåg det. Jag vet att man ska multiplicera sannolikheten för varje gång, eller det kanske beror på, kom ihåg att exemplet var kasta en tärning.

Typ, sannolikheten att slå en sexa är 1/6, att slå den igen är (1/6) x (1/6) = 1/36, ingen aning om det stämmer, eller en kan appliceras i det här fallet.

När du behöver en viss sekvens av händelser att slå in multiplicerar du deras sannolikheter på det viset.

Men när du har 100 numrerade bollar, och gör 100 dragningar (och sedan lägger tillbaks bollen i tunnan) är varje dragning oberoende av föregående. Då kommer du att endast hamna nära 8 "rätt" per 100 dragningar pga den variation som förekommer. Drar du däremot 1000000 bollar kommer du att hamna väldigt nära 8% rätt då slumpen är negligerbar över ett så stort antal.

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av Ingetledigtnamn:

@Dissociativ: Det var bara JeanCs program som räknade fel. Om du angivit 8% vinstchans så fick man run 70000 vinster när man körde 1000000 varv. Det var extra tydligt om man körde med 1% för då fick man 0 vinster. Skulle gissa på att en test som borde gjorts med <= gjordes med < och då ligger man 1% fel i vinstchans.

Därför jag inte förstod den stora mängden vinster på hans script. Tack för förklarigen

Trädvy Permalänk
Medlem
Registrerad
Jul 2018
Skrivet av kronwalled:

När du behöver en viss sekvens av händelser att slå in multiplicerar du deras sannolikheter på det viset.

Men när du har 100 numrerade bollar, och gör 100 dragningar (och sedan lägger tillbaks bollen i tunnan) är varje dragning oberoende av föregående. Då kommer du att endast hamna nära 8 "rätt" per 100 dragningar pga den variation som förekommer. Drar du däremot 1000000 bollar kommer du att hamna väldigt nära 8% rätt då slumpen är negligerbar över ett så stort antal.

Jag förstår, tack så mkt för förklaringen, det är rätt uppenbart när du förklarar.

Trädvy Permalänk
Medlem
Plats
Uppsala
Registrerad
Dec 2008

Vad är det egentligen du vill veta? Din ursprungliga fråga ledde oss helt fel.

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

Vill bara påpeka att lösningar på formen

randomInteger = random() % range

inte är korrekt, ändå ser man detta rätt ofta som svar (inte i denna tråd dock!). Det duger absolut för enkla exempel, men det skulle aldrig få användas i program där man har krav på en perfekt distribution av slumptalen.

Orsaken är att om assert(MAX_RANDOM % range == 0) misslyckas, vilket det kommer göra för de flesta värden på range, så blir vissa av de lägre talen [0..range) sannolikare än andra.

Bl.a. JavaScript som visas ovan använder sig av en funktion som returnerar ett flyttal i det halvöppna intervallet [0.0, 1.0), det blir korrekt och enkelt att generera en jämn fördelning (men finns ju andra fördelningar som är lämpliga i andra lägen). Eller tror i alla fall det blir korrekt (använder mest C och C++ i jobbet). Man blir lite nervös när man läser Pythons beskrivning

Citat:

random.uniform(a, b)

Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.

The end-point value b may or may not be included in the range depending on floating-point rounding in the equation a + (b-a) * random().

Om b kan inkluderas har man ett rätt stort problem!!!

Här är ett exempel i C++11 där ovan nämnda potentiella problem garanterat inte finns. Något mer komplicerat jämfört med många andra språk, men fördelen är att man delat upp det hela i de tre logiska delmoment som man alltid måste beakta:

  1. generera en "bra" frö till sin slumpmässiga serie

  2. val av lämplig funktion för att generera en serie "pseudo random" tal

  3. skapa en specifik distribution inom ett givet intervall

#include <random> #include <iostream> #define PERCENT_WIN_CHANCE 8u #define ROUNDS 100u int main() { // Get some "real" random value, generated in HW on modern ARMs and x86 // CPUs. Reading this device is quite expensive. // // https://en.wikipedia.org/wiki/RdRand // // On an Intel Core i7-7700K, 4500 MHz (45 x 100 MHz) processor (Kaby // Lake-S microarchitecture), a single RDRAND or RDSEED instruction takes // 110ns or 463 clock cycles, regardless of the operand size (16/32/64 // bits). This number of clock cycles applies to all processors with // Skylake or Kaby Lake microarchitecture. On the Silvermont // microarchitecture processors, each of the instructions take around 1472 // clock cycles, regardless of the operand size; and on Ivy Bridge // processors it takes up to 117 clock cycles.[18] // // On an AMD Ryzen CPU, each of the instructions takes around 1200 clock // cycles for 16-bit or 32-bit operand, and around 2500 clock cycles for a // 64-bit operand. std::random_device rndDev; // As it is slow to read from random devices, such device should only be // used to generate a good seed to a function that can generate a pseudo // random series that satisfies the required statistical properties. // // This example uses Mersenne Twister: // https://en.wikipedia.org/wiki/Mersenne_Twister std::mt19937 rndGen(rndDev()); // Clamp the random number generated into an _uniform_ integer range // [1..100] (represent minim chance to win for counting as a win in this // example). std::uniform_int_distribution<unsigned> dist(1, 100); // Run the simulation for ROUNDS rounds. auto wins = 0u; for (auto round = 0u; round < ROUNDS; round++) { auto randomInt = dist(rndGen); if (randomInt <= PERCENT_WIN_CHANCE) { wins++; } } std::cout << wins << " wins in " << ROUNDS << " rounds with " << PERCENT_WIN_CHANCE << "% to win." << std::endl; }

Att simulera slumpmässiga händelse är ett relativt komplext problem på en datorn, mycket då datorer normalt sett ska göra exakt samma sak varje gång. Program som uppför sig slumpmässiga är i de flesta fall buggiga

Overkill för detta exempel, men väldigt viktigt om man faktiskt skrev ett program där pengar är involverat.

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer