Życie w RAM-ie

Po tych czynnościach wstępnych zabierajmy się do pracy. Zacznijmy od utworzenia mechanizmu mutacji, czyli przypadkowej zmienności formuły (genotypu) stworka (rysunek 2). Potrzebna będzie funkcja mogąca zmienić wartość dowolnego parametru struktury Stworek. Będzie nieskomplikowana, ale długa, bo każdy gen wymaga innego potraktowania algorytmem modyfikującym. Wprowadźmy także do gry parametr intensywnosc, który w jakiś sposób będzie regulował natężenie mutacji. Proponuję - ale się nie upieram - taki oto kształt algorytmu:

mutuj( int intensywnosc)

{

int co, il_przekszt, nr;

if( random( 101) < intensywnosc)

{

//która cecha (gen) mutuje?

co = random( 8);

il_przekszt = S.il_przekszt;

//które przekształcenie mutuje?

nr = random( il_przekszt);

switch( co)

{

case 0: //liczba przekształceń +/- 1

il_przekszt = il_przekszt + random(3)-1;

if( il_przekszt > MAX_IL_PRZEKSZT)

il_przekszt = MAX_IL_PRZEKSZT;

if( il_przekszt < 2)

il_przekszt = 2;

//przybyło przekształceń?

if( il_przekszt > S.il_przekszt)

{ //jeśli tak, zainicjuj nowe poprzednim

S.G[il_przekszt-1][0]=S.G[il_przekszt-2][0];

S.G[il_przekszt-1][1]=S.G[il_przekszt-2][1];

S.G[il_przekszt-1][2]=S.G[il_przekszt-2][2];

S.G[il_przekszt-1][3]=S.G[il_przekszt-2][3];

S.G[il_przekszt-1][4]=S.G[il_przekszt-2][4];

S.G[il_przekszt-1][5]=S.G[il_przekszt-2][5];

S.P[il_przekszt-1] = S.P[ il_przekszt - 2];

}

S.il_przekszt = il_przekszt;

brea

k;

case 1: //mutacja genu 0 na głębokość +/-0.1

S.G[ nr][ 0] = S.G[ nr][ 0] +

(random( 2001) - 1000) / 10000.;

break;

case 2: //mutacja genu 1 na głębokość +/-0.1

S.G[ nr][ 1] = S.G[ nr][ 1] +

(random( 2001) - 1000) / 10000.;

//... geny 2, 3, 4, 5 - analogicznie

case 7: //mutacja prawdopodobieństw

S.P[ nr] = S.P[ nr] + random( 21) - 10;

if( S.P[ nr] < 1)

S.P[ nr] = 1;

}

}

}

Funkcja ta przypadkowo uszkadza jakiś fragment łańcucha genetycznego. Parametr intensywnosc blokuje wejście do funkcji tym łatwiej, im jest mniejszy i jego działanie jest zgodne z intuicyjnym odczuciem intensywności mutacji. Parametr co kieruje uwagę funkcji na konkretny gen. Długa fraza switch() pracowicie opisuje mechanizm zmiany każdego genu. Trzeba być bardzo ostrożnym - zmiana nie może naruszyć reguł działania stworka, np. liczba przekształceń zawsze musi się zawierać w zakresie od 2 do MAX_IL_PRZEKSZT, a każdy współczynnik afiniczny powinien być niewielką liczbą rzeczywistą.

Genotyp stworka i przytoczony tutaj algorytm jest zresztą i tak za krótki - już widzimy, że brakuje np. implementacji i zmienności koloru afinicznego dywanu (kolorem zajmowaliśmy się miesiąc temu). Więcej cech stworka znajdziecie w załączonych materiałach programistycznych.

Życie w RAM-ie

Rysunek 5. Zbyt duża intensywność rozmnażania w stosunku do mutacji prowadzi do upodobnienia wszystkich stworków - pula genetyczna się wyjaławia. Te mgliste organizmy mają podobne ustroje. Jest to bardzo niebezpieczne, bo najdrobniejsza zmiana presji środowiska (u nas - upodobań oceniającego) prowadzi do śmierci całej społeczności. Tylko precyzyjnie wyważony udział intensywności mutacji i rozmnażania powoduje powstanie populacji zdolnych do stabilnego istnienia i przygotowanych na nieoczekiwane zmiany. Brzydkie stworki też są potrzebne...

Życie w RAM-ie

Rysunek 6. Jest pomysł, aby wystawić na łąkę monitory, na których będą wyświetlane cyfrowe kwiaty. Kamery obserwowałyby, do których monitorów najczęściej podlatują owady, zmylone pięknem prezentowanej grafiki. Odpowiedni algorytm genetyczny - opracowując dane z kamer - manipulowałby współczynnikami cyfrowych kwiatów. Kierunek ewolucji tych roślin wytyczałyby owady.

Teraz skoncentrujemy się na następnym etapie - ocenie bieżącego stanu stworka. Ocenę będziemy wystawiać osobiście - ot taki dziwny świat, w którym ktoś ocenia i szereguje obywateli. Oczywiście to zły, korupcjogenny pomysł na społeczeństwo, ale za to łatwy do implementacji. Chciałoby się tutaj dostrzec trochę szersze analogie ze światem za oknem, ale trzymajmy się tematu tego artykułu...

Aby oceniać stworki, musimy mieć nie jednego, a całe ich społeczeństwo oraz lepszy interfejs programu (porównaj rysunek 3). Musimy dokładnie widzieć stworki, mieć wywiad - wgląd w ich społeczność - i dopiero wtedy kliknięciami myszy możemy wskazywać te, które nagrodzimy i te, które skażemy na śmierć. Wprowadzamy do programu dwie zmienne - numery stworka najlepszego i najgorszego:

int najlepszy; //numer akurat najlepszego...

int najgorszy; //...i najgorszego stworka

W interfejsie programu z rysunku 3 zmienne te są ustawiane za pomocą kliknięć odpowiednio zatytułowanych przycisków.

Po zrealizowaniu przypadkowej zmienności genotypów oraz presji środowiska (czyli wydzielania najlepszego i najgorszego stworka) czeka nas etap ostatni - implementacja narodzin i śmierci w populacji stworków. Jak już wspominałem, najlepszy stworek oraz stworek wylosowany umieszczą swoje wymieszane geny w tablicy najgorszego stworka. Najgorszy stworek tym samym opuści populację. Najlepszy przekaże swoje cechy potomkowi.

Oto propozycja algorytmu rozmnażania:

rozmnazaj( int intensywnosc)

{

int i, j, partner, czyj_gen, il_przekszt;

if( random( 101) < intensywnosc)

{

partner = random( IL_

STWORKOW);

czyj_gen = random( 2);

//0 - gen najlepszego, 1 - partnera

if( czyj_gen == 0)

il_przekszt = S[ najlepszy].il_przekszt;

else

il_przekszt = S[ partner].il_przekszt;

S[ najgorszy].il_przekszt = il_przekszt;

//dziedziczenie współczynników

for( i = 0; i < il_przekszt; ++i)

{

czyj_gen = random( 2);

if( czyj_gen == 0)

{

for( j = 0; j < 6; ++j)

S[ najgorszy].G[ i][ j] =

S[ najlepszy].G[ i][ j];

}

else

{

for( j = 0; j < 6; ++j)

S[ najgorszy].G[ i][ j] =

S[ partner].G[ i][ j];

}

//dziedziczenie prawdopodobieństw

czyj_gen = random( 2);

if( czyj_gen == 0)

S[ najgorszy].P[ i] = S[ najlepszy].P[ i];

else

S[ najgorszy].P[ i] = S[ partner].P[ i];

//dziedziczenie kolorów

czyj_gen = random( 2);

if( czyj_gen == 0)

S[ najgorszy].K[ i] = S[ najlepszy].K[ i];

else

S[ najgorszy].K[ i] = S[ partner].K[ i];

}

}

}


Nie przegap

Zapisz się na newsletter i nie przegap najnowszych artykułów, testów, porad i rankingów: