środa, 26 lipca 2017

Realistyczny model wielokrotnych pożarów lasu cz. 2

Nie wiem ilu z czytelników podjęło własną próbę implementacji. Mam nadzieję że wielu, bo bez własnych prób programowania nauczyć się nie sposób.
Ale teraz moja implementacja - możecie zobaczyć na ile nasze myślenie podobnymi/odmiennymi drogami.

Po pierwsze, ponieważ mamy plik Log musimy zdefiniować procedurę exit() która ma głównie za zadanie zapisać bufor danych pliku na dysk, a potem zamknąć plik (linie 186-187):
Warto jednak wziąć pod uwagę, że deklarując taką procedurę "przykrywamy" istniejącą procedurę domyślną, która prawdopodobnie też wykonuje jakąś użyteczną pracę. Dlatego musimy tą starą procedurę wywołać, co odbywa się za pomocą super.exit()  (linia 189) .

No to przechodzimy do procedury doMonteCarloStep() zaczynając od ewentualnego zapalenia lasu. Najprostszym sposobem byłoby po prostu umieszczenie w głównej pętli instrukcji

 if(LigtP>random(0,1))
World[i][j]=coś tam...




Problem w tym, że taka instrukcja if z wywołaniem kosztownej funkcji random wykonywałaby się w każdym kroku Monte Carlo dla każdego żywego drzewa, a ze względu na to że LigtP jest, i powinno być bardzo małe, to bardzo rzadko warunek byłby spełniony.
W naszym programie oszukujemy więc trochę i bardzo przyśpieszamy ograniczając te losowania do niezbędnego minimum:

W każdym kroku M C doliczamy do zmiennej Burn sumaryczne prawdopodobieństwo zapłonu całego lasu (linia 76). Potem wykonujemy pętlę, która trwa tak długo jak zmienna Burn jest większa od 0 (linia 77). W pętli tej wykonujemy losowanie komórki świata, i JEŚLI TRAFIMY W DRZEWO to je podpalamy, co polega na obliczeniu czasu pożaru z dzielenia rozmiaru drzewa przez parametr FireTimeDiv. Wynik zmieniamy na ujemny co jest dla nas sygnałem, że drzewo już płonie. Jeśli podpalenie się uda to zmniejszamy zmienną Burn o jeden. No i ustawiamy "magiczną" flagę dla wizualizacji is_burning na true.

Teraz już możemy przystąpić do właściwej pętli kroku Monte Carlo:



Tak jak w poprzedniej wersji programu losujemy N*N komórek i w zależności od stanu wylosowanej komórki. Jeśli jest to pusta komórka (czyli o wartości 0) to próbujemy zasiać drzewo (linie 95-100).  Jeśli wartość jest dodatnia to po prostu drzewo trochę rośnie (linie 101-106). Wreszcie, gdy wartość jest negatywna to próbujemy zapalenia sąsiadów w sąsiedztwie Moora (linie 109-121) i dodajemy jeden do wartości komórki co razem z obcięciem części ułamkowej przy podpalaniu (linia 83 i 117) gwarantuje nam że każde płonące drzewo w końcu gaśnie stając się pustą komórką o wartości 0.  No i każde zapalenie drzewa ustawia nam flagę is_burning na potrzeby wizualizacji.

No i wreszcie dochodzimy do samej wizualizacji:


 ... której główna część prawie się nie zmieniła, poza tym że zliczamy puste, żywe oraz płonące komórki. Za to na koniec dodajemy wydruki statystyk (linia 164-178) na ekranie i zapis ich do pliku logu (linia 180-181).

No i to by było na tyle... Rezultat działania tego programu możecie znaleźć na Youtube, ale lepiej obejrzyjcie to sami. Efekty mogą was zaskoczyć.


Brak komentarzy:

Prześlij komentarz