poniedziałek, 23 stycznia 2017

Deterministyczny automat komórkowy (i synchroniczny)

W poprzednich przykładach jednowymiarowych automatów komórkowych uaktualnienie następowało wg. "reguły Monte Carlo" - losowaliśmy jakąś komórkę, stosowaliśmy do niej reguły zmiany stanu, zmienialiśmy stan i losowaliśmy kolejną. Wykonanie N losowań, czyli takiej liczby losowań i jest komórek umownie nazwaliśmy "krokiem Monte Carlo". Jednak taki sposób uaktualniania nie tylko nie gwarantuje kolejności, ale nawet tego, że w danym kroku każda komórka zostanie uaktualniona. Wręcz przeciwnie - możemy być niemal pewni że w pojedynczym kroku M C będzie wiele komórek pominiętych i wiele wylosowanych dwa razy. A trochę takich wylosowanych trzy albo cztery - tym więcej im większe N.
Taki sposób uaktualniania bliski jest ekologom i naukowcom społecznym - bo wydaje się dobrze odzwierciedlać kolejność zdarzeń (a właściwie jej brak) w systemach zbudowanych ze względnie makroskopowych i obdarzonych "własną wolą" agentów.
Fizycy jednak wolą inną metodę uaktualniania - synchroniczną. W tym wypadku sprawdzamy wszystkie komórki "jednocześnie" - czyli wg. globalnego stanu aktualnego wyliczamy od razu globalny stan następny. Technicznie potrzebne są do tego dwie "tablice świata" - po jednej dla chwili obecnej i kolejnej. Uaktualnienie można zrobić za pomocą pętli po tablicy, lub w jakiś sposób je zrównoleglić (dlatego lubią to fizycy, bo zrównoleglanie algorytmów jest jedną z ich pasji ;-) )
Poniżej kod automatu dla tej samej co poprzednio reguły, ale z uaktualnianiem synchronicznym/równoległym - a zatem też w pełni deterministyczny. Każdy przebieg dla tego samego stanu początkowego będzie identyczny.
  • W liniach 6 i 7 tworzymy dwie "tablice świata". W pętli (linie 36-54) w procedurze draw() przeglądamy KOLEJNO komórki tablicy WorldOld, ale wynik stosowania reguły zapisujemy w tablicy WorldNew, więc tablica WorldOld przez cały przebieg pętli pozostaje niezmieniona.
  • Dopiero po zakończeniu pętli dokonujemy zamiany zawartości tablic (linie 57-59).
    To akurat w Processingu jest bardzo proste, bo każda tablica jest tu obiektem dostępnym za pomocą uchwytu, więc wystarczy zamienić to co trzymają uchwyty. Tak jakbyśmy zamieniali dwa ciężkie kanistry z wodą przekładając je z ręki do ręki...
    Musimy to jednak zrobić w powietrzu, więc potrzebna jest trzecia ręka do potrzymania na chwilę - to trzecią ręką jest zmienna WorldTmp.
  • Inicjacja modelu (linie 13-19) łączy w sobie dwa dotychczasowe sposoby. Jeśli zmienna IDens jest większa od 0 to siejemy komórki losowo z zadaną gęstością, a w przeciwnym wypadku siejemy jedną komórkę w środku tablicy. Oczywiście zasiewamy tablicę WorldOld, bo to ona będzie następnie przetwarzana.
  • Wyświetlanie (linie 29-34) też odbywa się z tablicy WorldOld, bo ona trzyma zarówno stan początkowy, jak każdy następny stan aktualny. Tablica WorldNew używana jest tylko w okolicy pętli zmiany stanu.

    Wyniki działania programu są zależne od gęstości, ale tak czy inaczej mało przypominają to co widzieliśmy w wersji probabilistycznej. Są znacznie bardziej regularne, co jest dosyć typowe. Fizykom i matematykom się podoba - pewnie dlatego że lubią regularność :-)

Brak komentarzy:

Prześlij komentarz