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
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
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
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
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
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
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
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
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
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
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 „
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... i
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)