background image

CZEŚĆ!

Funkcje.

Twoje funkcje wyglądają tak:

f1(x) = x^2

f2 (x) = 3 * sin(x)

A teraz obie funkcje na jednym rysunku:

Trzeba przy pomocy algorytmu genetycznego znaleźć miejsce przecięcia wykresów tych funkcji. Z rysunku 

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0.0

0.5

1.0

1.5

2.0

2.5

3.0

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0

1

2

3

4

5

6

7

8

9

10

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0

1

2

3

4

5

6

7

8

9

10

background image

widać, że wykresy przecinają się dla x=1.7, a dokładniej, to dla x=1.7221, ponieważ
(1.7221)^2 

= 2.9656284

3*sin(1.7221) = 2.9657263
czyli różnica między wynikami wynosi tylko 0.0000979. Jeżeli algorytm genetyczny zadziała poprawnie, to 
uzyska się wynik w okolicy x=1.7221.

Jest tu jednak pewien haczyk. Klasyczny algorytm genetyczny nadaje się tylko do zadań typu „znaleźć 
maksimum funkcji f(x)=...” , a to dlatego, że zastosowano w nim metodę ruletki. Żeby od zadania „znaleźć 
miejsce przecięcia się wykresów funkcji ...” przejść do zadania „znaleźć maksimum funkcji ...”, należy zrobić 
kilka sztuczek matematycznych.

Po pierwsze, funkcje odejmujemy od siebie i uzyskujemy taki wykres:

f1(x) – f2(x) = x^2 – 3*sin(x)

Zauważ, że funkcja osiąga wartość zero gdy x=1.7,  funkcja ma wartości ujemne i dodatnie a jej maksimum jest 
dla x=3.14. Gdybyśmy taką funkcję zbadali algorytmem genetycznym to znalazłby on jej maksimum równe 
x=3.14, a to nie jest to, co chcieliśmy :-). Dlatego też robimy drugą sztuczkę matematyczną i rysujemy wykres 
wartości bezwzględnych różnicy tych funkcji:

abs( f1(x) – f2(x) )

Zauważ, że funkcja ma minimum dla x=1.7, ale maksimum ma dla x=3.14 (tak jak poprzednia), więc 
gdybyśmy ją zbadali algorytmem genetycznym to znaleźlibyśmy jej maksimum x=3.14, a nie minimum x=1.7. 
Dlatego trzeba zrobić trzecią sztuczkę matematyczną – odwrócić wykres funkcji względem osi X. Można to 
zrobić odejmując ujemną wartość funkcji od jakiejś liczby, np. od dziesięciu:

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

-2

0

2

4

6

8

10

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0

1

2

3

4

5

6

7

8

9

10

background image

10  -  abs( f1(x) – f2(x) )

I to jest to, o co chodziło :-). Funkcja ma maksimum dla x=1.7 i na dodatek jest nieujemna. Jeżeli taką funkcję 
zbadasz algorytmem genetycznym, to powinien on znaleźć jej maksimum wynoszące x=1.7. A jeżeli znajdziesz 
jej maksimum, to przechodząc przez te „sztuczki matematyczne” do tyłu znajdziesz miejsce przecięcia się 
wykresów funkcji x^2 i 3*sin(x). Czyli ostatecznie funkcja, którą będziesz badał algorytmem genetycznym 
będzie funkcją f(x) = 10 – abs(  x^2 - 3*sin(x)  ), x należy do <0.2 ... 3.14>.

Funkcja, która jest na ostatnim rysunku to funkcja dostosowania. Mówi ona, jak „dobry” jest chromosom o 
jakimś fenotypie, a fenotyp reprezentuje tutaj wartość x. Na przykład chromosom o fenotypie x=3 jest bardzo 
„kiepski”, bo wartość jego funkcji dostosowania wynosi 1.5, za to chromosom o fenotypie x=2.5 jest już 
„niezły”, bo wartość jego funkcji dostosowania wynosi 5.5. Oczywiście chromosomy „najlepsze” to te, które 
maja fenotypy x=1.7, bo ich wartość funkcji dostosowania jest równa aż 10.

I tutaj pojawia się kolejny haczyk, a raczej całkiem spory hak. Napisałem, że chromosomy „najlepsze” to te, 
które mają fenotyp x=1.7. Ale z wykresu tej funkcji wynika, że do chromosomów „bardzo dobrych” można 
zaliczyć wszystkie, których fenotypy reprezentują wartości x od 0.2 do -powiedzmy- 2.1 , ponieważ dla tych 
wartości x wartość funkcji dostosowania jest wysoka - powyżej 8. Gdy uruchomisz algorytm genetyczny, to 
pod koniec (przy wysokich numerach pokolenia) w populacji zostają już tylko chromosomy „bardzo dobre” i 
„najlepsze”, te „gorsze” zostały z populacji usunięte. Na początku pisałem, że algorytm znajdzie chromosom 
„najlepszy” (x=1.7), jednak w przypadku takiej funkcji ten „najlepszy” nie musi wcale mieć wartości x=1.7, 
może mieć wartość 0.2, albo 0.5, albo 1.5 albo 1.9 – wszystkie one mają podobną wartość funkcji 
dostosowania, więc są równie „dobre”. Dlatego też nie można się dziwić, jeśli algorytm powie, że „najlepszy” 
jest chromosom o x=0.2 - taki chromosom jest prawie tak samo dobry, jak ten o x=1.7.

Program. Program po prostu działa :-). Po uruchomieniu wyrzuca on wyniki do pliku „wyniki.txt” w tym 
samym katalogu, w którym jest binarka *.exe. Najlepiej zrobić tak: uruchom Dev-C++ i wczytaj treść 
programu ProjektAI.cpp. Teraz zmieniasz parametry w programie (np. prawdopodobieństwo krzyżowania, 
mutacji, liczba pokoleń), kompilujesz i uruchamiasz program (F9), który wyniki wyrzuca do pliku „wyniki.txt”.

Przykładowo, dla takich parametrów:
    const int lp=50; //liczba pokoleń w eksperymencie
    const float a=0.2; //wartość początkowa przestrzeni poszukiwań
    const float b=3.14; //wartość końcowa przestrzeni poszukiwań
    const int N=10; //liczba genów w chromosomie
    const int pula=30; //liczba osobników w populacji (parzysta)
    const float pk=0.7; //prawdopodobieństwo krzyżowania
    const float pm=0.00; //prawdopodobieństwo mutacji
    bool elitarna=false; //dla strategi klasycznej wpisać false, dla 
elitarnej – true

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0

1

2

3

4

5

6

7

8

9

10

background image

program do pliku „wyniki.txt” wyrzucił takie wyniki:

   0 +7.357 +9.709    3   1101010001 1.793

   1 +7.539 +9.746    5   0001010001 1.785
   2 +8.912 +9.746   21   0001010001 1.785

   3 +8.762 +9.722   16   0101010001 1.791
   4 +8.777 +9.976   12   0000100001 1.716

   5 +8.929 +9.976   13   0000100001 1.716
   6 +8.890 +9.991   15   1100100001 1.725

   7 +8.810 +9.991   26   1100100001 1.725
   8 +8.785 +9.648    1   0000110001 1.808

   9 +8.887 +9.648    3   0000110001 1.808
  10 +8.910 +9.648    2   0000110001 1.808

  11 +9.066 +9.648    2   0000110001 1.808
  12 +9.149 +9.623   27   0100110001 1.814

  13 +9.059 +9.611    5   1100110001 1.816
  14 +9.094 +9.648   26   0000110001 1.808

  15 +9.061 +9.547    2   0001110001 1.831
  16 +8.916 +9.547   17   0001110001 1.831

  17 +8.985 +9.547    6   0001110001 1.831
  18 +9.058 +9.547    1   0001110001 1.831

  19 +9.090 +9.547    0   0001110001 1.831
  20 +9.175 +9.547    4   0001110001 1.831

  21 +9.161 +9.547    5   0001110001 1.831
  22 +9.143 +9.547    2   0001110001 1.831

  23 +9.103 +9.547    4   0001110001 1.831
  24 +9.083 +9.547    1   0001110001 1.831

  25 +9.147 +9.547    8   0001110001 1.831
  26 +9.152 +9.547    4   0001110001 1.831

  27 +9.216 +9.547    7   0001110001 1.831
  28 +9.210 +9.547    0   0001110001 1.831

  29 +9.177 +9.547    0   0001110001 1.831
  30 +9.131 +9.547    5   0001110001 1.831

  31 +9.127 +9.547    1   0001110001 1.831
  32 +9.123 +9.547    4   0001110001 1.831

  33 +9.123 +9.547    5   0001110001 1.831
  34 +9.121 +9.547   16   0001110001 1.831

  35 +9.104 +9.547    3   0001110001 1.831
  36 +9.209 +9.496    0   0011110001 1.842

  37 +9.273 +9.522    7   0101110001 1.837
  38 +9.291 +9.522    0   0101110001 1.837

  39 +9.261 +9.547   10   0001110001 1.831
  40 +9.187 +9.547   17   0001110001 1.831

  41 +9.174 +9.547    6   0001110001 1.831
  42 +9.234 +9.547   25   0001110001 1.831

  43 +9.293 +9.547    8   0001110001 1.831
  44 +9.367 +9.547   10   0001110001 1.831

  45 +9.422 +9.547    8   0001110001 1.831
  46 +9.394 +9.547    6   0001110001 1.831

  47 +9.393 +9.522    6   0101110001 1.837
  48 +9.362 +9.496    2   0011110001 1.842

  49 +9.332 +9.496    3   0011110001 1.842

Kolejne kolumny oznaczają:

1 – numer pokolenia
2 – średnia wartość funkcji dostosowania w populacji
3 – maksymalna wartość funkcji dostosowania w populacji
4 – numer w populacji chromosomu, który ma największą wartość funkcji dostosowania (mało

przydatna rzecz w tym miejscu)

5 – chromosom, który w całej populacji ma największą wartość funkcji dostosowania
6 – wartość fenotypu chromosomu

background image

Jak się dobrze przyjrzeć, to największa wartość ŚREDNIEJ WARTOŚCI funkcji dostosowania występuje w 45. 
pokoleniu – wynosi ona 9.422 (teoretyczne maksimum wynosi 10). Dla tego pokolenia chromosom o
największej wartości funkcji dostosowania jest taki: 0001110001, a wartość jego fenotypu wynosi 1.831. 
Czyli algorytm nie znalazł „najlepszego” chromosomu (najlepszy jest dla x=1.7), ale znalazł „bardzo dobry” 
(x=1.831). Teraz trzeba obejrzeć wykres średniej wartości funkcji dostosowania w populacji:

Na osi poziomej są pokolenia, na pionowej – średnie wartości funkcji dostosowania w pokoleniu. Widać, że na 
początku populacja była „taka sobie” (śred. wart. f. dost. = 7.5), ale szybko stała się „dobra” ( ...= 9), a pod 
koniec stała się już „bardzo dobra” (...= 9.5 ).

Teraz wezmę takie same parametry jak wyżej, ale wprowadzę mutację:
    const float pm=0.01; //prawdopodobieństwo mutacji

Program wyrzucił takie wyniki:

   0 +8.058 +9.987   15   1000100001 1.719
   1 +8.421 +9.762    9   0011111110 1.659

   2 +8.140 +9.762   21   0011111110 1.659
   3 +8.622 +9.746    1   0001010001 1.785

   4 +8.687 +9.496   22   0011110001 1.842
   5 +8.711 +9.496   18   0011110001 1.842

   6 +8.695 +9.841   24   0000010001 1.762
   7 +8.614 +9.547    6   0001110001 1.831

   8 +8.730 +9.470   28   0111110001 1.848
   9 +8.881 +9.470   18   0111110001 1.848

  10 +8.986 +9.773    2   1011111110 1.661
  11 +9.033 +9.773   13   1011111110 1.661

  12 +9.029 +9.773    2   1011111110 1.661
  13 +9.005 +9.783   25   0111111110 1.664

  14 +8.984 +9.773   13   1011111110 1.661
  15 +8.961 +9.773    5   1011111110 1.661

  16 +8.871 +9.773    8   1011111110 1.661
  17 +9.080 +9.773    4   1011111110 1.661

  18 +9.140 +9.783   25   0111111110 1.664
  19 +9.081 +9.762    1   0011111110 1.659

  20 +9.032 +9.681   27   0010111110 1.636
  21 +9.070 +9.691    4   1010111110 1.638

  22 +9.078 +9.691   24   1010111110 1.638
  23 +9.089 +9.721    6   0001111110 1.647

  24 +9.041 +9.742   29   0101111110 1.653
  25 +9.024 +9.721   15   0001111110 1.647

  26 +9.082 +9.783    9   0111111110 1.664
  27 +8.991 +9.793    5   1111111110 1.667

  28 +9.017 +9.793   27   1111111110 1.667
  29 +8.986 +9.622    7   0111011110 1.618

0

5

10

15

20

25

30

35

40

45

50

7.0

7.5

8.0

8.5

9.0

9.5

background image

  30 +8.974 +9.632    8   1111011110 1.621
  31 +8.943 +9.593   29   1101011110 1.610

  32 +8.896 +9.574   12   1001011110 1.604
  33 +8.921 +9.701   17   0110111110 1.641

  34 +8.936 +9.691    6   1010111110 1.638
  35 +8.933 +9.574    0   1001011110 1.604

  36 +8.888 +9.472   26   0111101110 1.572
  37 +8.966 +9.613   13   1011011110 1.615

  38 +8.925 +9.613   13   1011011110 1.615
  39 +8.879 +9.603    6   0011011110 1.613

  40 +8.824 +9.358   15   1000101110 1.535
  41 +8.837 +9.481    2   1111101110 1.575

  42 +8.878 +9.613    9   1011011110 1.615
  43 +8.842 +9.613    3   1011011110 1.615

  44 +8.888 +9.613    3   1011011110 1.615
  45 +8.881 +9.613    6   1011011110 1.615

  46 +8.863 +9.613    8   1011011110 1.615
  47 +8.900 +9.613    2   1011011110 1.615

  48 +8.950 +9.622    6   0111011110 1.618
  49 +8.936 +9.622    8   0111011110 1.618

Największa wartość ŚREDNIEJ WARTOŚCI funkcji dostosowania występuje w 18. pokoleniu – wynosi ona 
9.140 . Dla tego pokolenia chromosom o największej wartości funkcji dostosowania jest taki: 0111111110, a 
wartość jego fenotypu wynosi 1.664. Czyli znowu algorytm nie znalazł „najlepszego” chromosomu, ale 
„bardzo dobry”. Dla tych wyników wykres jest taki:

Widać, że populacja była najpierw całkiem dobra (8.2), potem bardzo dobra (9.1), ale potem trochę się 
pogorszyła (8.9). To jest normalne – algorytm jest losowy... Funkcja jest bardziej poszarpana, co pewnie 
wynika z mutacji chromosomów.

Spróbuję teraz ustawić prawdopodobieństwo mutacji na 0.03, a liczbę pokoleń na 300. Najlepszy chromosom 
jest w pokoleniu 294, dla tego pokolenia śr. wart. f. dostosowania wynosi 9.34, najlepszy chromosom w tym 
pokoleniu ma postać 0100010001 co odpowiada 1.768.  Wykres jest taki:

0

5

10

15

20

25

30

35

40

45

50

8.0

8.2

8.4

8.6

8.8

9.0

9.2

background image

Wartość funkcji dostosowania nie jest zła, ale widać jej duże zmiany w kolejnych populacjach (wpływ dużego 
prawdopodobieństwa mutacji). Ten sam wykres, ale dla pierwszych 50 pokoleń jest taki:

We wszystkich przykładach widać, że algorytm działa poprawnie – populacja staje się coraz bardziej „idealna”, 
a znajdowane chromosomy mają fenotypy zbliżone do wartości 1.7 (która daje maksymalną wartość funkcji 
dostosowania).

Algorytm trzeba przetestować dla różnych parametrów: wartości prawdopodobieństwa krzyżowania, mutacji, 
liczby pokoleń, liczby bitów w chromosomie, liczby osobników w populacji itp. No i trzeba z tych badań 
wyciągnąć jakieś mądre wnioski :-)

Strategia elitarna. Trzeba jeszcze sprawdzić „algorytm z zastosowanym ulepszeniem” Najprościej będzie 
wziąć strategię elitarną. Polega ona na tym, że (o ile rozumiem) najlepszy chromosom nie podlega krzyżowaniu
ani mutacji, dzięki czemu jest „chroniony”. W klasycznym algorytmie najlepszy osobnik podlega
krzyżowaniu i mutacji, więc może on z „najlepszego” stać się „gorszym” albo i „najgorszym” i wypaść z
populacji.
Strategię elitarną w algorytmie zrealizowałem tak: przed funkcją KRZYZOWANIE() uruchamiana jest
funkcja NR_MAX_CHROM(), która znajduje chromosom o największej wartości funkcji dostosowania
w populacji (a właściwie znajduje jego numer). (Przed NR_MAX_CHROM() trzeba wywołać
OBLICZ_DOSTOSOWANIE()  ). Ten najlepszy chromosom jest zapamiętywany przez wywołanie funkcji
PAMIETAJ_NAJ_CHROM(). Potem następuje krzyżowanie i mutacje. Potem ten najlepszy chromosom
jest przez funkcję WPISZ_NAJ_CHROM() wpisywany z powrotem do populacji, na miejsce zerowe (bo
tak najłatwiej). Pojawia się tu problem: a co będzie, gdy w tym miejscu jest chromosom lepszy od tego
chronionego? Zostanie on zniszczony, a na jego miejsce wpisany ten chroniony. Byłoby najlepiej, gdyby
ten chroniony chromosom wpisywać na miejsce najgorszego chromosomu, ale to dodatkowa komplikacja
algorytmu, więc musi być tak, jak jest.

0

5 0

1 0 0

1 5 0

2 0 0

2 5 0

3 0 0

8 .0

8 .2

8 .4

8 .6

8 .8

9 .0

9 .2

9 .4

0

5

10

15

20

25

30

35

40

45

50

8.0

8.2

8.4

8.6

8.8

9.0

9.2

background image

W programie wybór strategii dokonuje się przez ustawienie zmiennej „elitarna” na początku kodu: jeśli
wpiszesz „elitarna=false;” to zostanie uruchomiona strategia klasyczna, jeśli „elitarna=true;” to zostanie
uruchomiona strategia elitarna (false i true wpisywać małymi literami!).

Algorytm elitarny trzeba sprawdzić tak samo jak algorytm klasyczny. Przykładowo, niech będą takie 
parametry:
    const int lp=50; //liczba pokoleń w eksperymencie
    const float a=0.2; //wartość początkowa przestrzeni poszukiwań
    const float b=3.14; //wartość końcowa przestrzeni poszukiwań
    const int N=10; //liczba genów w chromosomie
    const int pula=30; //liczba osobników w populacji (parzysta)
    const float pk=0.7; //prawdopodobieństwo krzyżowania
    const float pm=0.00; //prawdopodobieństwo mutacji
    bool elitarna=true; //dla strategi klasycznej wpisać false, dla 
elitarnej – true

Dla tych parametrów program wyrzucił takie wyniki:

   0 +8.169 +9.945   28   1110100001 1.736
   1 +9.412 +9.945    0   1110100001 1.736
   2 +9.626 +9.979   26   0010100001 1.727
   3 +9.672 +9.998   16   0100100001 1.722
   4 +9.838 +9.998    0   0100100001 1.722
   5 +9.760 +9.998    0   0100100001 1.722
   6 +9.643 +9.998    0   0100100001 1.722
   7 +9.740 +9.998    0   0100100001 1.722
   8 +9.706 +9.998    0   0100100001 1.722
   9 +9.725 +9.998    0   0100100001 1.722
  10 +9.766 +9.998    0   0100100001 1.722
  11 +9.746 +9.998    0   0100100001 1.722
  12 +9.889 +9.998    0   0100100001 1.722
  13 +9.946 +9.998    0   0100100001 1.722
  14 +9.953 +9.998    0   0100100001 1.722
  15 +9.960 +9.998    0   0100100001 1.722
  16 +9.951 +9.998    0   0100100001 1.722
  17 +9.948 +9.998    0   0100100001 1.722
  18 +9.957 +9.998    0   0100100001 1.722
  19 +9.950 +9.998    0   0100100001 1.722
  20 +9.959 +9.998    0   0100100001 1.722
  21 +9.959 +9.998    0   0100100001 1.722
  22 +9.943 +9.998    0   0100100001 1.722
  23 +9.946 +9.998    0   0100100001 1.722
  24 +9.943 +9.998    0   0100100001 1.722
  25 +9.959 +9.998    0   0100100001 1.722
  26 +9.967 +9.998    0   0100100001 1.722
  27 +9.977 +9.998    0   0100100001 1.722
  28 +9.979 +9.998    0   0100100001 1.722
  29 +9.989 +9.998    0   0100100001 1.722
  30 +9.991 +9.998    0   0100100001 1.722
  31 +9.991 +9.998    0   0100100001 1.722
  32 +9.991 +9.998    0   0100100001 1.722
  33 +9.992 +9.998    0   0100100001 1.722
  34 +9.990 +9.998    0   0100100001 1.722
  35 +9.991 +9.998    0   0100100001 1.722
  36 +9.994 +9.998    0   0100100001 1.722
  37 +9.996 +9.998    0   0100100001 1.722
  38 +9.996 +9.998    0   0100100001 1.722

background image

  39 +9.995 +9.998    0   0100100001 1.722
  40 +9.996 +9.998    0   0100100001 1.722
  41 +9.996 +9.998    0   0100100001 1.722
  42 +9.996 +9.998    0   0100100001 1.722
  43 +9.996 +9.998    0   0100100001 1.722
  44 +9.998 +9.998    0   0100100001 1.722
  45 +9.998 +9.998    0   0100100001 1.722
  46 +9.998 +9.998    0   0100100001 1.722
  47 +9.998 +9.998    0   0100100001 1.722
  48 +9.998 +9.998    0   0100100001 1.722
  49 +9.998 +9.998    0   0100100001 1.722

Widać, że największa wartość średniej wartości funkcji dostosowania była w 44. pokoleniu, wartość ta 
wynosiła 9.998, najlepszy chromosom miał postać  0100100001, co odpowiada fenotypowi x=1.722, czyli 
algorytm znalazł „idealny” chromosom. Wykres dla tych wyników jest taki:

Jak widać, na końcu populacja stała się „idealna”...

Porównanie strategii. Na koniec trzeba porównać obie strategie: klasyczną i elitarną. Oczywiście dane należy 
tak dobrać, aby rzeczywiście elitarna była lepsza od klasycznej :-) Wynik można przedstawić na rysunku, np. 
takim (tutaj prawdopodobieństwo mutacji = 0):

Na zielono jest strategia elitarna, na czerwono – klasyczna. Widać, że elitarna szybciej daje wynik i ten wynik 
jest lepszy – otrzymujemy na końcu populację „idealną”.

I jeszcze rysunek dla tych samych parametrów, ale z prawdopodobieństwem mutacji = 0.01:

0

5

10

15

20

25

30

35

40

45

50

8.0

8.2

8.4

8.6

8.8

9.0

9.2

9.4

9.6

9.8

10.0

0

5

10

15

20

25

30

35

40

45

50

7.5

8.0

8.5

9.0

9.5

10.0

background image

Rysunki. Rysunki można robić w Excelu, ale są też inne narzędzia. Ja robiłem je w Scilabie i Tobie
też to polecam. Robi się je błyskawicznie. Instrukcja:
Wejść na 

http://www.scilab.org/ 

i ściągnąć pliki scilab-4.1.2.exe (instalka, 16MB) oraz

man-eng-scilab-4.1.2.zip (dokumentacja, 3MB, nie trzeba ściągać ale może się przydać).
Zinstalować scilaba i uruchomić go („scilab-4.1.2”; nie „scilab console”.) Pokaże się okienko, gdzie
wpisuje się komendy. Można np. wpisać 2+2 i wcisnąć Enter, powinno pokazać się 4 :-) :

Ze scilaba wychodzi się wpisując 

exit. Teraz wpisz taką komendę:

x=0.2:0.001:3.14; f1=x.^2; f2=3*sin(x); plot(x,f1,'r', x,f2,'g')

Czyli tak:

Powinno pokazać się okienko z takim wykresem:

0

5

10

15

20

25

30

35

40

45

50

8.0

8.2

8.4

8.6

8.8

9.0

9.2

9.4

9.6

9.8

10.0

0.0

0.5

1.0

1.5

2.0

2.5

3.0

3.5

0

1

2

3

4

5

6

7

8

9

10

background image

Zamknij okienko z wykresem (jeśli nie zamkniesz, to kolejny rysunek zostanie nałożony na poprzedni).Teraz 
wpisz:

plot(x,f1,'k--', x,f2,'k:')

i już wiesz jak kolorować wykresy (r=red, k=black itp. Więcej? wpisz: help LineSpec).
Teraz przejdź do katalogu, w którym jest binarka projektu z AI i plik „wyniki.txt”. Robi się to podając
komendę „cd ...nazwa katalogu...”, np. tak:

(jest to komenda Scilaba. Jeśli w nazwie są spacje, to ścieżkę umieść w cudzysłowach:
cd „

c:\Documents

 and Settings\.......”)

Dla pewności wpisz „dir” i sprawdź, czy w katalogu, w którym jesteś jest plik wyniki.txt. Jeśli jest, to
podaj magiczną komendę:

clear; t=read('wyniki.txt',-1,6); x=t(:,1); sred=t(:,2); maks=t(:,3); 
[A,B]=max(sred); t(B,:), plot(x,sred,'r')

wszystko w jednej linii, o tak:

W odpowiedzi (ans) masz podany: numer pokolenia, w którym była największa wartość średniej funkcji
dostosowania (43), wartość tej funkcji w tym pokoleniu (9.965), wartość fenotypu dla chromosomu, który w 
tym pokoleniu miał największą wartość funkcji dostosowania (1.713). Widać też chromosom zapisany binarnie, 
ale jakoś dziwnie, bo Scilab myśli że to jest liczba dziesiętna :-) Chromosom zapisany binarnie znajdziesz w 
pliku „wyniki.txt”. Sprawdź też w tym pliku, czy to pokolenie jest rzeczywiście maksymalne (coś mi tu nie 
grało). Pokazuje Ci się także okienko z wykresem. Wykres możesz skopiować do schowka klikając: okienko z 
wykresem > File > Copy to clipboard > EnhMetafile. Jeżeli na wykresie chcesz mieć siatkę, to dodaj komendę 
xgrid; (..... plot(x,sred,'r'), xgrid;  )

Wpisane komendy w Scilabie można powtarzać klawiszami „strzałka w górę / strzałka w dół”.
Zatwierdza się Enterem. Teraz w Dev-C++ zmieniasz parametry algorytmu, kompilujesz i uruchamiasz
program, który wyniki zrzuca do pliku. Jak zrzuci, przejdź do Scilaba, wpisz linię zaczynającą się od 

clear... 

już masz wykres. Zamknij okienko z wykresem, zmień parametry w Devie, kompilacja, Scilab i tak w kółko. 
Rysunki robią się szybko i sprawnie i biednemu studentowi pozostaje tylko wymyślić trochę mądrych tekstów 
do sprawozdania... :-)

KONIEC

(04.12.2007)