Wróć do informacji o e-podręczniku Wydrukuj Zapisz jako PDF Udostępnij materiał

Metoda Monte Carlo polega na modelowaniu procesów fizycznych poprzez losowanie wielkości charakteryzujących proces i szacowanie wyniku na podstawie tak otrzymanych danych. Pomysłodawcą takiej właśnie techniki był polski matematyk Stanisław Ulam. Dzięki metodzie Monte Carlo możemy np. symulować obserwowane w przyrodzie ruchy Browna.

Chaotyczne i pozornie samorzutne ruchy Browna są wynikiem zderzeń drobin pyłku z cząsteczkami cieczy lub gazu. Spróbujemy symulować ruchy jednej cząsteczki pyłku obliczając jej kolejne współrzędne. Później wykreślimy trasę, jaką pokonała cząsteczka.

Symulacja będzie polegała na losowym wyznaczeniu kilkuset kolejnych punktów o współrzędnych (x, y). Aby wykreślić ruchy Browna, musimy przyjąć pewne założenia:

  • cząsteczka na początku będzie znajdować się w środku układu współrzędnych (0, 0),

  • w każdym ruchu cząsteczka będzie przemieszczała się o wektor o stałym module (długości) r,

  • kierunek ruchu będzie wyznaczony losowym kątem fi,

  • kolejne współrzędne (x, y) cząstki będą określone następującymi wzorami:

φ(0,2π)
Xn=Xn1+(rcos(φ))
Yn=Yn1+(rsin(φ))

Wartości obliczone w symulacji to tablice (listy) współrzędnych X oraz Y. Liczba ich elementów równa jest liczbie kroków symulacji.

Przykład 1

Napiszmy program obliczający losowe współrzędne cząsteczki. W tym celu skorzystamy z funkcji sqrt(), sin(), cos() oraz ze zmiennej pi, należących do modułu math. Po zaimportowaniuimportowaniezaimportowaniu go będziemy mogli obliczyć kolejne wartości współrzędnych (x, y) losowanych punktów.

Aby móc uzyskać te same wyniki (identyczne zestawy liczb pseudolosowych) użyjemy funkcji seed()seed(x)seed() z modułu random. Wprowadzimy parametr seed_start, który pozwoli inicjować wartość początkową generatora liczb pseudolosowych.

Dzięki funkcji randint() będziemy losować wartości całkowite. Uzyskamy dwie listy o tej samej długości, zawierające kolejne punkty w układzie współrzędnych. Funkcja będzie zwracać te listy (brown_X, brown_Y), abyśmy mogli analizować poszczególne punkty (x, y).

def ruchy_browna(pozycja_poczatkowa: tuple, ile_krokow: int, wektor_r: float, seed_start: int = 234567) -> tuple:  
	from math import sqrt, sin, cos, pi, radians
	from random import randint, seed

	seed(seed_start)
	brown_X: list = [pozycja_poczatkowa[0]]
	brown_Y: list = [pozycja_poczatkowa[1]]

	for krok in range(1, ile_krokow):
		# wylosowany kąt musi być podany w radianach; wymagają tego funkcje sin() i cos()
		fi: float = radians(float(randint(0, 360)))
		brown_X.append(brown_X[krok - 1] + (wektor_r * cos(fi)))
		brown_Y.append(brown_Y[krok - 1] + (wektor_r * sin(fi)))

	return (brown_X, brown_Y)

# przykład uruchomienia
punkty = ruchy_browna((0, 0), 10, 0.84)

print(punkty[0])
[0, 
 0.8379538022182524, 1.2954505916308752, 0.5280724072110906, 1.3313684022200403, 
 0.5163199921482032, 0.45772455420313773, 1.236558992039239, 2.068384169782158, 
 1.5746445578564807]

print(punkty[1])
[0, 
 -0.0585954379450648, 0.6458878391290912, 0.9875466193127636, 1.2331388512798624, 
 1.0299244589761418, 0.1919706567578895, -0.12269888171147686, -0.2396042865179322, 
 0.43996998875702364]

W celu zobrazowania obliczeń posłużymy się biblioteką matplotlibmatplotlibmatplotlib. Wykorzystamy ją pisząc program, który będzie rysował na płaszczyźnie punkty, bazując na danych dostarczonych przez poprzednią funkcję.

def wizualizuj_ruchy_browna(wspolrzedne: tuple) -> None:
	import matplotlib.pyplot as plt

	X: list = wspolrzedne[0]
	Y: list = wspolrzedne[1]
	plt.plot(X, Y, 'o:', color='red', linewidth=2)
	plt.xlabel('Współrzędne X')
	plt.ylabel('Współrzędne Y')
	plt.title('Ruchy Browna')
	plt.grid(True)
	plt.show()
    
# wywołanie z danymi poprzedniej funkcji
punkty = ruchy_browna((0, 0), 10, 0.84)
wizualizuj_ruchy_browna(punkty)

Wynikiem działania przedstawionego programu będzie wykres reprezentujący kolejne współrzędne położenia cząsteczki.

R4r7QN1Vh6d5J
Ważne!

Nietypowym sposobem zapisu definicji funkcji są tzw. type hintstype hintstype hints, omówione w dokumencie PEP‑484 języka Python. Pomagają one programistom, ale nie wpływają na działanie programów – nie są więc wymagane.

W przedstawiony wyżej sposób możemy symulować ruchy Browna. Podczas uruchamiania programu zwracajmy uwagę na wartości poszczególnych parametrów - wpływają one na dane końcowe.

1
Polecenie 1

Bazując na poprzednich przykładach spróbuj tak wywołać program, aby uzyskać na wykresie tylko punkty początkowy i końcowy podczas wykonywania 300 kolejnych kroków. Jako wektor_r przyjmij wartość 0,73, a seed_start niech wynosi 432432.

Już wiesz

Podsumujmy najważniejsze elementy tej lekcji:

  • metoda Monte Carlo może być przydatna przy szacowaniu wyników na podstawie dużej liczby zmiennych losowych

  • w języku Python możemy stosować tzw. type hintstype hintstype hints

  • funkcja seed() pozwala ustawić wartość początkową (ziarno) dla generatora liczb pseudolosowych

Słownik

zmienna losowa
zmienna losowa

zmienna, której wartość pozostaje nieznana do momentu losowania; w języku Python można uzyskać ją m.in. dzięki funkcjom należącym do modułu random:

  • randint(z, b) – zwraca liczbę całkowitą z zakresu [a, b]

  • randrange(a, b, c) – zwraca liczbę całkowitą z zakresu [a, b + 1] z krokiem c

  • random() – zwraca liczbę rzeczywistą z zakresu [0.0, 1.0)

importowanie
importowanie

operacja pozwalająca w programie (funkcji) używać dodatkowych funkcji lub obiektów, dostępnych w zewnętrznych bibliotekach

matplotlib
matplotlib

biblioteka służąca do przedstawienia obrazów złożonych z punktów o współrzędnych x oraz y (wykresów, histogramów, rozkładów itp.); moduł matplotlib nie jest dostępny w standardowej instalacji Pythona; należy zainstalować go korzystając z mechanizmu pip

type hints
type hints

informacja o typie danego obiektu zapisana literalnie w kodzie programu; z uwagi na dynamiczną naturę języka Python pomaga w zrozumieniu kodu programu i pozwala na sprawdzanie kodu przez różne środowiska IDE (np. PyCharm, SublimeText lub Atom); przykład użycia: zmienna: int = 10; type hints są dokładnie opisane w dokumencie PEP 484 – ich inna nazwa to annotations (opisane w dokumencie PEP 3107)

seed(x)
seed(x)

(z ang. seed – ziarno) funkcja pozwalająca ustalić punkt początkowy obliczeń, których rezultatem jest wygenerowanie liczby pseudolosowej przez funkcje takie jak random(), randint() i podobne; po określeniu wartości zmiennej x wyniki działania funkcji losowych są powtarzalne; jeśli nie podano wartości x lub ustalono ją jako None, za wartość x przyjmuje się aktualny czas