0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ e-learning: Automaty komórkowe Mirosław Dudek dla Otwartych Warsztatów Komputerowych Streszczenie Celem tego krótkiego kursu jest pokazanie działania prostych automatów komórkowych na przykładach programowania obiektowego. Wydruki stanu automatów zapisywane są do plików ppm. 0.1 Jednowymiarowe automaty komórkowe Za twórcę automatów komórkowych uważa się Johna von Neunmanna. W tym rozdziale ograniczymy się do automatów jednowymiarowych w wersji spopularyzowanej przez Stevena Wolframa (1986) tj. do automatów 8-bitowych. Automat komórkowy oznacza układ, który ewoluuje w dyskretnym czasie i posiada skończoną ilość stanów w których może występować. Rysunek 1: Wyobraźmy sobie że chcemy zrobić wizualizację koralika poruszającego się jednostajnie wzdłuż pierścienia na który jest on nanizany. Żeby nie rozwiązywać skomplikowanych równań ruchu i zastanawiać się nad najlepszym algorytmem numerycznym dla nich wystarczy skorzystać z algorytmu automatu komórkowego. Dla uproszczenia zamiast pierścienia koralik będzie poruszał się po odcinku prostej na który nałożone są periodyczne warunki brzegowe, tj. jeśli koralik poruszając się np. w prawą stronę dotrze do prawego końca odcinka to równoważne będzie pojawieniu się koralika na lewym końcu odcinka. Koralik bedzie kontynuował ruch w prawo. Kolejne uproszczenie to odcinek po którym porusza się koralik będzie przybliżony dyskretną liczbą L położeń które może zająć poruszający się koralik. Miejsce w którym jest koralik będziemy reprezentować jedynką a miejsce puste zerem jak na schemacie poniżej 000000000000000000000001000000000000000000000000000 W kolejnych krokach czasowych rysować będziemy dywan czasoprzestrzenny pokazujący zmieniające się położenie koralika. Koralików może być więcej i np. trzy pierwsze kroki ewolucji czasowej dla 5 koralików poruszających się w prawą stronę możemy przedstawić jak niżej. 0000000001100010000000010000000000000000000000000010 0000000000110001000000001000000000000000000000000001 1000000000011000100000000100000000000000000000000000 Reguły 8-bitowe Wolframa to przyporządkowanie stanom (1 - zajęty lub 0 - pusty) trójki sąsiednich węzłów (i-1,i,i+1) z poprzedniego kroku czasowego t stanu węzła środkowego (i-tego) w kolejnym kroku czasowym t + 1. W przypadku stanów zero-jedynkowych trzy węzły mają M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 1 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ 2 3 = 8 możliwości pojawienia się jedynek i zer. Formalnie, takie przyporządkowanie trójce bitów jednego bitu dla węzła środkowego można zapisać jako nastepujący przepis σ i (t + 1) = Φ(σ i 1 (t), σ i (t), σ i+1 (t)), (1) gdzie Φ jest regułą Wolframa i ma postać jak na rysunku poniżej. Rysunek 2: Takie odwzorowanie można reprezentować liczbą dziesiętną. Jeśli popatrzymy na konfigurację łańcucha binarnego na Rys.4. to licząc od prawej strony mamy 240 = 1 2 7 + 1 2 6 + 1 2 5 + 1 2 4 + 0 2 3 + 0 2 2 + 0 2 1 + 0 2 0 (2) ji wartość dziesiętna 240 jest tzw. Regułą Wolframa o numerze 240. Dla automatów 8-bitowych mamy 256 reguł. Poniżej znajduje się program reg.cc który przypisuje liczbie dziesiętnej wartość łańcucha binarnego o zadanej długości. 1 #include <iostream> 2 #include <c a s s e r t > 3 #include <s t d l i b. h> 4 5 using namespace std ; 6 7 8 class C e l l u l a r { // d e k l a r a c j a k l a s y C e l l u l a r 9 private : 10 int Regula ; 11 char RegulaLancuchBin ; // d e k l a r a c j a wskaznika na znak 12 // pod tym adresem b e d z i e zapamietana 13 // t a b l i c a r e p r e z e n t u j a c a lancuch binarny 14 // d l a l i c z b y Regula 8 b i t o w e j 15 public : 16 17 C e l l u l a r ( ) { 18 RegulaLancuchBin=new char [ 8 ] ; 19 i f (! RegulaLancuchBin ){ 20 cout<< brak pamieci dla tablicy RegulaLancuchBin [8] <<e n d l ; 21 } 22 } 23 24 void WczytajRegule ( int dec ){ 25 26 a s s e r t ( dec>=0 && dec <256); 27 28 Regula=dec ; 29 30 i t o s ( Regula, RegulaLancuchBin, 2, 8 ) ; // zamieniamy l i c z b e Regula 31 // na lancuch bitowy 32 } ; M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 2 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ 33 34 void i t o s ( int xx, char lanc, int nn, int DLUG) ; 35 36 void PokazRegule ( ) { 37 cout<< Regula <<Regula<< : <<RegulaLancuchBin<<e n d l ; 38 } 39 40 } ; 41 42 void C e l l u l a r : : i t o s ( int xx, char lanc, int nn, int DLUG){ 43 long x=xx ; 44 int l=dlug 1; 45 long n = nn ; 46 int j ; 47 48 for ( j =0; j<dlug; j++) ( l anc+j )= 0 ; 49 ( l anc+dlug)= 0 ; 50 51 i f (! x ) ; 52 else 53 { 54 do 55 { 56 ( l anc+l )= 0 +x % n ; 57 58 x/=n ; 59 60 l ; 61 } while ( x ) ; 62 for ( j =0; j<l ; j++) ( lanc+j )= 0 ; 63 ( l anc+dlug)= 0 ; 64 65 } 66 } 67 68 69 int main ( int argc, char argv ){ 70 i f ( argc!=2){ 71 cout<< Poprawny format polecenia: <<argv [0] << nr reg Wolframa <<e n d l ; 72 return 0 ; 73 } 74 75 int reg=a t o i ( argv [ 1 ] ) ; //numer r e g u l y Wolframa 76 77 C e l l u l a r A; 78 A. WczytajRegule ( reg ) ; 79 A. PokazRegule ( ) ; 80 81 return 0 ; 82 } Kolejny program, reguly.cc, wyrysowuje dywan przestrzenny na ekranie dla zadanej reguły. 1 #include <iostream> 2 #include <c a s s e r t > 3 #include <s t d l i b. h> 4 M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 3 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ 5 using namespace std ; 6 7 8 class C e l l u l a r { // d e k l a r a c j a k l a s y C e l l u l a r 9 private : 10 int Regula ; 11 char RegulaLancuchBin ; // d e k l a r a c j a wskaznika na znak 12 // pod tym adresem b e d z i e zapamietana 13 // t a b l i c a r e p r e z e n t u j a c a lancuch binarny 14 // d l a l i c z b y Regula 8 b i t o w e j 15 public : 16 17 C e l l u l a r ( ) { 18 RegulaLancuchBin=new char [ 8 ] ; 19 i f (! RegulaLancuchBin ){ 20 cout<< brak pamieci dla tablicy RegulaLancuchBin [8] <<e n d l ; 21 } 22 } 23 24 void WczytajRegule ( int dec ){ 25 a s s e r t ( dec>=0 && dec <256); 26 Regula=dec ; 27 i t o s ( Regula, RegulaLancuchBin, 2, 8 ) ; // zamieniamy l i c z b e Regula 28 // na lancuch bitowy 29 } ; 30 31 void i t o s ( int xx, char lanc, int nn, int DLUG) ; 32 void PokazRegule ( ) { 33 cout<< Regula <<Regula<< : <<RegulaLancuchBin<<e n d l ; 34 } 35 36 int ZakodujSasiedztwo ( const int &lewy, const int &srodek, const int &prawy ){ 37 int l i c z b a d e k o d, reg, r e f ; 38 char znak, zero= 0 ; 39 r e f =(int ) zero ; 40 41 reg=prawy+2 srodek+4 lewy ; 42 znak = ( RegulaLancuchBin+7 r e g ) ; 43 l i c z b a d e k o d =(( int ) ( znak)) r e f ; 44 return l i c z b a d e k o d ; 45 46 } 47 } ; 48 49 void C e l l u l a r : : i t o s ( int xx, char lanc, int nn, int DLUG){ 50 long x=xx ; 51 int l=dlug 1; 52 long n = nn ; 53 int j ; 54 55 for ( j =0; j<dlug; j++) ( l anc+j )= 0 ; 56 ( l anc+dlug)= 0 ; 57 58 i f (! x ) ; 59 else 60 { M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 4 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ 61 do 62 { 63 ( l anc+l )= 0 +x % n ; 64 65 x/=n ; 66 67 l ; 68 } while ( x ) ; 69 for ( j =0; j<l ; j++) ( lanc+j )= 0 ; 70 ( l anc+dlug)= 0 ; 71 72 } 73 } 74 75 void WarunkiPeriodyczne ( int &i l e f t, const int &i, int &i r i g h t, const int &L ) ; 76 77 int main ( int argc, char argv ){ 78 i f ( argc!=4){ 79 cout<< Poprawny format polecenia: ; 80 cout<<argv [0] << nr reg Wolframa l krok czas l wezlow <<e n d l ; 81 return 0 ; 82 } 83 84 int reg=a t o i ( argv [ 1 ] ) ; //numer r e g u l y Wolframa 85 int T=a t o i ( argv [ 2 ] ) ; // l i c z b a krokow czasowych 86 int L=a t o i ( argv [ 3 ] ) ; // l i c z b a wezlow 87 88 C e l l u l a r A; 89 A. WczytajRegule ( reg ) ; 90 A. PokazRegule ( ) ; 91 92 int Dywan=new int [ L ] ; 93 int DD=new int [ L ] ; 94 95 for ( int i =0; i <L ; i ++){ 96 Dywan [ i ]=0; 97 } 98 99 100 int ilewy, i s r o d, iprawy ; 101 int slewy, ssrod, sprawy ; 102 103 (Dywan+L/2)=1; // s t a r t 104 105 for ( int t =0; t<t; t++){ 106 107 for ( int i =0; i<l ; i ++){ // przegladamy stan dywanu w c h w i l i t 108 i f ( (Dywan+i )==1)cout<< * ; else cout<< ; 109 } 110 cout<<endl ; 111 112 113 for ( int i =0; i<l ; i ++){ 114 i l e w y=i 1; i s r o d=i ; iprawy=i +1; 115 WarunkiPeriodyczne ( ilewy, i srod, iprawy, L ) ; 116 slewy = (Dywan+i l e w y ) ; s s r o d = (Dywan+i s r o d ) ; sprawy= (Dywan+iprawy ) ; M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 5 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ Rysunek 3: 117 118 (DD+i )=A. ZakodujSasiedztwo ( slewy, ssrod, sprawy ) ; 119 } 120 121 for ( int i =0; i<l ; i ++){ 122 (Dywan+i )= (DD+i ) ; 123 } 124 } 125 126 127 return 0 ; 128 } 129 130 void WarunkiPeriodyczne ( int &i l e w y, const int &i, int &i prawy, const int &L){ 131 i f ( i ==0) i l e w y=l 1; 132 else { 133 i f ( i==l 1) i prawy =0; 134 } 135 } Wynik działania tego programu dla reguły Wolframa o numerze 149 jest na rysunku poniżej. Kolejny program regulyppm.cc na dysku zapisuje dywan czasoprzestrzenny w postaci pliku ppm. Pogram ten dostępny jest wraz z innymi źródłami tego kursu. Tutaj zamieszczamy tylko fragment wprowadzający format zapisu do pliku ppm. Pozostałe części programu są jak poprzednio. Uwaga, zmienna L z poprzedniego programu to stała N poniżej. 1 int main ( int argc, char argv ){ 2 i f ( argc!=3){ 3 cout<< Poprawny format polecenia: ; 4 cout<<argv [0] << nr reg Wolframa l krok czas <<e n d l ; 5 return 0 ; 6 } 7 8 int reg=a t o i ( argv [ 1 ] ) ; //numer r e g u l y Wolframa 9 int T=a t o i ( argv [ 2 ] ) ; // l i c z b a krokow czasowych 10 M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 6 Materiał dystrybuowany bezpłatnie
0.1 Jednowymiarowe automaty komórkowe Przykłady programowania w C++ 11 C e l l u l a r A; 12 A. WczytajRegule ( reg ) ; 13 // A. PokazRegule ( ) ; 14 15 16 17 int ilewy, i s r o d, iprawy ; 18 int slewy, ssrod, sprawy ; 19 20 21 // Najpierw piszemy symbol P3 k t o r y oznaczac b e d z i e ze k o l o r y 22 // beda kodowane w ASCII 23 24 cout<< P3 <<endl ; 25 26 //potem piszemy dwie l i c z b y c a l k o w i t e N M r e p r e z e n t u j a c e 27 // odpowiednio l i c z b e kolumn i l i c z b e w i e r s z y obrazka 28 // np. 100 100 29 // c z y l i N=400 i M=100 30 // 31 int N=1000, M=1000; 32 cout<<m<< <<N<<endl ; 33 //W k o l e j n e j l i n i i polecen piszemy maksymalna l i c z b e kolorow 255 34 35 cout <<255<<endl ; 36 37 // Nastepnie piszemy t r o j k i RGB l i c z b c a l k o w i t y c h 38 // z p r z e d z i a l u [ 0, 2 5 5 ] o l i c z b i e t r o j e k rownej NxM 39 40 int r, g, b ; 41 42 43 44 45 int Dywan=new int [ N ] ; 46 int DD=new int [ N ] ; 47 48 for ( int i =0; i <N; i ++){ 49 Dywan [ i ]=0; 50 } 51 (Dywan+N/2)=1; // s t a r t 52 53 54 for ( int t =0; t<t; t++){ 55 56 for ( int i =0; i<n; i ++){ // przegladamy stan dywanu w c h w i l i t 57 i f ( (Dywan+i )==1)cout <<255<< <<0<< <<0<<endl ; 58 else cout<<0<< <<0<< <<0<<endl ; 59 } Natomiast na kolejnym rysunku mamy wynik jego działania dla tej samej reguły Wolframa o numerze 149. M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 7 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ Rysunek 4: Ta sama reguła 149 ale jej wynik zrzucony został do pliku.ppm o rozdzielczości 1000 1000 pikseli. Widać strukturę fraktalną utworzonego dywanu czasoprzestrzennego. 0.2 Dwuwymiarowe automaty komórkowe Ponieważ każdy układ dyskretny w czasie o tej własności że liczba stanów tego układu jest skończona spełnia warunki bycia automatem komórkowym to można pokusić się o napisanie programu na automat dwuwymiarowy. Inspirację można wziąć z gry komputerowej Game of Life Johna Conway a. Nie jest to gra komputerowa w potocznym rozumieniu bo nie ma w niej zwycięzców i przegranych - zobacz np. http://www.math.com/students/wonders/life/life.html. W naszym przypadku również życie będzie toczyć się na siatce kwadratowej o L L kwadratów. Każdy kwadrat może być w dwóch stanach: zajęty lub pusty co bedziemy oznaczać odpowiednio jedynką i zerem. O tym jaki bedzie stan kwadratu w położeniu (i, j) sieci kwadratowej w kolejnym kroku czasowym decydują reguły, powiedzmy że mają one postać przepisu polegającego na tym ze jeśli w otoczeniu kwadratu (i,j) jest za mało kwadratów zajętych (liczba mniejsza niż 3) to stan kwadratu σ (i,j) (t + 1) w kolejnym kroku czasowym (t+1) wynosi 0. Podobnie jeśli otoczenie kwadratu (i,j) jest przepełnione. Niech stan kwadratu σ (i,j) (t + 1) = 1 tylko jeśli obsadzenie dziewięciu kwadratów z kwadratem (i,j) w centrum przyjmuje wartości 3 lub 4. Wtedy matematycznie te reguły można zapisać w postaci wzoru: 0; jeśli σ (i,j) (t + 1) = 1; jeśli 3 0; jeśli sąsiedztwo(i,j) sąsiedztwo(i,j) sąsiedztwo(i,j) σ (i,j) (t) < 3 (3) σ (i,j) (t) < 5 (4) σ (i,j) (t) 5 (5) gdzie σ = 0 lub 1. Te dziewięć kwadratów reprezentujących sąsiedztwo kwadratu (i,j) przedstawiono na rysunku ponniżej. Poniżej przedstawiony jest kod programu realizującego taki automat komórkowy. Plik dostępny jest niezależnie pod nazwą 2Dautomaty.cc. W programie najpierw poproszeni jestesmy o podanie liniowego wymiaru sieci kwadratowej L. Można wpisać np. L=100. Potem poproszeni jesteśmy o wpisanie liczby kroków czasowych trwania naszego eksperymentu. Na początek najlepiej wybrać liczbę kroków czasowych taką samą jak liniowy wymiar sieci, tj. N=100. W programie w funkcji main() nastepuje wydruk do pliku o nazwie serweta.ppm. Taki wydruk dla (6) M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 8 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ Rysunek 5: Sąsiedztwo 9 kwadratów z centralnym kwadratem (i,j). Kazdy kwadrat może być w stanie σ = 0 lub 1 czyli kwadrat pusty i kwadrat obsadzony. parametrów L=1000 i N=1000 można zobaczyć na rysunku poniżej w przypadku gdy warunkami początkowymi były stany wszystkich kwadratów sieci kwadratowej L L puste za wyjątkiem 9 kwadratów w centrum siatki. 1 // p r z y k l a d automatu dwuwymiarowego na s i e c i kwadratowej 2 // Regule stanowi stan s a s i e d z t w a 9 kwadratow ( t u t a j g w i a z d k i ) 3 // s i e c i kwadratowej LxL 4 // 5 // 6 // 7 // 8 // Stan s i wezla srodkowego i w nastepnym kroku czasowym z a l e z y od stanow 9 // s k d z i e w i e c i u wezlow 10 //w kroku poprzednim k = 1.. 9 : 11 // 12 // s i =suma k =1..9 s k 13 // Regula : 14 // i f (suma<3) s i =0 15 // i f (suma>=3 && suma<5) s i =1 16 // i f (suma>=5) s i =0 17 #include <iostream> 18 #include <fstream> 19 #include <c a s s e r t > 20 #include <s t d l i b. h> 21 22 using namespace std ; 23 24 class Otoczenie { 25 private : 26 int Sasiad [ 9 ] ; // s t a t y c z n a t a b l i c a d l a stanow obsadzen 9 kwadratow 27 int stan ; 28 int L ; // l i n i o w y wymiar s i e c i kwadratowej 29 int suma ; // l i c z b a k t o r a mowi i l e sposrod komorek j e s t z a j e t y c h 30 public : 31 Otoczenie ( int LL){L=LL; } // k o n s t r u k t o r 32 int OkreslStanOtoczenia ( int S, int nr ){ // argumentem j e s t wskaznik na i n t 33 // adres b e d z i e r e p r e z e n t o w a l s i a t k e kwadratowa 34 // przy pomocy t a b l i c y jednowymiarowej 35 // o t o c z e n i e w konwencji s i e c i kwadratowej. 36 //n=i L+j ; numer porzadkowy t a b l i c y jednowymiarowej 37 // odpowiadajacy elementowu ( i, j ) t a b l i c y 38 // dwuwymiarowej 39 // ( i 1, j 1) ( i 1, j ) ( i 1, j +1) 40 // ( i, j 1) ( i, j ) ( i, j +1) 41 // ( i +1, j 1) ( i +1, j ) ( i +1, j +1) M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 9 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ 42 43 44 int i i, j j ; 45 int suma=0; 46 int n, i, j ; 47 48 i=nr /L ; j=nr%l ; // p r z y p i s a n i e numerowi nr wspolrzednych ( i, j ) 49 // s i a t k i kwadratowej 50 51 // gorny w i e r s z o t o c z e n i a 9 kwadratow 52 i i =PeriodWar ( i 1); 53 j j=periodwar ( j 1); 54 n=i i L+j j ; suma+= (S+n ) ; 55 n=i i L+j ; suma+= (S+n ) ; 56 j j=periodwar ( j +1); 57 n=i i L+j j ; suma+= (S+n ) ; 58 // srodkowy w i e r s z o t o c z e n i a 9 kwadratow 59 j j=periodwar ( j 1); 60 n=i L+j j ; suma+= (S+n ) ; 61 n=i L+j ; suma+= (S+n ) ; 62 j j=periodwar ( j +1); 63 n=i L+j j ; suma+= (S+n ) ; 64 // dolny w i e r s z o t o c z e n i a 9 kwadratow 65 i i =PeriodWar ( i +1); 66 j j=periodwar ( j 1); 67 n=i i L+j j ; suma+= (S+n ) ; 68 n=i i L+j ; suma+= (S+n ) ; 69 j j=periodwar ( j +1); 70 n=i i L+j j ; suma+= (S+n ) ; 71 72 73 i f ( suma<3) stan =0; // za malo komorek z a j e t y c h 74 else { 75 i f (suma>=3 && suma<5) stan =1; // warunki optymalne d l a komorek 76 else stan =0; // p r z e p e l n i e n i e 77 } 78 79 return stan ; 80 } 81 82 83 int PeriodWar ( int i ){ // metoda dbajaca aby wartosc 84 int k=i ; // argumentu i b y l a w [ 0, L 1] 85 i f ( i <0) k=l 1; 86 else { 87 i f ( i>=l) k=0; 88 } 89 return k ; 90 } 91 92 } ; 93 94 void WarunkiPocz ( int s, int L){ 95 int n ; 96 97 // najpierw wypelniamy zerami c a l a s i a t k e kwadratowa M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 10 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ 98 for ( int i =0; i<l ; i ++){ 99 for ( int j =0; j<l ; j ++){ 100 n=i L+j ; 101 ( s+n)=0; 102 } 103 } 104 105 // wypelniamy jedynkami 9 kwadratow na srodku s i a t k i 106 107 n=(l/2) L+L/ 2 ; ( s+n)=1; ( s+n 1)=1; ( s+n+1)=1; 108 n=(l/2+1) L+L/ 2 ; ( s+n)=1; ( s+n 1)=1; ( s+n+1)=1; 109 n=(l/2 1) L+L/ 2 ; ( s+n)=1; ( s+n 1)=1; ( s+n+1)=1; 110 } 111 112 int Z e r u j S i a t k e ( int tab, int L){ 113 114 for ( int i =0; i <L ; i ++){ 115 for ( int j =0; j<l ; j ++){ 116 ( tab+i L+j )=0; 117 } 118 } 119 120 } 121 122 void ZapisDoPlikuPPM ( int N, int M, int S ){ 123 124 fstream WY; // d e k l a r a c j a 125 WY. open ( serweta.ppm, i o s : : out ) ; // i z a p i s do p l i k u serweta. ppm 126 127 128 // Najpierw piszemy symbol P3 k t o r y oznaczac b e d z i e ze k o l o r y 129 // beda kodowane w ASCII 130 131 WY<< P3 <<endl ; 132 133 //potem piszemy dwie l i c z b y c a l k o w i t e N M r e p r e z e n t u j a c e 134 // odpowiednio l i c z b e kolumn i l i c z b e w i e r s z y obrazka 135 // 136 WY<<M<< <<N<<endl ; 137 //W k o l e j n e j l i n i i polecen piszemy maksymalna l i c z b e kolorow 255 138 139 WY<<255<<endl ; 140 141 // Nastepnie piszemy t r o j k i RGB l i c z b c a l k o w i t y c h 142 // z p r z e d z i a l u [ 0, 2 5 5 ] o l i c z b i e t r o j e k rownej NxM 143 144 int r, g, b ; 145 int n ; 146 147 for ( int i =0; i <M; i ++){ 148 for ( int j =0; j<n; j ++){ 149 150 n=i M+j ; 151 152 i f ( ( S+n)==1)WY<<255<< <<0<< <<0<<endl ; 153 else WY<<255<< <<255<< <<255<<endl ; M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 11 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ 154 } 155 } 156 157 WY. c l o s e ( ) ; // zamkniecie z a p i s u 158 } 159 160 void ZamienSiatki ( int A, int B, int L2 ){ 161 for ( int n=0;n<l2 ; n++){ 162 (A+n)= (B+n ) ; 163 } 164 } 165 166 int main ( ) { 167 168 cout<< Wprowadz wymiar liniowy sieci kwadratowej L= ; 169 int L ; 170 cin>>l ; 171 int L2=L L ; 172 173 cout<< Podaj liczbe krokow czasowych ewolucji automatu komorkowego N= ; 174 int Nkrokow ; 175 cin>>nkrokow ; 176 177 // d e k l a r a c j a dynamiczna t a b l i c y SIATKA [ ] 178 int SIATKA=new int [ L2 ] ; //w kroku t 179 // wtedy n t y element t a b l i c y oznacza w i e r s z i oraz kolumne j 180 // i=n/l oraz j=n % L 181 182 183 int DUBEL=new int [ L2 ] ; // s i a t k a d u b e l w kroku t+1 184 185 186 // Deklarujemy warunki poczatkowe z a p e l n i e n i a t a b l i c y SIATKA 187 //w p o s t a c i z a p e l n i o n y c h 9 kwadratow 188 // p o z o s t a l e elementy s i a t k i sa n i e z a p e l n i o n e 189 190 191 WarunkiPocz (SIATKA, L ) ; 192 193 // a l o k a c j a o b i e k t u z k l a s y Otoczenie 194 Otoczenie A(L ) ; // o b i e k t z metoda do w y l i c z e n i a 195 // stanu s a s i e d z t w a s k l a d a j a c e g o s i e z 9 kwadratow 196 197 for ( int t =0; t<nkrokow ; t++){ 198 Z e r u j S i a t k e (DUBEL, L ) ; // wyzerowanie elementow s i a t k i dubla 199 // stany z a j e t o s c i elementow s i a t k i 200 // dotycza kroku w t+1 201 for ( int n=0;n<l2 ; n++){ 202 (DUBEL+n)=A. OkreslStanOtoczenia (SIATKA, n ) ; //argumentem 203 // j e s t SIATKA d l a kroku t 204 } 205 206 207 ZamienSiatki (SIATKA,DUBEL, L2 ) ; //podmiana s i a t e k 208 } 209 M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 12 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ 210 ZapisDoPlikuPPM (L, L,SIATKA ) ; 211 212 return 0 ; 213 } Rysunek 6: Wynik działania dwuwymiarowego automatu komórkowego z regułami przeżycia we wzorach (6) po 1000 kroków czasowych i warunkach pocątkowych w postaci zapełnionych 9 kwadratów na środku siatki. W przypadku tego programu skorzystaliśmy z małej sztuczki polegającej na tym że do zapisu stanów L L kwadratów użyliśmy tablicy jednowymiarowej zamiast kwadratowej. W tym przypadku tablica jednowymiarowa SIATKA[0.. L 2 1] przebiegała L 2 kwadratów sieci kwadratowej wierszami od góry do dołu jak poniżej: 0 1 2... L-1 L L+1 L+2... 2L-1... L(L-1) L(L-1)+1 L(L-1)+2... L 2-1 Wtedy element (i, j) można wyliczyć z następujących równań: M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 13 Materiał dystrybuowany bezpłatnie
0.2 Dwuwymiarowe automaty komórkowe Przykłady programowania w C++ i = n/l j = n%l (7) gdzie n = 0, 1,..., L 2 1 jest indeksem tablicy jednowymiarowej. M.R. Dudek dla < OWK/ > http://www.owk.if.uz.zgora.pl 14 Materiał dystrybuowany bezpłatnie