« Dynnet newsletter | Main | Bra bloggtips »

oktober 27, 2003

Myntfördelningen - en gåta mindre

I Nya rön om mynt-estimering skrevs bland annat om hur mina växelmynt fördelades empiriskt:
MyntAntalVärde(SEK)
10kr1711710
5kr2651325
1 kr849849
50 öre202101

En liten fråga ställdes om vad denna fördelning beror på. Speciellt noterades att det fanns så många 1-kronor jämfört med övriga myntslag. För att citera: Studiet av myntfördelning måste alltså anses vara ett senare forskningsprojekt..

Sedan är nu!

Vi gör en simulering av olika värden av pengar tillbaka vid ett köp, från 0 till 19.50 SEK. Anledningen till att större värden än 19.50 inte tas med är att vi antar att de i så fall returneras i sedlar, dvs 20-kronors sedlar etc (som, tyvärr, inte är studieobjekt för tillfället).

Följande förutsättningar görs:
- Kassören har tillräckligt med mynt för att kunna göra en "optimal" växel, dvs med så få mynt som möjligt.
- Vi antar att alla olika växelvärden är lika sannolika, dvs det är lika stor chans att få tillbaka 19.50 som 2.00.
- All betalning görs endast med sedlar och vi använder alltså aldrig några mynt för betalning (ny!)

Logiken i simuleringen är följande:

För varje pengar-tillbaka-situation:
1. Simulera pengar-tillbaka-värde, från 0.0 .. 19.50 SEK.
Dessa kan endast vara jämna kronor eller 50-öringar.

2. Från detta värde undersök hur många 10-, 5-, 1-kronor, samt 50-öringar vi får (vid en optimal växel).

Om man simulerar flera olika sådana pengar-tillbaka-körningar, får vi även en summa av det totala värdet av växelmynten.

Här är R-koden som simulerar detta. (Systemet R finns som vanligt på www.r-project.org.)

Generering av växel (0 - 19.50)
> (0:39)/2
 [1]  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0
[16]  7.5  8.0  8.5  9.0  9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5
[31] 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5


Funktionen return.change returnerar hur många 10-, 5-, 1-kronor resp 50-öringar som krävs för en "optimal växling", dvs med målet att det ska bli så få mynt som möjligt. Funktionen returnerar:
antal 10-kronor,5-kronor,1-kronor,50-öringar

return.change <- function(money=19.50) {
   coins <- c(10, 5, 1, 0.5)
   dist <- c(0,0,0,0)
   for (i in 1:4) {
     if (money > 0) {
       while (money >= coins[i]) {
         dist[i] <- dist[i] + 1
         money <- money - coins[i]
       } 
     }
   }
   dist
}
# return.change()
Funktionen change.simulate gör själva simuleringen, med parametern n som är antalet pengar-tillbaka-situationer.

Returvärdet är:
dist : antal 10-kronor,5-kronor,1-kronor,50-öringar
dist.sum : totalsumman

Här kan vi alltså både jämföra med fördelningen av antalet myntslag och den empiriska totalsumman (som var 3985 SEK).

change.simulate <- function(n=10) {
   dist <- c(0,0,0,0)
   for (i in 1:n) {
     ss <- sample( (0:39)/2, 1, replace=T)
     dist <- dist + return.change(ss)
   }
   coins <- c(10, 5, 1, 0.5)
   # total value of money
   dist.sum <- sum(dist * coins)
   list(dist=dist, dist.sum=dist.sum)
}
# change.simulate(100)

Så körs vi!

Ett mål är att komma så nära den empiriska fördelningen och totalsumman som möjligt, dvs
 dist:      171 265 849 202
 dist.sum:  3985
Några exempelkörningar.

Först kör vi med 100 växlingar:
> change.simulate(100)
$dist
[1]  49  39 180  53

$dist.sum
[1] 891.5
Sedan med 1000 körningar:
> change.simulate(1000)
$dist
[1]  494  514 2017  495

$dist.sum
[1] 9774.5
500 körningar. Vi börjar närma oss.
> change.simulate(500)
$dist
[1] 260 249 953 248

$dist.sum
[1] 4922
Följande är ganska likt den fördelning som jag faktiskt fick. Cirka 800 1-kronor, samt övriga kring 200 stycken.
$dist
[1] 179 215 852 208

$dist.sum
[1] 3821
Låt oss nu se om medelvärdet av totalsumman för 100 sådana körningar motsvarar det empiriska 3985.
> mean(replicate(100, change.simulate(400)$dist.sum) )
[1] 3932.04

Medelvärdet 3932 får nog anses vara tillräckligt bra.

Varför n=400?
Hur ska vi nu förklara värdet n=400? Det är alltså antal pengar-tillbaka-situationer som görs i simuleringen. Om vi nu gör en liten efterkonstruktion så innebär det att under de cirka 2 år som jag sparat växelmynten, har jag fått växelpengar ungefär varannan dag. Faktiskt inte helt orealistiskt.

Detta skulle t.ex. innebära att under ett års sparande (med n=200) skulle det blir följande fördelning och totalsumma:
> change.simulate(200)          
$dist
[1] 109 106 383 105

$dist.sum
[1] 2055.5

Återstoden
Det krävs naturligtvis mer empirisk data för att testa modellen, så nästa undersökning kan göras ungefär oktober 2005. Eftersom simuleringen verkar visa på en rätt realistisk modell, återstår att göra en mer formell analys av fenomenet. Vi får se när detta sker...

Koppling till vikt/volym: Naturligtvis borde de respektive myntsorterna ha vägts, men så gjordes inte. Sådant är dock ganska enkelt att göra närhest vid behov.

Uppdatering
Det skulle nog även vara bra med en medelvärdeskörning för själva fördelningen med n=400, och inte bara på totalsumman.:
> ss <- apply(replicate(100,change.simulate(400)$dist),1,mean)
> ss
[1] 199.69 202.17 802.75 199.31

> sum(ss*c(10,5,1,.5))
[1] 3910.155
Dvs cirka 800 1-kronor, och cirka 200 övriga mynt-sorter.

En medelvärdeskörning för n=1, dvs ett enda pengar-tillbaka-tillfälle är enligt följande, där vi kan köra 10000 sådana simuleringar eftersom det inte tar så lång tid:
> ss <- apply(replicate(10000,change.simulate(1)$dist),1,mean)
> ss
[1] 0.4961 0.5022 2.0037 0.5012

> sum(ss*c(10,5,1,.5))
[1] 9.7263

Dvs i medelvärde cirka 2 stycken 1-kronor, och respektive 0.5 övriga myntsorter. Medelvärdet för totalsumman är cirka 9.73 SEK.

Egentligen skulle vi ju bara behövs ha dessa värden, resten kan man projicera fram. Låt oss gå baklänges:

Vi har 849 stycken 1 kronor, vilket n-värde får vi och hur ser den övriga fördelningen ut. Eftersom vi vet att vi får igenom snitt 2 1-kronor per pengar-tillbala-situation blir n = 849/2 = 424.5 ~ 425.

De övriga mynten ska fördela sig med 1/4 av antalet 1-kronor, vilket innebär: 212.25 stycken 10-or, 5-or respektive 50-öringar.

Låt oss nu testa detta mot simuleringen
> ss<-apply(replicate(100,change.simulate(425)$dist),1,mean)
> ss
[1] 214.18 212.06 853.00 211.35
> sum(ss*c(10,5,1,.5))
[1] 4160.775
Tja, det är en bra utgångspunkt i alla fall.

Posted by hakank at oktober 27, 2003 04:36 EM Posted to Diverse

Comments

Antagandet "All betalning görs endast med sedlar och vi använder alltså aldrig några mynt för betalning (ny!)" stämmer mycket bra på mig. Jag har inget myntfack i plånboken och betalar nästan uteslutande med sedlar.

Gällande fördelningen kan det vara av intresse att jag nästan aldrig använder mynt när jag parkerar (utan bensinkort eller betalning via mobilen). Det enda jag regelbundet använder mynt för är att köpa cola (8 kr) på jobbet. Oftast betalar jag med en femkrona och tre enkronor.

Posted by: Marcus at oktober 28, 2003 02:51 EM

Om colaköpen: Troligen inte helt ovanligt, så jag får nog försöka få in sådana beteenden i modellen.

Hur ofta är regelbundet?

Posted by: Håkan Kjellerstrand at oktober 29, 2003 12:05 EM