Spis treści. Literatura 32

Podobne dokumenty
w analizie wyników badań eksperymentalnych, w problemach modelowania zjawisk fizycznych, w analizie obserwacji statystycznych.

Aproksymacja funkcji a regresja symboliczna

Algorytm genetyczny (genetic algorithm)-

Aproksymacja. funkcji: ,a 2. ,...,a m. - są funkcjami bazowymi m+1 wymiarowej podprzestrzeni liniowej X m+1

SCHEMAT ROZWIĄZANIA ZADANIA OPTYMALIZACJI PRZY POMOCY ALGORYTMU GENETYCZNEGO

Algorytmy genetyczne

ALGORYTMY GENETYCZNE ćwiczenia

Metody Rozmyte i Algorytmy Ewolucyjne

Strategie ewolucyjne (ang. evolu4on strategies)

Algorytmy genetyczne. Paweł Cieśla. 8 stycznia 2009

2) R stosuje w obliczeniach wzór na logarytm potęgi oraz wzór na zamianę podstawy logarytmu.

Algorytm Genetyczny. zastosowanie do procesów rozmieszczenia stacji raportujących w sieciach komórkowych

Metody numeryczne Technika obliczeniowa i symulacyjna Sem. 2, EiT, 2014/2015

Klasa 1 technikum. Poniżej przedstawiony został podział wymagań na poszczególne oceny szkolne:

Programowanie celowe #1

Algorytm. a programowanie -

Dobór parametrów algorytmu ewolucyjnego

3. Interpolacja. Interpolacja w sensie Lagrange'a (3.1) Dana jest funkcja y= f x określona i ciągła w przedziale [a ;b], która

Optymalizacja ciągła

Wykład z Technologii Informacyjnych. Piotr Mika

INTERPOLACJA I APROKSYMACJA FUNKCJI

ROZWIĄZYWANIE RÓWNAŃ NIELINIOWYCH

ROZKŁAD MATERIAŁU NAUCZANIA KLASA 1, ZAKRES PODSTAWOWY

Odkrywanie algorytmów kwantowych za pomocą programowania genetycznego

Metody przeszukiwania

MATeMAtyka 3. Przedmiotowy system oceniania wraz z określeniem wymagań edukacyjnych. Zakres podstawowy i rozszerzony. Zakres podstawowy i rozszerzony

Przedmiotowy system oceniania wraz z określeniem wymagań edukacyjnych klasa druga zakres rozszerzony

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

ROZKŁAD MATERIAŁU DO II KLASY LICEUM (ZAKRES ROZSZERZONY) A WYMAGANIA PODSTAWY PROGRAMOWEJ.

Programowanie genetyczne

1 Wprowadzenie do algorytmiki

Algorytmy genetyczne

Technikum Nr 2 im. gen. Mieczysława Smorawińskiego w Zespole Szkół Ekonomicznych w Kaliszu

6. Klasyczny algorytm genetyczny. 1

Algorytmy ewolucyjne NAZEWNICTWO

Liczby zespolone. x + 2 = 0.

SPIS TREŚCI WSTĘP LICZBY RZECZYWISTE 2. WYRAŻENIA ALGEBRAICZNE 3. RÓWNANIA I NIERÓWNOŚCI

Wymagania edukacyjne z matematyki klasa IV technikum

a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

Próbny egzamin z matematyki dla uczniów klas II LO i III Technikum. w roku szkolnym 2012/2013

1 Równania nieliniowe

PLAN WYKŁADU OPTYMALIZACJA GLOBALNA OPERATOR KRZYŻOWANIA ETAPY KRZYŻOWANIA

Kształcenie w zakresie podstawowym. Klasa 1

Programowanie genetyczne, gra SNAKE

Zadanie 5 - Algorytmy genetyczne (optymalizacja)

TEORETYCZNE PODSTAWY INFORMATYKI

Układy równań i nierówności liniowych

Zagadnienia do małej matury z matematyki klasa II Poziom podstawowy i rozszerzony

Metody numeryczne w przykładach

Szukanie rozwiązań funkcji uwikłanych (równań nieliniowych)

Definicje. Algorytm to:

Algorytmy genetyczne. Materiały do laboratorium PSI. Studia niestacjonarne

Algorytmy ewolucyjne - algorytmy genetyczne. I. Karcz-Dulęba

1. Synteza automatów Moore a i Mealy realizujących zadane przekształcenie 2. Transformacja automatu Moore a w automat Mealy i odwrotnie

Wyszukiwanie binarne

WYMAGANIA I KRYTERIA OCENIANIA Z MATEMATYKI W 3 LETNIM LICEUM OGÓLNOKSZTAŁCĄCYM

Matematyka dyskretna dla informatyków

WYMAGANIA EDUKACYJNE Z MATEMATYKI DLA KLASY III

Algorytm. Krótka historia algorytmów

MATeMAtyka 1. Przedmiotowy system oceniania wraz z określeniem wymagań edukacyjnych. Zakres podstawowy i rozszerzony Klasa pierwsza

Algorytmy genetyczne

Algorytmy genetyczne. Materiały do laboratorium PSI. Studia stacjonarne i niestacjonarne

Metody numeryczne. Sformułowanie zagadnienia interpolacji

ALGORYTMY EWOLUCYJNE W OPTYMALIZACJI JEDNOKRYTERIALNEJ

Wymagania edukacyjne matematyka klasa 1 zakres podstawowy 1. LICZBY RZECZYWISTE

Algorytmy genetyczne. Dariusz Banasiak. Katedra Informatyki Technicznej Wydział Elektroniki

MATeMAtyka 3. Propozycja przedmiotowego systemu oceniania wraz z określeniem wymagań edukacyjnych. Zakres podstawowy i rozszerzony

Wprowadzenie Metoda bisekcji Metoda regula falsi Metoda siecznych Metoda stycznych RÓWNANIA NIELINIOWE

1 Metody rozwiązywania równań nieliniowych. Postawienie problemu

Zad. 3: Układ równań liniowych

Spis treści. Przedmowa... XI. Rozdział 1. Pomiar: jednostki miar Rozdział 2. Pomiar: liczby i obliczenia liczbowe... 16

Algorytmy genetyczne w interpolacji wielomianowej

przetworzonego sygnału

5. Rozwiązywanie układów równań liniowych

Rozdział 2: Metoda największej wiarygodności i nieliniowa metoda najmniejszych kwadratów

Generowanie i optymalizacja harmonogramu za pomoca

Wymagania edukacyjne z matematyki w klasie III gimnazjum

Algorytmika i pseudoprogramowanie

Algorytmy stochastyczne, wykład 02 Algorytmy genetyczne

LUBELSKA PRÓBA PRZED MATURĄ 09 MARCA Kartoteka testu. Maksymalna liczba punktów. Nr zad. Matematyka dla klasy 3 poziom podstawowy

Plan wynikowy z przedmiotu: MATEMATYKA

ROZKŁAD MATERIAŁU NAUCZANIA KLASA 2, ZAKRES PODSTAWOWY

Strategie ewolucyjne. Gnypowicz Damian Staniszczak Łukasz Woźniak Marek

Metody rozwiązywania równań nieliniowych

Algorytmy genetyczne w optymalizacji

Poprawność semantyczna

Wymagania edukacyjne z matematyki dla zasadniczej szkoły zawodowej na poszczególne oceny

INFORMATYKA ELEMENTY METOD NUMERYCZNYCH.

Dr inż. Robert Wójcik, p. 313, C-3, tel Katedra Informatyki Technicznej (K-9) Wydział Elektroniki (W-4) Politechnika Wrocławska

Klasa 2 INFORMATYKA. dla szkół ponadgimnazjalnych zakres rozszerzony. Założone osiągnięcia ucznia wymagania edukacyjne na. poszczególne oceny

Zapisywanie algorytmów w języku programowania

V. WYMAGANIA EGZAMINACYJNE

Rozdział 1 PROGRAMOWANIE LINIOWE

Matematyka stosowana i metody numeryczne

WYMAGANIA EDUKACYJNE NA POSZCZEGÓLNE OCENY MATEMATYKA STOSOWANA - KLASA II I. POWTÓRZENIE I UTRWALENIE WIADOMOŚCI Z ZAKRESU KLASY PIERWSZEJ

Dopasowywanie modelu do danych

Zapis algorytmów: schematy blokowe i pseudokod 1

Analiza składowych głównych. Wprowadzenie

Języki programowania zasady ich tworzenia

III. STRUKTURA I FORMA EGZAMINU

Transkrypt:

Spis treści Aproksymacja funkcji a regresja symboliczna 2. Elementy aproksymacji funkcji............................... 2.. Aproksymacja średniokwadratowa dla dyskretnego zbioru argumentów.... 5.2 Regresja symboliczna.................................... 9 2 Przykładowe metody automatycznej aproksymacji funkcji 2 2. Programowanie genetyczne................................. 2 2.. Algorytmy genetyczne............................... 3 2..2 Zastosowanie do automatycznej aproksymacji.................. 4 2..3 Przykład....................................... 26 Literatura 32

Aproksymacja funkcji a regresja symboliczna Problem aproksymacji funkcji polega na tym, że funkcjęf(), znaną lub określoną tablicą wartości, należy zastąpić inną funkcją, f(), zwaną funkcją aproksymującą lub przybliżeniem funkcji F(). Przybliżenie takie powoduje pojawienie się błędów i problem oszacowania tych błędów oraz ich wielkość mają istotny wpływ na wybór metody aproksymacji. Gdy zbiór, na którym jest mierzony błąd aproksymacji, jest zbiorem dyskretnym, aproksymacja jest nazywana punktową, gdy jest to przedział jest nazywana integralną. Klasyczne metody aproksymacji funkcji zakładają określony zbiór funkcji bazowych, z których jest budowana poszukiwana funkcja oraz sposób ich wykorzystania (na przykład zbudowanie z nich tak zwanego wielomianu uogólnionego). Z kolei regresja symboliczna jest procedurą indukcji symbolicznej postaci funkcji, która dopasowuje się do danych wejściowych określonych tablicą wartości. Poszukiwana funkcja jest budowana z symboli zdefiniowanych przez badacza bez założenia jej modelu. Potrzeba przeprowadzenia procesu aproksymacji pojawia się, na przykład: w analizie wyników badań eksperymentalnych, w problemach modelowania zjawisk fizycznych, w analizie obserwacji statystycznych. W dalszej części omówiono i porównano pojęcia aproksymacji w ujęciu klasycznym (na podstawie [9][6][27][35][36]) oraz regresji symbolicznej (na podstawie [29]).. Elementy aproksymacji funkcji Aproksymacja jest problemem przybliżania funkcji, polegającym na wyznaczaniu dla danej funkcji F() takich funkcji f(), które w określonym sensie najlepiej przybliżają funkcję F() dla danego zbioru wejściowego. Podstawowym problemem aproksymacji funkcji jest określenie jej postaci. Najczęściej przyjmuje się, że poszukiwana funkcja ma postać wielomianu uogólnionego: f()=a 0 ϕ 0 ()a ϕ ()...a n ϕ n () () gdzieϕ 0,ϕ,...,ϕ n są funkcjami bazowymin wymiarowej podprzestrzeni liniowejx n przestrzeni X. Przy zadanych funkcjach bazowych należy więc wyznaczyć takie wartości współczynników a 0,a,...,a n, aby funkcjaf() spełniała określone warunki, na przykład minimalizowała normę różnicy F() f(). Norma taką przy tym może być: f =sup f() (norma Czebyszewa), a;b f 2 =( b a f 2,w=( b f() 2 d) 2 (normal 2 ), a w() f() 2 d) 2 (normal 2 z wagą), gdzie w() jest ciągłą, nieujemną funkcją wagową, dodatnią poza zbiorem miary zero. Gdy funkcja F() jest określona na dyskretnym zbiorze wartości, rozpatruje się normę: ( ) n F = [F( i )] 2 2 i=0 Dla poszukiwanej funkcji w postaci opisanej wzorem () należy określić odpowiednią podprzestrzeń przestrzenix n oraz związany z nią zbiór funkcji bazowychϕ k (). Często wybieranymi przestrzeniami są: 2

podprzestrzeń funkcji trygonometrycznych z funkcjami bazowymi:,sin,cos,sin2,cos2,...,sink,cosk szczególnie przydatna, gdy aproksymowana funkcja jest funkcją okresową, podprzestrzeń wielomianów stopnia co najwyżejnzjednomianami:,, 2, 3,..., n podprzestrzeń z bazą wielomianów:,( 0 ),( ),...,( n ) stosowana przy interpolacji wzorami Newtona. Tak więc zagadnienie najlepszej aproksymacji przy wybranych funkcjach bazowychϕ k () sprowadza się do znalezienia wartości współczynnikówa k takich, aby otrzymać minimum wyrażenia: F() (a 0 ϕ 0 ()a ϕ ()...a n ϕ n ()) Szczególnie interesująca jest aproksymacja wielomianowa, gdzie twierdzenia Weierstrassa (Tw. i Tw. 2) gwarantują, że zawsze można znaleźć wielomian o dowolnie małym odchyleniu od od poszukiwanej funkcji F() na przedziale a; b. Dowody wspomnianych twierdzeń można znaleźć na przykład w [], [7], czy [35] Tw. (Tw. Weierstrassa dla wielomianów algebraicznych) Jeżeli funkcjaf() jest ciągła na skończonym przedziale a;b, to dla każdegoε>0można dobrać takien, że jest możliwe utworzenie wielomianup n () stopnian, który spełnia nierówność: w całym przedziale a;b. F() P n () <ε Tw. 2 (Tw. Weierstrassa dla wielomianów trygonometrycznych) Jeżeli funkcja F() jest funkcją ciągłą i okresową o okresie2π, to dla każdegoε>0 istnieje wielomian trygonometryczny: spełniający dla wszystkichnierówność: w całym przedziale a;b. n S n ()=a 0 s k coskb k sink k= F() S n () ε Niestety nie ma jednak ogólnej metody umożliwiającej znajdowanie dla dowolnej funkcji ciągłej na a;b takiego wielomianu stopniannajlepiej ją przybliżającego. W zależności od przyjętego sposobu oszacowania błędów aproksymacji wyróżnia się trzy rodzaje aproksymacji: aproksymację interpolacyjną, aproksymację jednostajną, aproksymację średniokwadratową. 3

Y y=f() f( ) y=f() f( 0 ) 0 2 k n X Rysunek : Aproksymacja interpolacyjna. Y y=f() y=f() F( ) F( 0 ) 0 2 k n X Rysunek 2: Aproksymacja jednostajna i średniokwadratowa (funkcja F() zwykle nie jest znana jest dana zbiorem punktów). W przypadku aproksymacji interpolacyjnej, podobnie jak w zagadnieniu interpolacji, wymaga się, aby dana funkcja, f(), i funkcja szukana, F(), przyjmowały dokładnie te same wartości na danym, dyskretnym zbiorze argumentów X (Rys. ). Warunek ten może być uzupełniony warunkami wyrażającymi równość pochodnych w danych punktach, jeżeli wartości pochodnych zostaną zadane. Pozostałe rodzaje aproksymacji dopuszczają (zakładają) poszukiwanie funkcji, której wartości na dyskretnym zbiorze argumentówx są wynikami pomiarów, czyli mogą być obarczone błędami, i wtedy żądanie, aby poszukiwana funkcja przyjmowała w podanych punktach dokładnie takie wartości 4

nie ma sensu (Rys. 2). Poszukuje się więc funkcji jedynie przybliżajacej daną funkcję, która umożliwi jej wygładzenie, czyli pozwoli z danych zakłóconych błędami otrzymać gładką funkcję przybliżającą. W zadaniu aproksymacji jednostajnej dla funkcji F() określonej na przedziale a; b poszukuje się funkcjif() dającej najmniejsze maksimum różnicy międzyf() af() na całym przedziale a;b : F() f() = sup F() f() a;b Wreszcie aproksymacja średniokwadratowa polega na tym, aby dla funkcji F() określonej na przedziale a;b znaleźć minimum całki: F() f() = b a w()[f() f()] 2 d a dla funkcjif() danej na dyskretnym zbiorze argumentów znaleźć minimum sumy: n F() f() = w( i )[F( i ) f( i )] 2 (2) i=0 gdziew( i ) 0 dlai=,2,...n. W ramach przedstawionych rodzajów aproksymacji można znaleźć szereg metod różniących się zbiorem funkcji bazowych, bądź sposobem wykorzystania tych funkcji (na przykład funkcje wymierne). Przykładowe metody to: dla aproksymacji średniokwadratowej: aproksymacja wielomianowa, aproksymacja za pomocą wielomianów ortogonalnych, aproksymacja trygonometryczna, wykorzystanie szybkiej transformaty Fouriera, zastosowanie funkcji sklejanych, dla aproksymacji jednostajnej: metoda szeregów potęgowych, wykorzystanie przybliżenia Padégo, zastosowanie szeregów Czebyszewa. Całość problematyki aproksymacji wykracza poza ramy niniejszej pracy, stąd w dalszej części, jako przykład, zostanie omówiona aproksymacja średniokwadratowa za pomocą wielomianów dla funkcji określonej dla pewnego zbioru punktówx... Aproksymacja średniokwadratowa dla dyskretnego zbioru argumentów Jak wspomniano, w tym rodzaju aproksymacji dla funkcjiy=f(), która na pewnym zbiorzex punktów 0,,..., n przyjmuje wartościy 0,y,...,y n, poszukuje się takiej funkcjif() przybliżającej funkcjęf(), która zminimalizuje wyrażenie (2). Niechϕ 0,ϕ,...,ϕ n będzie zbiorem funkcji bazowych podprzestrzenix n. Należy znaleźć wielomian uogólniony reprezentujący funkcjęf(), będący najlepszym przybliżeniem średniokwadratowym funkcjif() na zbiorze, 2,..., n. Poszukuje się więc funkcji: m f()= a i ϕ i () (3) i=0 5

w której współczynnikia i minimalizują wartość wyrażenia (2). Następnie można wprowadzić funkcję: [ n m 2 H(a 0,a,...,a m )= w( j ) F( j ) a i ϕ i ( j )] = j=0 i=0 n w( j )Rj 2 (4) j=0 gdziew() jest funkcją wagową taką, żew( i )>0dlai=0,,...,n ar j jest odchyleniem w punkcie j. Funkcja wagowaw() zwykle ma stałą wartość, równą tożsamościowo jedności. Jednak w pewnych specjalnych przypadkach dobiera się inne funkcje wagowe, na przykład, aby otrzymane przybliżenie było w pewnych punktach lepsze ze względu na to, że w tych punktach wartości szukanej funkcji są znane z mniejszym błędem. Przyjmuje się wtedy w tych punktach większe wartości funkcji wagowej. Przy tych oznaczeniach, dla wyznaczenia warości współczynnikówa i należy obliczyć pochodne cząstkowe funkcjih względem zmiennycha i. Ponieważ musi być spełniony warunek: H a k =0, k=0,,...,m otrzymuje się układm równań liniowych zm niewiadomymia i : [ ] H n m = 2 w( j ) F( j ) a i ϕ i ( j ) ϕ k ( j )=0, k=0,,...,m (5) a k j=0 i=0 Dla przykładu zostanie przedstawiona aproksymacja funkcji danej tabelą Tab. za pomocą funkcji liniowej oraz kwadratowej. W rzeczywistości jest to funkcja: y=2 0 2 4 5 0 y 8 5.5 8 9 Tablica : Poszukiwana funkcja (y=2 0 ). Poszukiwana będzie funkcja w postaci wielomianu uogólnionego (3): m y= a i ϕ i () i=0 z funkcjami bazowymi (aproksymacja wielomianowa):,, 2, 3,..., n W pierwszym przypadku przyjmując m = (aproksymacja liniowa), poszukiwana będzie funkcja o postaci: y () =a 0 a W związku z powyższym i przy założeniu, że funkcja wagowa w() jest tożsamościowo równa 0, funkcjah zgodnie ze wzorem (4) przyjmie postać (metoda najmniejszych kwadratów): 4 H(a 0,a )= [y j (a 0 a j ] 2 j=0 Należy teraz znaleźć zbiór współczynnikówa i minimalizujący wartość powyższej funkcji. W tym celu trzeba rozwiązać układ równań: H(a 0,a ) a 0 =0 H(a 0,a ) a =0 6

czyli: 4 [y j (a 0 a j )] =0 j=0 4 [y j (a 0 a j )] j =0 j=0 lub 4 a 0 5 a j = 4 y j j=0 j=0 4 4 a 0 j a 2 j = 4 (6) j y j j=0 j=0 j=0 Po wstawieniu wartości j orazy j z Tab. układ (6) przyjmie postać: { 5a0 22a = 23.5 22a 0 46a = 242 (7) Rozwiązaniem układu równań (7) są wartości (z dokładnością do0.0): co daje poszukiwaną funkcję: { a0 = 8.39 a = 2.93 y () =2.82 7.70 z błędem kwadratowym aproksymacji wynoszącym ok.9.35. Drugie rozwiązanie powstanie przy założenium=2 we wzorze (3) i wykorzystaniu tego samego co poprzednio zbioru funkcji bazowych. Poszukiwana funkcja tym razem będzie miała postać: y (2) =a 0 a a 2 2 W tym przypadku układ równań wygląda następująco: H(a 0,a,a 2 ) a 0 H(a 0,a,a 2 ) a H(a 0,a,a 2 ) a 2 = 4 [y j (a 0 a j a 2 2 j )] =0 j=0 = 4 [y j (a 0 a j a 2 2 j)] j =0 j=0 = 4 [y j (a 0 a j a 2 2 j )] 2 j =0 j=0 czyli: 4 4 a 0 5 a j a 2 2 j = 4 y j j=0 j=0 j=0 4 4 a 0 j a 2 4 j a 2 3 j= 4 j y j j=0 j=0 j=0 j=0 4 a 0 2 4 j a 3 4 j a 2 4 j = 4 2 j y j j=0 j=0 j=0 j=0 Stąd: 5a 0 22a 46a 2 = 23.5 22a 0 46a 98a 2 = 242 46a 0 298a 0898a 2 = 276 oraz rozwiązanie (z dokładnością do0.0): a 0 = 2.4 a = 5.22 a 2 = 0.2 7

co daje aproksymację poszukiwanej funkcji: z błędem ok.3.65. Powyższe wyniki ilustruje Tab. 2 oraz Rys. 3. y (2) = 0.2 2 5.22 2.4 2 4 5 0 Błąd kwadratowy y 8.00.00 5.50 8.00 9.00 y () 4.88 2.06 3.58 6.40 20.50 9.35 y (2) 7.3 2.54 5.38 8.7 9.06 3.65 Tablica 2: Wartości funkcji:y=2 0 oraz funkcji aproksymujących:y() =2.82 7.70 iy (2) = 0.2 2 5.22 2.4. y y y y Rysunek 3: Wykresy funkcji:y=2 0 oraz funkcji aproksymujących: y () =2.82 7.70 iy (2) = 0.2 2 5.22 2.4. Należy dodać, że ponieważ proces znajdowania wyrażenia analitycznego przybliżającego funkcję daną tablicą wartości lub wykresem składa się w pierwszym kroku z wyboru postaci funkcji, a dopiero później określa się (wylicza) wartości współczynników tak, aby przyblizenie to było jak najlepsze, właśnie wybór postaci funkcji jest problemem kluczowym. Czasami istnieją pewne przesłanki dotyczące tej postaci, ale najczęściej wybiera się ją spośród pewnych stosunkowo prostych wzorców na przykład na zasadzie podobieństwa wykresu poszukiwanej funkcji do danej funkcji wzorcowej. Takimi wzorcami moga być: y=a b c y=e a2 bc y=ae b c y=a 2 bc y 2 =a 2 bc 8

y= ab cd y= a 2 bc y= a 2 bc y=a b c 2 oraz wiele innych. Często przed procesem wyliczania wartości parametrów ocenia się przydatność wybranego wzorca odpowiednimi metodami, na przykład metodą wyrównywania. Zwykle jednak nie ma pewności co do rzeczywistej postaci aproksymowanej funkcji..2 Regresja symboliczna Zadaniem regresji symbolicznej jest znalezienie symbolicznej postaci wyrażenia matematycznego (funkcji), która dokładnie (lub w zadowalającym stopniu) odzwierciedla określone wartości zmiennej zależnej dla podanego zbioru wartości zmiennych niezależnych. Jest to więc, w istocie, zadanie punktowej aproksymacji funkcji, z tym, że w tym przypadku poszukuje się nie tylko zbioru parametrów (współczynników) dla założonego modelu funkcji, lecz również samego modelu. Tym właśnie regresja symboliczna różni się od konwencjonalnej liniowej, kwadratowej, wielomianowej, czy trygonometrycznej aproksymacji funkcji. W odróżnieniu od metod konwencjonalnych, gdzie zakłada się postać modelu rozwiązania, a zadaniem procesu jest znalezienie zbioru warości odpowiednich współczynników modelu, regresja symboliczna znajduje zarówno model, jak i odpowiednie wartości jego parametrów. Tak sformułowane zadanie aproksymacji można zdefiniować poprzez zbiór niezależnych zmiennych wejściowych, Z, oraz zależną zmienną wynikową, y. Celem jest więc przybliżenie wartości zmiennej y używając zmiennych niezależnych Z oraz współczynników W, w taki sposób, aby: =f(z,w)ǫ gdzie ǫ reprezentuje szum. Jak wspomniano w p.., w standardowych metodach aproksymacji postać funkcji f jest predefiniowana. Przykładowo, dla aproksymacji liniowej, funkcja f ma założoną postać: f(z,w)=w 0 w...w n n gdziew jest poszukiwanym zbiorem wartości współczynników. W przeciwieństwie do technik klasycznych metody takie, jak Programowanie Genetyczne, niektóre podejścia probabilistyczne, czy Programowanie Mrowiskowe nie zakładają predefiniowanego modelu rozwiązania. Używają za to zbioru funkcji elementarnych, których kombinacja daje w rezultacie pełną postać poszukiwanej funkcji. Na przykład, mając dane funkcje -argumentoweh,...,h u oraz 2-argumentoweg,...,g b, można z ich kombinacji utworzyć wiele różnych wyrażeń, przykładowo: f(z,w)=h (g 2 (g ( 3,w ),h 2 ( ))) (8) Oczywiście dopuszczalna jest każda inna poprawna kombinacja zmiennych i funkcji. Zbiory H oraz G zwykle zawierają standardowe funkcje (lub operatory) arytmetyczne (dodawanie, odejmowanie, mnożenie, dzielenie), trygonometryczne (sinus, cosinus, tangens, itd.), logiczne (not, lub, i) czy logarytmiczne. W związku z tym zastąpienie symbolihig w funkcji (8) może dać wyrażenie: f(z,w)=log(( 3 w ) sin ) Tak więc w tym podejściu do aproksymacji funkcji poszukuje się kombinacji zmiennych, funkcji i współczynników tak, aby zminimalizować błąd funkcji dla danego zbioru danych wejściowych. Przy tym zarówno postać i wielkość funkcji, jak i wszystkie jej elementy składowe funkcje elementarne 9

oraz liczba i wartości współczynników są automatycznie znajdowane przez algorytm. Regresja symboliczna ma więc tę przewagę nad podejściem klasycznem do aproksymacji funkcji, że równolegle poszukuje tak postaci funkcji jak i jej parametrów, co jest często kluczowym problemem w analizie danych eksperymentalnych, gdzie określenie z góry poszukiwanego modelu jest bardzo trudne, czy wręcz niemożliwe. Dodatkowo, zbiór funkcji elementarnych może być rozszerzony o zbiór instrukcji dowolnego języka programowania, dzięki czemu problem regresji symbolicznej można uogólnić na zadanie automatycznego programowania automatycznego znajdowania programu, który będzie realizował czynności zdefiniowane w jego specyfikacji. Można więc powiedzieć, że regresja symboliczna jest procedurą indukcji równania symbolicznego, funkcji lub programu, które dopasowują się do danych wejściowych. Poszukiwane wyrażenia są budowane z symboli zdefiniowanego przez badacza alfabetu. Mogą to być symbole matematyczne, lub instrukcje dowolnego języka programowania. Dobór alfabetu jest ściśle związany z rodzajem stawianego problemu. System przeprowadzający regresję symboliczną w każdej iteracji generuje wiele kandydujących rozwiązańf k, które podlegają ocenie na podstawie zbioru danych wejściowych. Istnieje wiele miar dopasowania, wśród których można znaleźć: błąd bezwzględny będący sumą modułów różnic wartości funkcji w zbiorze wejściowym (funkcji poszukiwanejf) i wartości wyliczonej przez bieżące rozwiązanief k : f P = N i= F i fi k błąd kwadratowy: N ( f p= Fi fi k i= ) 2 średni błąd procentowy: APE= N N F i fi k i= F i 00% gdzie N jest liczbą przypadków testowych w zbiorze wejściowym. Tak więc regresja symboliczna może być traktowana jako próba (re)konstrukcji lub przybliżenia funkcji na podstawie danej tabeli wartości zakładając: zbiór operatorów, funkcji i stałych, funkcję oceny jakości przybliżenia. Na przykład szukając funkcji danej tabelą Tab., mając dane operatory, funkcje i stałe przedstawione w Tab. 3, oraz funkcję oceny (np. APE), można wygenerować różne postacie rozwiązania operatory funkcje stałe,,,/ sin(), (), 2, 5 Tablica 3: Operatory, funkcje i stałe wykorzystane przy budowie poszukiwanej funkcji. dokładnego, na przykład: 2 ( 3 2) 2 5 5 2 0

Nie ma przy tym żadnych ograniczeń nałożonych na aproksymowaną funkcję, w szczególności na liczbę zmiennych wejściowych. Tymi samymi metodami można szukać na przykład funkcji trzech zmiennych: ( y= u ) 2 v 3 otrzymując (przy określonym zbiorze operatorów, funkcji i stałych) przykładowe rozwiązania dokładne: ( ( v ) 3 u ( ) ( ) 2 3 u v ( ) u ( 3 ) 2 v ) 2 Oczywiście oprócz rozwiązań dokładnych metody typu Programowanie Genetyczne, podejścia probabilistyczne, czy Programowanie Mrowiskowe generują wiele rozwiązań charakteryzujących się różną dokładnością przybliżenia.

2 Przykładowe metody automatycznej aproksymacji funkcji //...Tutaj krótki wstęp... 2. Programowanie genetyczne Programowanie genetyczne, autorstwa J.Kozy, jest rozszerzeniem idei algorytmów genetycznych, zaproponowanych przez J.Hollanda, na przestrzeń programów komputerowych. Obie te metody należą do grupy programów ewolucyjnych, czyli systemów, które wykorzystują zasady ewolucji i dziedziczenia [3]. Oprócz nich do wspomnianej grupy można zaliczyć również: strategie ewolucyjne Rechenberga i Schwefela [37, 40], programowanie ewolucyjne Fogla [4], metody przeszukiwaia rozproszonego Glovera [8]. Systemy te działają na populacji potencjalnych rozwiązań stosując szereg operacji zaczerpniętych z genetyki: mutację, krzyżowanie, selekcję opartą na ocenie dopasowawnia osobników. Algorytmy genetyczne są szeroko stosowane w różnych dziedzinach: matematyce, fizyce, informatyce, technice i badaniach operacyjnych, biologii, medycynie, czy naukach społecznych. Można stwierdzić, że wśród porównywalnych metod nie mają one sobie równych pod względem różnorodności zatosowań i efektywności działania [9]. Wśród ich ważniejszych (oraz historycznych) zastosowań można znaleźć: adaptacyjny program do gry w sześć pionków [4], symulacja żywej komórki [38, 45], zaprojektowanie zestawu detektorów dla urządzenia rozpoznającego (między innymi postacie) [0], optymalizacja funkcji [2, 24], badanie efektu pozycyjnej nieliniowości w optymalizacji [7], optymalizacja rurociągu gazowego [20], optymalizacja strukturalna konstrukcji [2], obróbka medycznych obrazów rentgenowskich [3], rozwiązanie iterowanego dylematu więźnia [3, 5]. Podobne obszary zastoswań można wskazać dla programowania genetycznego: //... tutaj będą zastosowania... Niniejszy rozdział zawiera ogólne informacje o algorytmach genetycznych wprowadzając podstawowe pojęcia związane z tymi algorytmami. Następnie szczegółowo zostało opisane programowanie genetyczne w jego klasycznej formie z uwzględnieniem trzech struktur programów: drzewiastej, liniowej oraz grafowej. Przedstawiony na końcu rozdziału przykład ilustruje działanie algorytmu programowania genetycznego. 2

2.. Algorytmy genetyczne Algorytmy genetyczne zostały stworzone przez Johna Hollanda, który w swojej pionierskiej książce z 975 roku [23] pokazał, jak można zastosować zasadę ewolucji do rozwiązywania problemów obliczeniowych. Następnie algorytmy genetyczne zostały wzbogacone o wiele ulepszeń i modyfikacji, jednak podstawowa zasada działania pozostała ta sama. Algorytmy genetyczne używane są przede wszystkim do rozwiązywania problemów optymalizacyjnych, ponieważ operując na pewnym zbiorze potencjalnych rozwiązań, wykonują operacje (znane z genetyki) na każdym rozwiązaniu z tego zbioru, każde rozwiązanie oceniają i wprowadzają mechanizm symulujący dobór naturalny. Do opisu działania algorytmów genetycznych stosuje się pojęcia pochodzące z genetyki: osobnik (genotyp, chromosom) reprezentuje pojedyncze potencjalne rozwiązanie postawionego problemu, populacja to zbiór osobników (rozwiązań problemu) o określonej liczebności, gen stanowi pojedynczy składnik chromosomu. Klasyczne algorytmy genetyczne operują na rozwiązaniach (chromosomach) będących łańcuchami znaków alfabetu (genów) złożonego z cyfr 0 i. Inne wersje mogą operować na bardziej złożonych alfabetach z większą liczbą symboli lub na bardziej złożonych strukturach będących w szczególności tablicami wielowymiarowymi, drzewami lub sieciami. Reprezentację struktury chromosomu należy wybrać w zależności od zdefiniowanego problemu. W naukach przyrodniczych oprócz chromosomu występuje dodatkowo pojęcie genotypu podzbioru chromosomów definiującego strukturę danego osobnika. W algorytmach genetycznych przyjęto, że genotyp składa się z pojedynczego chromosomu, stąd utożsamia się te dwa pojęcia. Każdy osobnik, reprezentując potencjalne rozwiązanie problemu, jest oceniany za pomocą funkcji celu, zwanej w biologii funkcją przystosowania. Funkcja ta stanowi miernik zysku lub użyteczności wielkości, która ma być zmaksymalizowana. Im lepsze jest rozwiązanie opisane danym osobnikiem, tym większa jest wartość funkcji przystosowania tego osobnika. Na populacji osobników są wykonywane podstawowe operacje, za pomocą których następuje modyfikacja ich materiału genetycznego: krzyżowanie, mutacja, reprodukcja. Krzyżowanie (dokładniej krzyżowanie proste) to połączenie informacji genetycznej dwóch osobników (rodziców) tworząc dwóch potomków przez wymianę odcinków chromosomów rodzicielskich. Z kolei mutacja polega na zmianie jednego lub więcej genów wybranego chromosomu, jest to więc wprowadzenie pewnej dodatkowej zmienności w populacji. W praktyce w algorytmach genetycznych mutacja odgrywa drugorzędną rolę zarówno z tego powodu, że i taką rolę pełni w rzeczywistości biologicznej, jak i dlatego, że mutacja sama w sobie jest przypadkowym błądzeniem w przestrzeni rozwiązań. Aby otrzymać minimalny zestaw operacji wystarczający do skonstruowania elementarnego algorytmu genetycznego, do powyższych elementów należy dodać reprodukcję osobników (reprodukcję różnicującą, czyli selekcję). Polega ona na powieleniu każdego osobnika populacji w stosunku zależnym od wartości funkcji celu dla tego osobnika. Dzięki temu osobniki o wyższym przystosowaniu mają większe prawdopodobieństwo wprowadzenia jednego lub więcej potomków do nowej populacji, natomiast osobniki o niskim przystosowaniu mają niewielkie szanse przeżycia i reprodukcji. Struktura elementarnego algorytmu genetycznego jest taka sama, jak typowego programu ewolucyjnego [3].Przebieg tego algorytmu przedstawia Algorytm 2... 3

Algorytm : Elementarny algorytm genetyczny t:=0 Utwórz populację początkową(p(t)) Oceń(P(t)) while (not warunek końca) do begin t:=t P(t) := Selekcja(P(t )) Krzyżuj(P(t)) Mutuj(P(t)) Oceń(P(t)) end { Koniec algorytmu } Podsumowując podstawowe cechy algorytmów genetycznych można powiedzieć że: nie przetwarzają bezpośrednio problemu, lecz jego zakodowaną postać, operują na dużej liczbie rozwiązań (osobników), poszukują rozwiązania metodą próbkowania, korzystają tylko z funkcji celu, a nie z innych pomocniczych informacji, opierają się na probabilistycznym a nie deterministycznym modelu działania. Cechy te odróżniają algorytmy genetyczne od konwencjonalnych technik optymalizacji [9]. 2..2 Zastosowanie do automatycznej aproksymacji Autorem pomysłu programowania genetycznego jest Koza [29], który zaadaptował algorytmy genetyczne do celów automatycznej aproksymacji. W krótkim okresie czasu od opublikowania w 992 roku książki Kozy wydano ponad osiemset różnych publikacji poświęconych programowaniu genetycznemu. Zaproponowano wiele różnych systemów programowania genetycznego: systemy używające drzew, liniowych lub grafowych genomów, systemy preferujące krzyżowanie, systemy preferujące mutacje. Niektóre z nich łączą także programowanie genetyczne z gramatykami bezkontekstowymi. Koza określił pięć wstępnych kroków, jakie należy wykonać, by rozwiązać problem stosując programowanie genetyczne:. wybór końcówek (symboli terminalnych), 2. wybór funkcji operujących na końcówkach (dokładniej operatorów, funkcji i instrukcji), 3. określenie funkcji dopasowania, 4. ustalenie wartości parametrów, 5. zdefiniowanie kryterium zakończenia obliczeń. Końcówki i funkcje stanowią komponenty generowanych programów, a wybór tych komponenetów oraz funkcji dopasowania w dużym stopniu określa przestrzeń, w jakiej programowanie genetyczne 4

poszukuje rozwiązania problemu. Parametry sterujące obliczeniami to między innymi wielkość populacji, prawdopodobieństwo krzyżowania i mutacji, itd. Kryterium końca obliczeń jest zwykle znalezienie programu, który rozwiązuje problem lub określona liczba generacji. W dalszej części zostaną szczegółowo opisane wspomniane elementy programowania genetycznego. Końcówki i funkcje są podstawowymi składnikami generowanego programu. Jednak końcówki i funkcje odgrywają różne role. Ogólnie mówiąc, końcówki reprezentują przetwarzane wartości, podczas gdy funkcje operują na tych wartościach. Razem funkcje i końcówki stanowią węzły drzewa (w podstawowym drzewiastym podejściu do programowania genetycznego). Zbiór końcówek składa się ze zmiennych wejściowych, stałych i bezargumentowych funkcji (w podejściu ze strukturą liniową instrucyjną potrzebne są również zmienne robocze, co zostanie omówione w dalszej części). Stanowią one liście drzewa mając moc równą zero. Przez moc funkcji rozumie się przy tym liczbę jej argumentów. Stąd zmienne wejściowe, stałe oraz bezargumentowe funkcje mają moc równą zero. Szczególną rolę w zbiorze końcówek połnią zmienne wejściowe. Ich wartości stanowią zbiór treninujący dane, za pomocą których system może się uczyć. Dane wejściowe mogą również pełnić rolę zbioru testowego służącego do dodatkowej weryfikacji zbudowanego rozwiązania. Zbiór końcówek może również zawierać stałe. W typowej drzewiastej strukturze wyrażenia, na początku cyklu wybiera się zbiór stałych liczb rzeczywistych dla całej populacji. Stałe te nie zmieniają swej wartości podczas całego cyklu. Oczywiście w trakcie obliczeń mogą powstawać nowe stałe jako wynik działania funkcji arytmetycznych na istniejących stałych. W niektórych podejściach stałe mogą być mutowane tak jak każda inna część programu. Zbiór funkcji w programowaniu genetycznym składa się z instrukcji języka programowania, operatorów i funkcji (rozumianych tradycyjnie). Zbiór funkcji może być tak dobrany, by jak najlepiej pasować do dziedziny rozwiązywanego problemu. Ogólnie można używać każdej konstrukcji dostępnej w dowolnym języku programowania, np.: Funkcje boolowskie: and, or, not, or,... Funkcje arytmetyczne: Plus (), Minus (-), Multiply, Mul (), Divide (/),... Funkcje trygonometryczne, logarytmiczne itp.:sin,cos, tg, ctg, log, ln,... Funkcje nadające wartość zmiennym (odpowiadające instrukcji przypisania): Assign. W zastosowaniu do struktury drzewiastej, wywołanie tej funkcji ma postać: (Assign a W) i oznacza: a:= W, gdzie W jest przypisywaną wartością. Funkcje indeksujące pamięć. Instrukcje: warunkowe: IF THEN ELSE, CASE lub SWITCH, sterujące: GO TO, CALL, JUMP, iteracyjne: WHILE DO, REPEAT UNTIL, FOR DO, podprogramy dowolna funkcja, jaka może być potrzebna w konkretnym zastosowaniu, może stać się elementem zbioru funkcji wykorzystywanych przez programowanie genetyczne, np. w sterowaniu mogą okazać się niezbędne funkcje: Read_sensor, Turn_left, Turn_right, Move_ahead,..., przy czym, jeśli moc takiej funkcji będzie wynosić zero, to funkcja ta w rzeczywistości będzie należała do zbioru końcówek. Ważną właściwością wymaganą od zbioru funkcji jest to, że każda funkcja powinna powinna radzić sobie z każdą wartością, którą może otrzymać jako wejście (własność domknięcia). Najprostszym przykładem funkcji, która nie posiada tej własności jest operator dzielenia, który nie może mieć zera jako drugiego argumentu. Dzielenie przez zero prowadzi do przerwania obliczeń, stąd zamiast 5

standardowego operatora dzielenia definiuje się tak zwane bezpieczne dzielenie (oznaczane jako % ). Takie bezpieczne dzielenie dla zera w mianowniku zwraca bardzo dużą liczbę lub zero. Ogólnie, wszystkie funkcje mogące powodować podobne błędy (np. pierwiastki kwadratowe, logarytmy) muszą być zastąpione ich bezpieczną postacią dającą konkretną wartość dla każdego argumentu. Funkcje (a także i końcówki) używane w programowaniu genetycznym powinny mieć możliwość rozwiązania postawionego problemu. Jednak z jednej strony zbiór funkcji zawierający zbyt mało operatorów nie pozwoli na rozwiązanie wielu problemów, natomiast z drugiej strony użycie zbyt dużego zbioru funkcji zwiększa przestrzeń poszukiwań i może utrudnić znalezienie rozwiązania. Często więc zbiór funkcji zawiera jedynie operatory arytmetyczne i logiczne: Plus, Minus, Multiply, Divide, or, and, or. Często proponuje się (np.[6, 29]), by poszukiwanie rozwiązań rozpoczynać od kombinacji prostych funkcji. Okazuje się bowiem, że programowanie genetyczne w czasie ewolucji populacji często ignoruje bardziej skomplikowane funkcje na rzecz prostszych. Oczywiście, jeśli okaże się, że prosty zbiór funkcji i końcówek nie pozwala na wystarczająco skuteczne rozwiązanie problemu, należy dokonać jego rozszerzenia, czy modyfikacji. Same końcówki i funkcje nie są programami/wyrażeniami (poza trywialnymi przypadkami wyrażeń stałych). W związku z tym muszą zostać połączone w odpowiednie struktury zanim mogą zostać wykonane jako programy lub wartościowane jako wyrażenia. Trzy główne struktury programów używane w PG to: drzewiasta, liniowa, grafowa. Struktura drzewiasta. Rys.4 przedstawia drzewiasty fenotyp. Węzły wewnętrzne drzewa zawierają funkcje, natomiat w liściach są umieszczane końcówki. Całość reprezentuje wyrażenie, które łatwo zapisać i zinterpretować w Notacji Polskiej (prefiksowej). Stosując prefiksowy porządek dla Rys.4, otrzymujemy następujące wyrażenie: równoważne wyrażeniu: orde abc (d ore) a (bc) zapisanemu w postaci infiksowej. Ta sama struktura drzewiasta oraz jej prefiksowa interpretacja ogranicza użycie pamięci podczas wykonywania. Nie są potrzebne zmienne robocze, gdyż wszystkie wyniki pośrednie są przechowywane w pamięci lokalnej drzewa (na stosie wbudowanym w algorytm kalkulatora). Na przykład wartości b iczrys.4 są lokalne dla węzła i nie są dostępne dla żadnej innej części drzewa podczas jego wartościowania. To samo jest prawdziwe dla każdej innej wartości w drzewie. Struktura liniowa. Liniowy fenotyp to ciąg instrukcji, który jest wykonywany kolejno od początku do końca, przy czym ciąg ten, uzupełniony dodatkowymi elementami (zgodnie z najbardziej rozpowszechnionym modelem AIMGP Automatic Induction of Machine Code with Genetic Programming [34]) można przedstawić następująco: nagłówek, treść (ciąg instrukcji), 6

_ or d e a b c Rysunek 4: Przykład drzewiastego fenotypu Rejestry procesora a b c d e 22 5 376 526 320 b = b c a = a b d = d or e a = d - a Rysunek 5: Przykład liniowego fenotypu stopka, instrukcja powrotu. Liniowy program z Rys.5 (dla czytelności pominięto nagłówek, stopkę i instrukcję powrotu) jest funkcjonalnym odpowiednikiem zapisu drzewiastego z Rys.4. Jednak jest tutaj inny sposób wykorzystania funkcji i końcówek. Są one teraz elementami instrukcji zwykle prostych instrukcji przypisania (chyba, że sama funkcja jest instrukcją). W związku z tym w instrukcjach używa się tak zwanej pamięci globalnej (w odróżnieniu od podejścia drzewiastego z pamięcią lokalną). Jest wiele sposobów implementacji takiej pamięci, ale najszerzej stosowane w programowaniu genetycznym jest rozwiązanie bazujące na dwu lub trójadresowej maszynie rejestrowej [5, 25, 33]. Maszyna rejestrowa używa liniowego łańcucha instrukcji operujących na liczbach zapisywanych w rejestrach pamięci. Instrukcje czytają wartości z rejestrów i również do rejestrów wpisują wyniki obliczeń. Jest to więc podstawowy model pracy typowego komputera. Liniowy program rozpoczyna wykonywać się od pierwszej instrukcji i kontynuuje wykonywanie następnych jednej instrukcji na raz, przy czym wyjątkiem od tej zasady jest sytuacja, w której program zawiera instrukcje skoków. Na końcu wykonania programu rezultat otrzymywany jest w wybranym rejestrze, a pozostałe rejestry pełnią rolę zmiennych wejściowych i roboczych. 7

End Start Sqrt A 24 7 PUSH POP Plus 6 9 237 4 Mul 6 5 Stos Read Write Pamięć indeksowana 0 2... 255 3 22 25... 97 Rysunek 6: Przykład programu PADO (fenotyp grafowy) [6] Struktura grafowa. Spośród podstawowych struktur programowych grafy są stosunkowo nowe. Podejście, które zostanie tutaj opisane zaproponowali Teller i Veloso [42, 43] i nosi ono nazwę PADO (Parallel Architecture Discovery and Orchestration). W strukturze grafowej (Rys.6) węzły zawierają funkcje i końcówki a krawędzie wskazują kierunek przepływu sterowania w programie.tak jak i w innych systemach programowania genetycznego, w PADO wykorzystuje się pamięć przechowującą dane i wyniki. Jako pamięć lokalną do przechowywania danych roboczych stosuje się tutaj stos. Każdy węzeł wykonuje funkcję, która czyta wartość ze stosu lub zapisuje na stos. Na przykład węzeł A na Rys.6 czyta wartość wejściową z pamięci globalnej (z zewnątrz programu) i umieszcza tę wartość na stosie. Węzeł 6 umieszcza na stosie wartość 6. Węzeł Mul pobiera z kolei dwie wartości ze stosu, mnoży je i wysyła wynik z powrotem na stos. Dane mogą również być przechowywane w pamięci indeksowanej, która jest tablicą o indeksach ze zbioru {0..255}. Węzeł nazwany Write pobiera dwa argumenty ze stosu. Wartość pierwszego argumentu zapisuje do pamięci indeksowanej pod adres wskazywany przez drugi argument, zwracając przy tym poprzednią wartość przechowywaną w zapisanej komórce pamięci. Węzeł Read wykonuje dokładnie czynność odwrotną zapisuje na stosie wartość odczytaną z pamięci indeksowanej oraz adres tej wartości. Cechą charakterystyczną podejścia grafowego jest to, że każdy węzeł oprócz tego, że wykonuje określone funkcje na wartościach ze stosu, musi zdecydować który węzeł będzie analizowany jako następny. Determinuje to porządek wykonywania programu zapisanego w strukturze grafowej. Wybór pomiędzy krawędziami wychodzącymi z węzła jest dokonywany za każdym razem, gdy węzeł zostaje wykonany. Przykładowo, na Rys.6 węzeł Mul może przekazać kontrolę do jednego a węzłow: Write, Read lub 4. Każdy węzeł zawiera własną funkcję decyzyjną, która na podstawie analizy wartości pamięci, szczytu stosu, operacji zawartej w węźle oraz zdefiniowanej w węźle tak zwanej stałej decyzyjnej (branch decision constant) określa węzeł, jaki ma byc wykonany jako następny. Inicjowanie populacji w programowaniu genetycznym. Pierwszym krokiem w wykonywaniu algorytmu programowania genetycznego (zgodnego z Alg.2..) jest inicjalizacja populacji. Oznacza to utworzenie zróżnicowanych struktur programowych dla dalszej ewolucji. W związku z różną 8

_ a e not c b d Rysunek 7: Drzewo zainicjowane metodą wzrostu z parametrem MDP równym 4 _ a b c d Rysunek 8: Drzewo zainicjowane metodą pełną u z parametrem MDP równym 3 reprezentacją programów dla struktury drzewiastej, liniowej i grafowej, proces ten jest odmienny dla omawianych podejść, zawsze jednak istnieje parametr związany z największą dozwoloną wielkością generowanego programu. Dla struktury drzewiastej jest to parametr MDP (maimum depth parameter) określający maksymalną głębokość generowanego drzewa, dla struktury liniowej ML (maimum length) i określa wprost maksymalną liczbę instrukcji w programie, podobnie w podejściu grafowym maksymalna liczba węzłów wyznacza długość programu. Istnieje przy tym oczywisty związek pomiędzy tymi wartościami a maksymalą głębokością drzewa binarnego, gdzie liczba węzłów drzewa wynosi2 MDP, stąd dla celów porównawczych można wykorzystać liczbę węzłów drzewa jako parametru wyznaczającego wielkość programu. Inicjowanie struktury drzewiastej odbywa się jedną z dwu metod [29]: wzrostu, pełną. W obu metodach drzewo jest tworzone od korzenia przez dołączanie węzłów na kolejnych poziomach. Pierwsza z metod polega na losowym wyborze węzłów spośród końcówek i funkcji traktowanych jako jeden łączny zbiór (wyjątkiem jest korzeń drzewa, który jest losowany jedynie ze zbioru funkcji). Z tego względu ta metoda generuje drzewa o nieregularnym kształcie, gdyż po wylosowaniu końcówki jako zawartości danego węzła staje się on liściem i nie następuje w tym miejscu dalsza rozbudowa drzewa nawet wtedy, gdy nie osiągnięto jeszcze maksymalnej głębokości drzewa (Rys.7). W metodzie pełnej dla węzłów nie leżących na ostanim poziomie (ze względu na założoną głębokość drzewa) losuje się jedynie funkcje, a dla liści jedynie końcówki. W efekcie każda gałąź drzewa posiada maksymalną głębokość (Rys.8). W praktyce, dla osiągnięcia dużej różnorodności populacji początkowej generuje się osobniki stosując kolejno różne wartości maksymalnej głębokości drzewa: 2, 3,..., MDP. Dodatkowo połowę populacji generuje się metodą wzrostu, a drugą metodą pełną. Technika ta nosi nazwę narastającej pół na pół (ramped half and half )[28]. 9

Rejestry procesora a b c d e Nagłówek b = b c a = a b d = d or e a = d - a Stopka Return Rysunek 9: Przykład liniowego genotypu z elementami organizacyjnymi Inicjowanie liniowej struktury programowania genetycznego jest odmienne od inicjowania struktury drzewiastej, gdyż tutaj programy są reprezentowane poprzez liniowe sekwencje kodu maszynowego operującego na rejestrach procesora. Jak wspomniano wcześniej, kod osobników o strukturze liniowej to zwykle cztery elementy (Rys.9): nagłówek, treść, stopka, Return. Nagłówek i stopka to najczęściej fragmenty, które nie podlegają ewolucji. Podobnie instrukcja powrotu stanowiąca element kończący program. W związku z tym przede wszystkim należy rozpatrzyć inicjowanie treści osobnika, gdzie każdy węzeł jest odpowiednią instrukcjią. Przy załóżeniu, że liczba i rodzaj instrukcji, które są odpowiednikami funkcji w drzewach, zostały uprzednio ustalone, inicjowanie osobnika z liniowym genotypem polega na losowym wyborze początkowych instrukcji, które operują na odpowiednim podzbiorze rejestrów procesora. Proces ten przebiega następująco:. Ustal (losowo) rozmiar osobnika wartość pomiędzy 2 a maksymalną długością (parametr ML). 2. Skopiuj nagłówek na początek osobnika, 3. Dodawaj instrukcjie aż ich liczba będzie równa rozmiarowi wybranemu w kroku. Instrukcje twórz poprzez losowy wybór typu instrukcji i uzupełnienie instrukcji odwołaniami do losowo wybranych rejestrów i/lub losowe wybranie stałej z ustalonego zakresu. 4. Skopiuj predefiniowaną stopkę na koniec osobnika. 5. Dołącz predefiniowaną instrukcję powrotu na koniec osobnika. W podany sposób można zainicjować całą populacje. Metoda opisana tutaj używana jest zamiast metod pełnej i wzrostu w drzewach. Można również zastosować odpowiedniki powyższych metod. W podejściu grafowym programy populacji początkowej są tworzone jako grafy o losowej budowie i zawartości, gdzie liczba węzłów, ich zawartość (funkcje lub końcówki) oraz połączenia są ustalane losowo. 20

Po zainicjowaniu populacji, zgodnie z przedstawionym w p.2.. algorytmem (Alg.2..), następuje ocena populacji początkowej. Dokonywana jest ona za pomocą funkcji celu (przystosowania), która jest w tym przypadku funkcją dopasowania wygenerowanego programu (osobnika) do danych zawartych w zbiorze trenującym. Ogólnie, funkcja dopasowania zapewnia sprzężenie zwrotne dla algorytmu uczenia się, jakim jest programowanie genetyczne, dając osobnikom lepiej dopasowanym do wymagań zawartych w zbiorze trenującym większe szanse na reprodukcję, poprawiając tym samym jakość populacji, która będzie podlegała dalszej ewolucji. Zakładając, że P jest ocenianym programem, a wartością wyprowadzaną przez P dla przykładu i w zbiorze trenującym jestp i, zaś wartością wyjściową zawartą w zbiorze trenującym dla przykładu i jesto i, podstawowa funkcja dopasowania (funkcja błędu) programup wynosi: n f P = p i o i (9) i= gdzienjest liczbą przykładów w zbiorze trenującym. Inną funkcją dopasowania jest funkcja błędu kwadratowego licząca kwadraty różnic wartości danych w zbiorze trenującym i obliczonych przez programp: n f P= (p i o i ) 2 i= Wartości funkcji dopasowania mogą być następnie skalowane (strojone): a P = f P aby lepsze programy (osobniki) miały większą wartość funkcji dopasowania. Można również wartości funkcji dopasowania znormalizować i wtedy otrzymuje się wartości z przedziału 0;, sumujące się do jedynki i większe dla lepszych programów. Kolejnym etapem obliczeń algorytmu programowania genetycznego jest pętla operacji wykonywana do momentu spełnienia warunku końca (stopu). Jako warunek ten przyjmuje się otrzymanie rozwiązania dokładnego (osiągnięcie zerowej wartości funkcji błędu lub wartości dla funkcji skalowanej bądź znormalizowanej), albo przybliżonego z wystarczającą dokładnością. Gdy takie rozwiązanie nie zostanie znalezione, obliczenia kończą się po osiągnięciu założonej liczby iteracji (pokoleń). Operatory genetyczne. Populacja inicjalna posiada zazwyczaj bardzo niskie dopasowanie. W związku z tym następuje ewolucja tej populacji (powstają kolejne pokolenia) poprzez przekształcanie populacji inicjalnej za pomocą operatorów genetycznych. Istnieje wiele operatorów genetycznych, ale trzema najważniejszymi są wspomniane w p.2.. i zawarte w Alg.2..: reprodukcja (selekcja), krzyżowanie, mutacja. W algorytmach ewolucyjnych funkcjonuje wiele różnych technik podejmowania decyzji określającej które osobniki mają być powielone, jak wiele potomstwa mają mieć, które osobniki należy wyeliminować z populacji. Główną zasadą jest nagradzanie lepszych rozwiązań liczniejszym potomstwem i dłuższym życiem. Należy przy tym bardzo rozsądnie manipulować nagrodami, gdyż zbyt liczne potomstwo nawet bardzo wysoko ocenionego osobnika może to prowadzić do małego zróżnicowania populacji. Z drugiej strony, jeżeli wszystkie osobniki będą miały zbliżoną liczbę potomstwa, doprowadzi to do stagnacji uniemożliwi ewoluowanie populacji w pożądanym kierunku. Programowanie genetyczne najczęściej wykorzystuje metody selekcji: 2

selekcję proporcjonalną, zwaną ruletkową (fitness proportional selection), selekcję obcinającą, zwaną selekcją (µ,λ)(truncation selection), selekcję porządkową (ranking selection), w wersji liniowej i wykładniczej, selekcję turniejową (tournament selection), przy czym w każdym przypadku po wyborze rodzica następuje jego reprodukcja powstaje potomek będący wierną kopią rodzica. Potomek ten zostaje dołączony do nowo tworzonej populacji (następnej generacji osobników). Podstawową metodą selekcji jest selekcja proporcjonalna [23]. Jest ona procesem, w którym osobniki zostają powielone w stosunku zależnym od wartości ich funkcji dopasowania. W tym celu każdemu osobnikowi przypisuje się prawdopodobieństwo: p i = f i N f k k= z jakim zostanie wylosowany do reprodukcji (N jest rozmiarem populacji). Następnie, uwzględniając wyliczone prawdopodobieństwa,n razy losuje się osobnika (np. metodą ruletki) jako rodzica. dzięki temu lepiej przystosowane osobniki mają większ a szansą wprowadzenia do nowej populacji swoich potomków. Druga najczęściej stosowana metoda selekcji wywodzi się ze strategii ewolucynjych [4], gdzie znana jest jako selekcja (µ, λ). Tutaj jedynie µ najlepszych osobników może być rodzicami i mogą oni mieć w sumieλpotomków. Proces ten polega naλ krotnym losowaniu osobnika (z puliµnajlepszych), który zostanie rodzicem. Ta sama metoda używana była przez genetyków i hodowców pod nazwą selekcji obcinającej [8,, 32, 39]. Selekcja porządkowa [22, 46] bazuje zbiorze osobników posortowanym według wartości funkcji dopasowania. Każdemu osobnikowi zostaje przyporządkowane prawdopodobieństwo selekcji jako funkcja jego rangi (indeksu i) w populacji. Dla liniowej werji tej selekcji prawdopodobieństwo jest liniową funkcją rangi: p i = N [p (p p ) i N ] gdzien jest rozmiarem populacji, p jest prawdopodobieństwem, że wybrany zostanie najgorszy N osobnik, a p jest prawdopodobieństwem, że wybrany zostanie najlepszy osobnik, a dla zapewnienia N stałości rozmiar u populacji powinno byćp p =2iobie te wartości muszą należeć do przedziału,2. Dla rankingu wykładniczego prawdopodobieństwo jest obliczane przy użyciu stałej selekcjic, p i = c c N cn i gdzie0<c<. Selekcja turniejowa nie jest oparta na współzawodnictwie w całej populacji, ale na jej podzbiorach. Liczba osobników, zwana rozmiarem turnieju, jest wybierana losowo z populacji, a następnie dokonuje się wyboru osobnika najbardziej dopasowanego. Procedura ta jest powtarzana N razy, gdzie N jest wielkością populacji, otrzymując w ten sposób nową populację. Selekcja turniejowa jest popularna ze względu na możliwość zrównoleglenia obliczeń, co skraca ich czas. Kolejnymi krokami algorytmu programowania genetycznego jest krzyżowanie i mutacja osobników nowej populacji. Operator krzyżowania łączy materiał genetyczny dwóch rodziców poprzez zamianę części jednego rodzica z częścią drugiego, jednak proces ten przebiega odmiennie dla poszczególnych podejść: drzewiastego, liniowego i grafowego. Krzyżowanie drzew jest przedstawione graficznie na Rys.0. Krzyżowanie to przebiega w następujących krokach: 22

Rodzic Rodzic 2 / / c d e 2 3 4 a b Potomek Potomek 2 / / 2 d e c 3 4 a b Rysunek 0: Przykład krzyżowania dla struktury drzewiastej [6]. Wybierz dwóch osobników jako rodziców. 2. W każdym rodzicu wybierz losowo podgałąź (na Rys.0 wybrane podgałęzie zaznaczone są podwójnymi i pogrubionymi liniami), przy czym podgałęzie składające się z końcówek powinny być wybierane z mniejszym prawdopodobieństwem niż inne podgałęzie. 3. Utwórz potomków przez wymianę wybranych podgałęzi pomiędzy dwoma rodzicami. W krzyżowanie genotypów liniowych zamiast zamieniać podgałęzie między rodzicami, wymienia się liniowe segmenty kodu. Krzyżowanie liniowe przedstawione jest graficznie na Rys., a przebiega ono następująco:. Wybierz dwa osobniki na rodziców. 2. Wybierz losową sekwencję instrukcji w każdym rodzicu (na Rys. wybrane instrukcje zaznaczone są szarym kolorem). 3. Wymień wybrane sekwencjie pomiędzy rodzicami tworząc dwa nowe osobniki (potomków). Krzyżowanie grafów jest nieco bardziej skomplikowane. Teller [44] w swiom systemie zastosował następującą procedurę:. Wybierz dwa osobniki (grafy) na rodziców i nazwij je P oraz T. 2. Podziel każdy graf na dwa zbiory węzłów, a następnie: 23

Rodzic Rodzic 2 Potomek Potomek 2 Nagłówek A B C D E Stopka Return Nagłówek 2 3 4 5 6 7 Stopka Return Nagłówek A 3 4 5 D E Stopka Return Nagłówek 2 B C 6 7 Stopka Return Rysunek : Przykład krzyżowania dla struktury linowej [6] (a) nazwij powstałe zbiory węzłów P, P2 (powstałe z grafu P) oraz T, T2 (powstałe z grafu T); (b) oznacz jako wewnętrzną każdą krawędź łączącą węzły w jednym zbiorze, w przeciwnym razie oznacz ją jako zewnętrzną; (c) oznacz każdy węzeł w każdym zbiorze jako wyjściowy, jeśli jest on węzłem początkowym dla krawędzi zewnętrznej, a jako wejściowy, jeśli jest węzłem końcowym dla krawędzi zewnętrznej. 3. Zamień wybrane zbiory pomiędzy rodzicami nowymi osobnikami będą: P T2 oraz T P2. 4. Rekombinuj krawędzie tak, aby wszystkie zewnętrzne krawędzie w połączonych teraz zbiorach wskazywały na losowo wybrane węzły wejściowe z pozostałych zbiorów. Za pomocą tej metody wszystkie krawędzie mają zapewnione połączenie w nowym osobniku i tworzone są poprawne grafy. Mutacje. Mutacja operuje tylko na jednym osobniku. W algorytmach genetycznych po krzyżowaniu każdy potomek stworzony poprzez krzyżowanie, z niewielkim prawdopodobieństwem ulega mutacji. Zmutowany osobnik umieszczany jest następnie z powrotem w populacji. W strukturze drzewiastej u osobnika wybranego do mutacji wybiera się losowo punkt (węzeł w jego drzewie) i zastępuje istniejące poddrzewo, którego korzeniem jest wybrany węzeł, innym, losowo wygenerowanym poddrzewem. Nowe poddrzewo jest tworzone w ten sam sposób i podlega tym samym ograniczeniom (głębokość, rozmiar) jak programy z populacji inicjalnej. Jest to tak zwana mutacja poddrzewa [29]. Oprócz tego stosuje się również inne typy operatora mutacji, na przykład (Rys.2): mutacja węzła losowa zmiana zawartości węzła; aby drzewo pozostało poprawne, po zmianie węzeł musi zawierać funkcję o takiej samej liczbie argumentów, jak przed zmianą (lub pozostac końcówką, jeżeli jest to liść) [30], mutacja przez zastąpienie rodzica poddrzewem potomek jest kopią losowo wybranego poddrzewa rodzica [26], mutacja przez zastąpienie poddrzewa końcówką potomek powstaje przez zastąpienie u rodzica losowo wybranego poddrzewa losowo wybraną końcówką [2]. Dla liniowych genotypów u osobnika wybranego do mutacji najpierw wybiera się instrukcję, która będzie podlegać mutacji. Następnie dokonuje w tej instrukcji jednej lub więcej zmian. Typ zmian wybierany jest losowo z następujących możliwości: 24

/ e d c b a / e d c b a / e d c b a not / d c b a / c b a / e d c b a / e d c b a a e d Rysunek 2: Przykłady różnych metod mutacji dla struktury drzewiastej 25

Nagłówek b = c a = a b a = d - Stopka Return Nagłówek b = c a = a b a = d - Stopka Return Rysunek 3: Przykłady różnych metod mutacji dla struktury liniowej Nr Wejście () Wyjście (y) 0,2 0,2 2 0,4 0,28 3 0,6 0,48 4 0,8 0,72 5,0,00 6,2,32 7,4,68 8,6 2,08 9,8 2,52 0 2,0 3,00 Tablica 4: Wartości poszukiwanej funkcji (zbiór trenujący) dowolne z odwołań do rejestrów może zostać zamienione na odwołanie do losowo wybranego rejestru ze zbiorów rejestrów wykorzystywanych w programie, funkcja (operator) może zostać zamieniona na dowolną funkcję ze zbioru dostępnego dla programu, stała może zostać zamieniona na losowo wybraną stałą zawierającą się w zakresie założonym dla stałych. Po mutacji osobników następuje ocena nowej populacji, co jest ostatnim krokiem głównej pętli programowania genetycznego. W przypadku znalezienia osobnika reprezentującego rozwiązanie dokładne (lub wystarczająco dobrze przybliżone) obliczenia są kończone w przeciwnym razie kontynuuje się ewolucję populacji. Dodatkowym kryterium zakończenia obliczeń jest osiągnięcie założonej liczby iteracji (generacji osobników). 2..3 Przykład Dla zilustrowania wprowadzonych pojęć zostanie przedstawiony przykład rozwiązania zadania regresji funkcji opisanej tabelą Tab.4 (funkcji 2 ). Podany przykład wykorzystuje drzewiastą strukturę 2 programu, co jest zgodne z pierwotnym podejściem zastosowanym w programowaniu genetycznym (w rzeczywistości Koza w swoich pierwszych eksperymentach stosował S-wyrażenie języka LISP, jednak implementacje w innych językach stosują struktury drzewiaste, które są w istocie zgodne z oryginalnym podejściem Kozy). Zgodnie z zasadami programowania genetycznego obliczenia należy rozpocząć od wykonania wspomnianych wcześniej wstępnych kroków:. Wybór zbioru końcówek: zmienna, stałe0i. 2. Wybór zbioru funkcji: operatory arytmetyczne,,,/( bezpieczne dzielenie). 26