Główna zawartość
Kurs: Programowanie > Rozdział 5
Lekcja 2: Losowość- Błądzenie przypadkowe
- Wyzwanie: Losowy wędrowiec
- Prawdopodobieństwo i rozkłady niejednostajne
- Wyzwanie: Wędrowiec
- Rozkład normalny liczb losowych
- Wyzwanie: gaussowskie błądzenie przypadkowe
- Specjalny rozkład liczb losowych
- Wyzwanie: lot Levy'ego
- Projekt: spryskiwacz do farb
© 2024 Khan AcademyWarunki użytkowaniapolitykę prywatnościInformacja o plikach cookie
Błądzenie przypadkowe
Zanim przejdziemy do złożonych zagadnień wektorów i ruchu opartego na fizyce, pomyślmy co to dokładnie oznacza, że coś przemieszcza się po ekranie. Zacznijmy od jednego z najlepiej znanych i prostych symulacji ruchu— błądzenia w przypadkowym kierunku.
Wyobraźcie sobie, że stoicie na równoważni. Co dziesięć sekund rzucacie monetą. Jeśli wypadnie orzeł, robicie krok do przodu. Jeżeli reszka, krok do tyłu. Na tym właśnie polega błądzenie w przypadkowym kierunku—ścieżka to seria losowych kroków. Jeżeli opuścimy równoważnię i staniemy na ziemi, możemy błądzić w dwóch wymiarach rzucając dwa razy monetą i postępując zgodnie z poniższą tabelą:
Pierwszy rzut | Drugi rzut | Wynik |
---|---|---|
Orły | Orły | Krok do przodu. |
Orły | Reszka | Krok w prawo. |
Reszka | Orły | Krok w lewo. |
Reszka | Reszka | Krok w tył. |
Tak, może się Wam wydawać, że nie jest to zbyt wyszukany algorytm. Niemniej jednak, błądzenie w losowym kierunku może być użyte aby zamodelować zjawiska mające miejsce w prawdziwym świecie, od ruchu cząsteczek gazu po zachowanie hazardzisty spędzającego cały dzień w kasynie. W naszym przypadku, zaczniemy omawianie tego tematu myśląc o trzech celach.
Obiekt Walker poruszający się w sposób losowy
Przypomnijmy sobie wpierw zasady programowania zorientowanego obiektowo (z ang. object-oriented programming, OOP) tworząc obiekt
Walker
. To będzie bardzo pobieżne przypomnienie. Jeżeli nie mieliście wcześniej styczności z programowaniem obiektowym, powinniście udać się do sekcji o zorientowanym obiektowo JavaScripcie.Obiekt w JavaScripcie to typ danych, który posiada zarówno właściwości, jak i funkcje dołączone do niego poprzez jego prototyp. Będziemy projektować obiekt
Walker
który przekazuje informację o własnym położeniu(gdzie znajduje się na ekranie) jak i ma możliwość wykonania pewnych czynności (takich jak rysowanie samego siebie albo przemieszczanie się).Aby móc tworzyć instancje
Walker
a, potrzebujemy wpierw zdefiniować obiekt Walker
. Obiekt ten będzie naszym wzorcem, a każda nowa instancja Walker
a jego kopią.Zacznijmy od zdefiniowania obiektu
Walker
. Walker
potrzebuje tylko dwóch informacji—wartość swojej współrzędnej x oraz współrzędnej y. Ustawimy je w funkcji konstruktora, ustawiając je na sam środek płótna.var Walker = function() {
this.x = width/2;
this.y = height/2;
};
Oprócz przechowywania swoich współrzędnych x i y,
Walker
posiada również metody które możemy wywoływać. Pierwsza z nich to metoda, która pozwala wyświetlić ten obiekt w postaci czarnej kropki. Pamiętajcie, że możemy dodawać metody do obiektu w JavaScripcie poprzez przyłączanie ich do prototypu
obiektu.Walker.prototype.display = function() {
stroke(0, 0, 0);
point(this.x, this.y);
};
Druga metoda nakazuje obiektowi
Walker
przemieszczenie się. Teraz wszystko zrobi się znacznie ciekawsze. Pamiętacie podłogę, na której wykonywaliśmy losowe kroki? Teraz możemy używać naszego płótna w tym samym celu. Istnieją cztery możliwe kroki. Krok w prawo może być symulowany poprzez zwiększanie wartości x
(x++
); w lewo zmniejszając x
(x--
); w przód poprzez zejście w dół o piksel (y++
); a w tył poprzez przeniesienie się w górę o piksel (y--
). Jak mamy wybrać z tych czterech opcji? Wcześniej stwierdziliśmy, że możemy rzucić dwoma monetami. Jednak w ProcessingJS, gdy chcemy losowo wybrać z paru możliwości, możemy wybrać losową liczbę za pomocą random()
.Walker.prototype.walk = function() {
var choice = floor(random(4));
};
Powyższy kod wybiera losowo liczbę zmiennoprzecinkową z zakresu między 0 a 4 i zmienia ją w pełną liczbę za pomocą metody (z nieskończoną liczbą dziewiątek); ponieważ
floor()
, dając w rezultacie wartość 0, 1, 2 lub 3. Technicznie rzecz biorąc, najwyższą wartością nigdy nie będzie 4.0, tylko floor()
zwraca najbliższą cyfrę która jest mniejsza lub równa, najwyższy wynik który uzyskamy jest równy 3. Następnie wykonujemy odpowiedni krok(w lewo, prawo, górę lub dół) w zależności od liczby która została wybrana.Walker.prototype.walk = function() {
var choice = floor(random(4));
if (choice === 0) {
this.x++;
} else if (choice === 1) {
this.x--;
} else if (choice === 2) {
this.y++;
} else {
this.y--;
}
};
Teraz, gdy napisaliśmy klasę, pora stworzyć autentyczny obiekt
Walker
a w naszym programie. Zakładając, że chcemy stworzyć model pojedynczego losowego błądzenia, deklarujemy i inicjalizujemy jedną globalną zmienną typu Walker
, wywołując funkcję konstruktora z nowym operatorem.var w = new Walker();
Teraz, aby nasz Walker autentycznie coś robił, musimy zdefiniować funkcję
draw()
i poinformować nasz obiekt, aby zrobił krok i narysował siebie za każdym razem, gdy ta funkcja jest wywołana:draw = function() {
w.walk();
w.display();
};
Ponieważ nie wywołujemy
background()
w naszej funkcji rysującej, będziemy widzieć ślad wędrówki naszego obiektu na płótnie:Ulepszanie poruszającego się losowo Walkera
Istnieje kilka ulepszeń, które możemy zastosować do naszego obiektu. Po pierwsze, wybór kroków Walkera jest ograniczony do czterech opcji—w górę, w dół, w lewo i w prawo. Ale przecież każdy piksel w naszym oknie ma ośmiu potencjalnych sąsiadów i dziewiątą możliwość - pozostanie w miejscu.
Aby stworzyć obiekt typu
Walker
który może przemieścić się na każdego z sąsiadujących pikseli(albo pozostać w miejscu), możemy wybrać liczbę pomiędzy 0 a 8 (co da nam dziewięć możliwych opcji). Mimo to, bardziej wydajnym sposobem byłoby napisanie kodu, który po prostu wybierze jeden z trzech możliwych kroków wdłuż osi x (-1, 0 lub 1) i jeden z trzech możliwych kroków wzdłuż osi y.Walker.prototype.walk = function() {
var stepx = floor(random(3))-1;
var stepy = floor(random(3))-1;
this.x += stepx;
this.y += stepy;
};
Idąc dalej tym tropem, moglibyśmy używać wartości dziesiętnej dla
x
i y
zamiast tego, przesuwając się pomiędzy losowymi wartościami z przedziału -1 i 1 - gdyby nasze środowisko pozwalało na wyświetlanie różnic między "2.2" a "2.4":Walker.prototype.walk = function() {
var stepx = random(-1, 1);
var stepy = random(-1, 1);
this.x += stepx;
this.y += stepy;
};
Wszystkie te dywagacje na temat “tradycyjnego” błądzenia mają jedną rzecz wspólną: w danej chwili czasu, prawdopodobieństwo, że
Walker
zrobi krok w danym kierunku (lub nie wykona żadnego kroku) jest równe prawdopodobieństwu, że Walker
dokona innego wyboru. Innymi słowy, jeżeli mamy cztery możliwe kroki, szansa wynosi 1 do 4 (albo 25%), że Walker
wykona któryś z tych kroków. W przypadku dziewięciu opcji, szansa ta wynosi 1 do 9 (albo 11,1%).Na nasze szczęście tak właśnie działa funkcja
random()
. Generator liczb losowych produkuje tak zwany “równomierny” rozkład liczb. Możemy sprawdzić ten rozkład za pomocą programu który liczy wszystkie losowania liczb i przedstawia je w postaci wysokości prostokąta:Czy wszystkie paski są tej samej wielkości, nawet po kilku minutach działania? Prawdopodobnie nie. Nasza wielkość próbki (czyli liczba losowych liczb które wybraliśmy) jest raczej mała i istnieją pewne rozbieżności, powodujące, że pewne liczby są wybierane częściej. Po pewnym czasie każdy dobry generator liczb losowych wyrównuje takie przypadki.
Losowe liczby które uzyskujemy z funkcji
random()
nie są tak na prawdę losowe: są przez to znane jako liczby “pseudo-losowe.” Są wynikiem matematycznej funkcji symulującej losowość. Ta funkcja potrafi ukazać swój wzór po pewnym czasie, ale ten czas jest tak duży, że z naszej perspektywy może to się wydawać po prostu losowe!W następnym rozdziale opowiemy o różnych sposobach na tworzenie Walkerów z "tendencjami" do chodzenia w określonych kierunkach. Ale zanim się za to zabierzemy, czeka na Was wyzwanie!
Ten kurs "Symulacje Natury" jest pochodną z "Natury Kodu " stworzonej przez Daniela Shiffmana, użytej pod licencją Creative Commons Attribution-NonCommercial 3.0 Unported License.
Chcesz dołączyć do dyskusji?
Na razie brak głosów w dyskusji