Przykładowy program wykorzystujący algorytm Monte Carlo w Pythonie.



Ostatnio mialem przyjemność pojechać na przegląd auta. Dowiedziałem się przy tej okazji, że przegląd każdego auta jest rejestrowany w systemie online, a co ważniejsze każdy wpis nie może odbyćsię częściej niż określony okres czasu.
Okazuje się że "urząd" zmierzył ile powinien trwać przegląd auta i w efekcie gdy stacja kontroli próbuje zakończyć przegląd za szybko, urząd uniemożliwia ten proceder, wskazując na słabą wnikliwość audytu.

Pytanie brzmi, jak określić optymalny czas przeglądu? W tym celu możemy posłużyć się metodą Monte Carlo. Zdobywając skromną próbkę czasu trwnia każdej z czynności (kontrola hamulców przednich, tylnich, ręczngo, świateł, klaksonu itd.) możemy wygenerować wręcz nieskończoną populację czasów trwania przeglądu,
aby na ich podstawie wyznaczyć prawdopodobne czasy wykonania kompletnego przeglądu.

Powyższe wyniki są obliczone dla wygenerowanych 11 scenariuszy, dla 5 czynności i 30 możliwych wariantów każdej z czynności.

import random
from matplotlib import pyplot as plt

plt.style.use('fivethirtyeight')
lista=[]
z=0
czynnosci = 5# ilość czynności następujących po sobie
licznik=0
wynik=[]
wersje=30   # możiwe wersje dla każdej czynności
scenario=11             # ilość scenariuzy jaką chcemy wygenerować
scenariusz=[]           # lista wygenerowanych scenariuszy
listawynikow=[]
indeks_wynikow=[]
szerokosc=.18
suma=0
w=0
s=0

for i in range(czynnosci):          # tworzymy populację wersji wydarzeń dla czynności
            for j in range(wersje):
                        
                        z=random.randint(1,10)
                        lista.append((i,z))

for j in range(scenario):           # dla określonej ilości scenariuszy generujemy losowo możliwe przebiegi
            for i in range (czynnosci):
                        zm=random.randint(0,1)
                        licznik=licznik+(lista[(i*10)+zm][1])
                     
            wynik.append(licznik)
            scenariusz.append(j)
            licznik=0
 
for i in range(scenario):
            listawynikow.append((wynik[i],scenariusz[i]))


print('-------------------------------------------------------------------------')
print('lista wynikow ',listawynikow)
print('-------------------------------------------------------------------------')
listawynikow.sort()     #sortujemy wyniki od najkrótszego do najdłuższego
print('lista wynikow posortowanych ',listawynikow)
print('-------------------------------------------------------------------------')
for i in range(len(listawynikow)):  # torzymy indeksy wyników
            indeks_wynikow.append(listawynikow[i][1])
print('indeks wynikow ',indeks_wynikow)
print('wynik ',len(wynik),' i ',wynik)
print('scenariusz ',len(scenariusz),' i', scenariusz)
# rysujemy podwójny wykres
fig, axs=plt.subplots(2)
axs[0].plot(scenariusz,wynik)
axs[1].plot(listawynikow)
plt.title('prognoza metodą Monte Carlo')
polowa=len(listawynikow)/2
print('z 50% prawdopodobieństwem czas wykonania nie przekroczy ',listawynikow[int(polowa)][0],' minut.')
dziewiecdziesiat=len(listawynikow)*.9
print('z 90% prawdopodobieństwem czas wykonania nie przekroczy ',listawynikow[int(dziewiecdziesiat)][0],' minut.')
plt.xlabel(indeks_wynikow)
plt.show()






	


Na poniższym rysunku mozna zobaczyć efekt działania programu. Na górnym wykresie można zobaczyć losowo wygenerowany czas realizacji całego przeglądu. Ewidetnie widać losowość uzyskanych wyników, gdzie kolejne symulacje dająskrajnie rózne wyniki.
Na dolnym wykresie, kolorem niebieskim oznaczono posegregowane wyniki od najkrótszego do najdłuższego. Pomarańczowa linia oznacza jedynie nr iteracji.



Pod wykresami można zauważyć drukowanie wyników w postaci tekstowej.
Efektem rogramu są stwierdzenia że z 50% prawdopodobieństwem przegląd zostanie wykonany w 7 minut, a z 90% prawdopodobieństwem w 32 minuty.
Wniosek - jeżeli połowa przeglądów kończy się w 27 minut, można przyjąć to z punkt wyjścia dla naszego systemu monitoringu przeglądów aut online... :)

Gdy wykonamy 100 symulacji wyniki będą już prezentować się nieco inaczej.



:)