Główna zawartość
Programowanie
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
© 2023 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
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 3, point, 999999 (z nieskończoną liczbą dziewiątek); ponieważ 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