Java. Programowanie, biblioteki open-source i pomysły na nowe projekty

40
Wydawnictwo Helion ul. Koœciuszki 1c 44-100 Gliwice tel. 032 230 98 63 e-mail: [email protected] PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ IDZ DO IDZ DO ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG KATALOG KSI¥¯EK KATALOG KSI¥¯EK TWÓJ KOSZYK TWÓJ KOSZYK CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOœCIACH ZAMÓW INFORMACJE O NOWOœCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE SPIS TREœCI SPIS TREœCI DODAJ DO KOSZYKA DODAJ DO KOSZYKA KATALOG ONLINE KATALOG ONLINE Java. Programowanie, biblioteki open-source i pomys³y na nowe projekty Autor: Brian Eubanks T³umaczenie: Grzegorz Borkowski ISBN: 83-246-0624-6 Tytu³ orygina³u: Wicked Cool Java: Code Bits, Open-Source Libraries, and Project Ideas Format: B5, stron: 248 Odkryj nieznane mo¿liwoœci Javy • Sieci semantyczne i neuronowe • Przetwarzanie grafiki i multimediów • Obliczenia naukowe Java, mimo stosunkowo krótkiej obecnoœci na rynku, sta³a siê jednym z najpopularniejszych jêzyków programowania. Codziennie korzystaj¹ z niej setki tysiêcy programistów z ca³ego œwiata. Najwiêksze korporacje œwiata za jej pomoc¹ buduj¹ systemy informatyczne przetwarzaj¹ce potê¿ne porcje danych. Aplikacje bazodanowe, serwlety i aplety to najbardziej znane zastosowania Javy, jednak nie jedyne. W sieci dostêpna jest ogromna iloœæ bibliotek tworzonych przez pasjonatów, którzy wykorzystuj¹ Javê do odmiennych celów, takich jak przetwarzanie grafiki, modelowanie sieci neuronowych, przeprowadzanie z³o¿onych obliczeñ i wielu innych zadañ. Dziêki ksi¹¿ce „Java. Programowanie, biblioteki open-source i pomys³y na nowe projekty” poznasz mniej znane zastosowania Javy. Dowiesz siê, jak za pomoc¹ bibliotek dostêpnych na licencji open-source tworzyæ ciekawe projekty i pisaæ nietypowe aplikacje. Nauczysz siê przetwarzaæ pliki XML i HTML, obrabiaæ i generowaæ grafikê a tak¿e wyœwietlaæ pliki multimedialne. Przeczytasz o sieciach semantycznych i neuronowych, odczytywaniu kana³ów RSS i sterowaniu urz¹dzeniami pod³¹czonymi do komputera. • Nieznane funkcje standardowego API Javy • Przetwarzanie ³añcuchów tekstowych • Analiza plików XML i HTML • Stosowanie RDF w projektach • Czytanie kana³ów RSS • Obliczenia o dowolnej precyzji • Realizacja algorytmów genetycznych • Symulowanie sieci neuronowych • Generowanie plików SVG • Wspó³praca z interfejsem MIDI Jeœli lubisz eksperymentowaæ z jêzykami programowania, ta ksi¹¿ka bêdzie dla Ciebie doskona³ym Ÿród³em inspiracji

description

Odkryj nieznane możliwości Javy * Sieci semantyczne i neuronowe * Przetwarzanie grafiki i multimediów * Obliczenia naukowe Java, mimo stosunkowo krótkiej obecności na rynku, stała się jednym z najpopularniejszych języków programowania. Codziennie korzystają z niej setki tysięcy programistów z całego świata. Największe korporacje świata za jej pomocą budują systemy informatyczne przetwarzające potężne porcje danych. Aplikacje bazodanowe, serwlety i aplety to najbardziej znane zastosowania Javy, jednak nie jedyne. W sieci dostępna jest ogromna ilość bibliotek tworzonych przez pasjonatów, którzy wykorzystują Javę do odmiennych celów, takich jak przetwarzanie grafiki, modelowanie sieci neuronowych, przeprowadzanie złożonych obliczeń i wielu innych zadań. Dzięki książce "Java. Programowanie, biblioteki open-source i pomysły na nowe projekty" poznasz mniej znane zastosowania Javy. Dowiesz się, jak za pomocą bibliotek dostępnych na licencji open-source tworzyć ciekawe projekty i pisać nietypowe aplikacje. Nauczysz się przetwarzać pliki XML i HTML, obrabiać i generować grafikę a także wyświetlać pliki multimedialne. Przeczytasz o sieciach semantycznych i neuronowych, odczytywaniu kanałów RSS i sterowaniu urządzeniami podłączonymi do komputera. * Nieznane funkcje standardowego API Javy * Przetwarzanie łańcuchów tekstowych * Analiza plików XML i HTML * Stosowanie RDF w projektach * Czytanie kanałów RSS * Obliczenia o dowolnej precyzji * Realizacja algorytmów genetycznych * Symulowanie sieci neuronowych * Generowanie plików SVG * Współpraca z interfejsem MIDI Jeśli lubisz eksperymentować z językami programowania, ta książka będzie dla Ciebie doskonałym źródłem inspiracji.

Transcript of Java. Programowanie, biblioteki open-source i pomysły na nowe projekty

  • 1. IDZ DO PRZYKADOWY ROZDZIA Java. Programowanie, SPIS TRECI biblioteki open-source KATALOG KSIEK i pomysy na nowe projekty Autor: Brian Eubanks KATALOG ONLINE Tumaczenie: Grzegorz Borkowski ISBN: 83-246-0624-6 ZAMW DRUKOWANY KATALOG Tytu oryginau: Wicked Cool Java: Code Bits, Open-Source Libraries, and Project Ideas Format: B5, stron: 248 TWJ KOSZYK Odkryj nieznane moliwoci Javy DODAJ DO KOSZYKA Sieci semantyczne i neuronowe Przetwarzanie grafiki i multimediw Obliczenia naukowe CENNIK I INFORMACJE Java, mimo stosunkowo krtkiej obecnoci na rynku, staa si jednym z najpopularniejszych jzykw programowania. Codziennie korzystaj z niej setki tysicy programistw z caego ZAMW INFORMACJE wiata. Najwiksze korporacje wiata za jej pomoc buduj systemy informatyczne O NOWOCIACH przetwarzajce potne porcje danych. Aplikacje bazodanowe, serwlety i aplety to najbardziej znane zastosowania Javy, jednak nie jedyne. W sieci dostpna jest ogromna ZAMW CENNIK ilo bibliotek tworzonych przez pasjonatw, ktrzy wykorzystuj Jav do odmiennych celw, takich jak przetwarzanie grafiki, modelowanie sieci neuronowych, przeprowadzanie zoonych oblicze i wielu innych zada. CZYTELNIA Dziki ksice Java. Programowanie, biblioteki open-source i pomysy na nowe projekty poznasz mniej znane zastosowania Javy. Dowiesz si, jak za pomoc bibliotek FRAGMENTY KSIEK ONLINE dostpnych na licencji open-source tworzy ciekawe projekty i pisa nietypowe aplikacje. Nauczysz si przetwarza pliki XML i HTML, obrabia i generowa grafik a take wywietla pliki multimedialne. Przeczytasz o sieciach semantycznych i neuronowych, odczytywaniu kanaw RSS i sterowaniu urzdzeniami podczonymi do komputera. Nieznane funkcje standardowego API Javy Przetwarzanie acuchw tekstowych Analiza plikw XML i HTML Stosowanie RDF w projektach Czytanie kanaw RSS Obliczenia o dowolnej precyzji Realizacja algorytmw genetycznych Wydawnictwo Helion Symulowanie sieci neuronowych ul. Kociuszki 1c Generowanie plikw SVG 44-100 Gliwice Wsppraca z interfejsem MIDI tel. 032 230 98 63 e-mail: [email protected] Jeli lubisz eksperymentowa z jzykami programowania, ta ksika bdzie dla Ciebie doskonaym rdem inspiracji
  • 2. PODZIKOWANIA ...................................................................................... 9 WSTP ....................................................................................................... 11 1 STANDARDOWE API JAVY ....................................................................... 15 Uycie nowej wersji ptli for .................................................................................................16 Wykorzystanie konstrukcji enum ...........................................................................................18 Mapy bez rzutowania w d ...................................................................................................21 Pisanie metod z parametrami generycznymi .........................................................................22 Metody ze zmienn liczb parametrw .................................................................................25 Asercje w Javie .......................................................................................................................27 Uycie System.nanoTime .......................................................................................................29 Upienie wtku na czas krtszy od milisekundy ....................................................................30 Klasy anonimowe ...................................................................................................................31 Porwnania == != .equals ...................................................................................................33 Podsumowanie .......................................................................................................................35 2 NARZDZIA DO PRACY Z ACUCHAMI TEKSTOWYMI ....................... 37 Uycie wyrae regularnych do wyszukiwania tekstw ........................................................38 Uycie metody String.split .....................................................................................................40 Wyszukiwanie fragmentw w acuchach tekstowych ..........................................................41 Uycie grup w wyraeniach regularnych ................................................................................42 Wykonywanie zamiany tekstw za pomoc wyrae regularnych ........................................44 Przetwarzanie z uyciem klasy Scanner .................................................................................47 Analiza skomplikowanej skadni przy uyciu klasy Scanner ....................................................49 Generowanie przypadkowego tekstu ....................................................................................51 Drukowanie zawartoci tablic w Javie 1.5 ..............................................................................52 Kodowanie i dekodowanie danych binarnych ........................................................................54
  • 3. Formatowanie tekstw za pomoc MessageFormat ............................................................. 57 Powrt funkcji printf formatowanie tekstw z klas Formatter ...................................... 58 Podsumowanie ...................................................................................................................... 59 3 PRZETWARZANIE XML I HTML ................................................................61 Szybkie wprowadzenie do XML ............................................................................................ 62 Uycie WebRowSet do utworzenia dokumentu XML .......................................................... 63 Zapamitywanie zalenoci midzy elementami w SAX ....................................................... 64 Bezporednie wywoywanie zdarze obiektu ContentHandler ............................................ 69 Filtrowanie zdarze interfejsu ContentHandler .................................................................... 71 Czytanie dokumentw XML z wykorzystaniem DOM4J ...................................................... 74 Uycie XPath do atwego pobierania danych ........................................................................ 76 Niewidoczne tagi, czyli filtrowanie dokumentu przed zaadowaniem do DOM4J ................ 80 Generowanie kodu analizatorw za pomoc JavaCC ........................................................... 83 Konwersja innych gramatyk na XML ..................................................................................... 87 Wykorzystanie techniki screen scraping do stron HTML ...................................................... 93 Wyszukiwanie z Lucene ........................................................................................................ 95 Podsumowanie ...................................................................................................................... 97 4 SIE SEMANTYCZNA ................................................................................99 Krtkie wprowadzenie do N3 i Jena ................................................................................... 101 Tworzenie sownikw RDF na wasne potrzeby ................................................................. 103 Uycie hierarchii RDF w Jena .............................................................................................. 106 Doczanie Dublin Core do dokumentw HTML ............................................................... 108 Zapytania w Jena RDQL ...................................................................................................... 109 Lojban, RDF i projekt Jorne ................................................................................................. 111 RSS i Informa ....................................................................................................................... 113 Czytanie rde RSS ............................................................................................................ 115 Odpytywanie i aktualizacja kanaw RSS ............................................................................. 116 Filtrowanie danych RSS ........................................................................................................ 117 Podsumowanie .................................................................................................................... 119 5 ZASTOSOWANIA W NAUKACH CISYCH I MATEMATYCZNO-PRZYRODNICZYCH ................................................121 Tworzenie i zastosowanie funktorw ................................................................................. 122 Uycie funktorw zoonych ............................................................................................... 125 Bity duego kalibru BitVector z biblioteki Colt .............................................................. 126 Tworzenie tablic prawdy za pomoc BitMatrix ................................................................... 128 Dwa terafurlongi w dwa tygodnie wielkoci fizyczne z JScience .................................... 130 Krnbrne uamki arytmetyka dowolnej precyzji ............................................................. 133 Funkcje algebraiczne w JScience .......................................................................................... 135 czenie tablic prawdy za pomoc portw ......................................................................... 136 czenie za pomoc JGraphT .............................................................................................. 139 6 Spis treci
  • 4. czenie oglnych jednostek obliczeniowych ......................................................................141 Budowanie sieci neuronowych z Joone ................................................................................144 Uycie JGAP do algorytmw genetycznych .........................................................................146 Tworzenie inteligentnych agentw przy uyciu Jade ...........................................................149 Jzyk angielski z JWorkNet ..................................................................................................153 Podsumowanie .....................................................................................................................155 6 PRZETWARZANIE GRAFIKI I WIZUALIZACJA DANYCH ....................... 157 Definiowanie graficznego interfejsu aplikacji Javy w XML ...................................................158 Wizualizacja danych w SVG ..................................................................................................160 Wywietlanie obrazw SVG .................................................................................................163 Konwersja JGraphT do JGraphView .....................................................................................164 Uycie map atrybutw w JGraph .........................................................................................166 Tworzenie wykresw z JFreeChart .....................................................................................167 Tworzenie raportw w Javie ...............................................................................................169 Prosta dwuwymiarowa wizualizacja danych ........................................................................171 Uycie transformacji afinicznych w Java 2D .........................................................................174 Budowanie aplikacji graficznych z funkcj zoom na pomoc Piccolo ...............................176 Podsumowanie .....................................................................................................................177 7 MULTIMEDIA I SYNCHRONIZACJA WTKW ....................................... 179 Tworzenie muzyki z JFugue .................................................................................................180 Uycie JFugue razem z Java Sound MIDI ..............................................................................181 Wysyanie zdarze do urzdze wyjciowych MIDI ............................................................183 Tworzenie dwikw w JMusic ...........................................................................................184 Uycie szumu i skomplikowanej syntezy w JMusic ..............................................................186 Niskopoziomowy dostp do Java Sound ..............................................................................189 Czytanie dwiku z linii wejciowej .....................................................................................191 Uycie Java Speech do tworzenia mwicych programw ..................................................192 Odmiecacz i Javolution .......................................................................................................193 Synchronizacja wtkw za pomoc CyclicBarrier ................................................................196 Podsumowanie .....................................................................................................................197 8 ROZRYWKA, INTEGRACJA I POMYSY NA NOWE PROJEKTY .............. 199 Uycie Javy do sterowania robotem LEGO .........................................................................200 Kontrolowanie myszy z uyciem klasy AWT Robot .............................................................201 Wybr dat z pomoc JCalendar ...........................................................................................202 Uycie klasy HttpClient do obsugi metody POST ..............................................................203 Symulacja systemu Cell Matrix w Javie .................................................................................204 Cell Matrix i algorytmy genetyczne ......................................................................................206 Uruchamianie aplikacji z Ant ................................................................................................207 Skrypty BeanShell .................................................................................................................208 Tworzenie testw JUnit .......................................................................................................210 Spis treci 7
  • 5. Uycie JXTA w aplikacjach Peer-to-Peer ............................................................................ 211 Pakiet narzdziowy Globus oraz sieci rozproszone ............................................................ 212 Uycie Jabbera w aplikacjach ............................................................................................... 212 Pisanie w jzyku asemblera JVM .......................................................................................... 213 Poczenie programowania genetycznego z BCEL ............................................................. 214 Kompilowanie innych jzykw do kodu Javy ....................................................................... 215 Wizualizacja gramatyki jzyka Lojban .................................................................................. 215 Edytor instrumentw muzycznych ...................................................................................... 216 WordNet Explorer .............................................................................................................. 216 Automatyczny generator RSS .............................................................................................. 217 Sieci neuronowe w robotach ............................................................................................... 217 Narzdzie zarzdzania metadanymi (adnotacjami) Javy 5 ................................................... 218 CVS i kontrola kodu rdowego ........................................................................................ 218 Wykorzystaj SourceForge do swoich projektw ................................................................ 219 Posumowanie ...................................................................................................................... 219 SOWNICZEK ...........................................................................................221 SKOROWIDZ ............................................................................................235 8 Spis treci
  • 6. . ZADZIWIAJCY JEST FAKT, E W WIELU KRGACH NAUKOWYCH FORTRAN WCI SPRAWUJE NIEPODZIELN WADZ (WIEM, WIEM, TE MNIE TO PRZERAA). PRZYCZYN TEGO STANU RZECZY NIEKONIECZNIE jest to, e Fortran jest wspaniaym jzykiem programowania, lecz raczej fakt, e jego standardowe biblioteki dostarczaj ogromny zbir operacji matema- tycznych, z ktrych korzysta wielka rzesza istniejcych programw. Java istnieje od ponad dekady, dziaa na wikszej liczbie dostpnych platform, ma standardowe API o bogatszych moliwociach i pozwala robi rzeczy niemoliwe w Fortra- nie. Dlaczego wic Java nie jest tak popularna w aplikacjach dla nauk ci- sych? Wynika to by moe z faktu, e Java nie posiada dobrych bibliotek
  • 7. matematycznych. Klasa java.lang.Math ma bardzo ograniczone moliwoci, ale poniewa jest to klasa ze standardowej dystrybucji Javy, niektrzy programici aplikacji naukowych nie trudz si zbytnio poszukiwaniem dodatkowych bi- bliotek. Moe po prostu uwaaj, e masz to, co widzisz (ang. what you see is what you get). Ten obraz jednak si zmienia, gdy powoli na scen wkraczaj nowe biblioteki istnieje obecnie wiele projektw typu open-source, w ktrych powstaj naprawd wspaniae rozwizania. W niniejszym rozdziale przyjrzymy si niektrym matematycznym i naukowym bibliotekom dostpnym dla Javy. Wrd zagadnie, w ktre si zagbimy, znajd si funktory, tablice prawdy, teoria grafw, jednostki fizyczne, sieci neuronowe, algorytmy genetyczne i sztuczna inteligencja. JGA Wedug sownika internetowego Merriam-Webster (dostpnego pod adresem www.m-w.com) funktor jest to co, co wykonuje funkcj lub operacj. Z punktu JAVA 5+ widzenia programisty funktor to funkcja, ktra moe by przekazana jako para- metr i uyta jak kada inna zmienna. Wiele jzykw, jak na przykad C, posiada wskaniki na funkcje. Wskaniki te przechowuj adres pamici, pod ktrym ulo- kowana jest dana funkcja. W takich jzykach moesz przekaza funkcj do innej funkcji i zastosowa j dla rnych argumentw na przykad dla kadego elementu kolekcji. Jzyki takie jak Scheme, Lisp czy Haskell uywaj czysto funkcyjnego stylu programowania, bardzo wydajnego w pewnych zastosowaniach (w szczeglnoci w dziedzinie sztucznej inteligencji). Java nie posiada funkcji w stylu Lispa czy C, ale moemy zaimplementowa taki sposb dziaania za po- moc interfejsw i klas bazowych. Generic Algorithms for Java to jedna z implementacji typu open-source obiek- tw funkcyjnych. Mamy w niej do czynienia z klasami odpowiadajcymi funktorom przyjmujcym zero, jeden lub dwa argumenty: Generator Funktor bezargumentowy UnaryFunctor Funktor jednoargumentowy BinaryFunctor Funktor dwuargumentowy Funktory te s zaprojektowane dla cisej wsppracy z Jav 5, gdy korzy- staj z typw generycznych (ang. generics) (ktre zostay omwione w rozdziale 1.). Klasa Generator jest w rzeczywistoci zdefiniowana jako Generator. Posiada ona bezargumentow metod gen, ktra zwraca obiekt typu R okrelony w kon- struktorze klasy. Aby utworzy funktor bezargumentowy, moemy uy nastpu- jcego kodu: 122 Rozdzia 5
  • 8. import net.sf.jga.fn.Generator; public class CubeGenerator extends Generator { double current = 0; public Double gen() { current = current + 1; return current * current * current; } } Wida tu wyranie sens nazwy Generator: napisana przez nas przykadowa klasa generuje szeciany kolejnych liczb naturalnych. Oprcz moliwoci two- rzenia wasnych generatorw biblioteka JGA posiada zbir gotowych generato- rw dla tworzenia wartoci rnego typu: losowych, staych lub wyliczanych. Wartoci zwracane przez generatory nie musz by liczbami. Klas reprezentujc funktor jednoargumentowy jest klasa UnaryFunctor. Definiuje ona metod fn, ktra przyjmuje parametr typu T i zwraca warto typu R. Moemy na przykad utworzy predykat, piszc funktor zwracajcy war- to typu Boolean. Stwrzmy klas typu UnaryFunctor, ktra zwraca warto true dla liczb parzystych: public class EvenNumber extends UnaryFunctor { public Boolean fn(Number x) { return (x.longValue() % 2) == 0; } } Na razie wyglda to tak, jakbymy dokadali sobie pracy bez wyranych korzy- ci. Jednake zalet takiego rozwizania jest moliwo tworzenia nowych metod, ktre jako parametr przyjm dowolne funktory. Kolejny listing pokazuje, jak to wyglda w praktyce: public void removeMatches(List aList, UnaryFunctor functor) { for (Number num : aList) { if (functor.fn(num)) aList.remove(num); } } Metoda ta usuwa wszystkie elementy z listy, dla ktrych funktor typu Number ->Boolean zwraca true (a dokadnie Boolean.TRUE; w Javie 5 typy te s rw- nowane). Przeledmy teraz dwa sposoby napisania kodu usuwajcego liczby parzyste z listy: Zastosowania w naukach cisych i matematyczno-przyrodniczych 123
  • 9. List numbers = ... // wypeniamy list jakimi liczbami // pierwszy sposb for (Number aNumber : numbers) { if (aNumber.longValue() % 2 == 0) numbers.remove(aNumber); } // drugi sposb removeMatches(numbers, new EvenNumber()); Metoda taka jak removeMatches moe by bardzo uyteczn czci biblio- teki. Pozwala nam ona zastosowa kolejno kilka funktorw typu UnaryFunctor na danej licie: removeMatches(numbers, lessThan30000); removeMatches(numbers, greaterThan10000000); Moemy osign ten sam efekt, uywajc klasy Iterables, ktra dobrze na- daje si do wykorzystania w ptlach for each wprowadzonych w Javie 5. Na stronach JGA znajdziesz bardziej szczegowe przykady filtrowanych iteracji. Oto krtki przykad ptli, ktra jest wykonywana wycznie na parzystych ele- mentach danej listy: UnaryFunctor even = new EvenNumber(); List numbers = ...; // dowolne wypenienie listy for (Number aNumber : Iterables.filter(numbers, even)) { System.out.println(aNumber); } Klasa Algorithms obejmuje implementacje niektrych popularnych algorytmw, ktre wykorzystuj funktory. Nastpny przykad uywa dwch z tych algorytmw: forEach stosuje funktor unarny dla kadego elementu z listy, a removeAll usuwa wszystkie elementy pasujce do predykatu: import net.sf.jga.util.Algorithms; List aList = ...; //wypeniamy list // usuwamy wszystkie wartoci rwne null UnaryFunctor isNull = new UnaryFunctor() { public Boolean fn(Object o) {return o == null;} }; Algorithms.removeAll(aList, isNull); // przycinamy acuchy tekstowe UnaryFunctor trimmer = new UnaryFunctor() { public String fn(String s) {return s.trim();} }; Algorithms.forEach(aList, trimmer); 124 Rozdzia 5
  • 10. Jeeli nie chcesz modyfikowa oryginalnej listy, moesz utworzy iterator przegldajcy oryginalne wartoci i zwracajcy zmodyfikowan warto kadego elementu lub ignorujcy wartoci null. Programowanie funkcjonalne jest bar- dzo uytecznym narzdziem programisty Javy. W nastpnej czci uyjemy nieco bardziej zaawansowanych cech omawianego API. JGA W poprzedniej czci uylimy funktorw do filtrowania danych wejciowych dla ptli for, eliminujc tym samym potrzeb filtrowania danych w samej ptli. JAVA 5+ JGA posiada funkcje pomocnicze suce tworzeniu zoonych funktorw i s one wbudowane automatycznie w kady unarny i binarny funktor. Klasa Unary- Functor posiada metod compose, ktra zwraca nowy funktor bdcy zoeniem z wewntrznym funktorem. Kiedy widzisz metod compose, traktuj j jak funkcj zoon: f.compose(g) oznacza funkcj f funkcji g. Innymi sowy, moesz utwo- rzy funktor h z dwch funktorw f i g, tak e h=f(g(x)), za pomoc nastpuj- cego kodu: UnaryFunctor f,g; UnaryFunctor h = f.compose(g); Kiedy wywoamy metod fn funktora h, zostanie faktycznie uyte zoenie dwch funktorw. Klasa BinaryFunctor ma podobn metod compose dla skadania jej z innymi funktorami unarnymi i binarnymi. Moemy utworzy w ten sposb acuch elementw o dowolnej dugoci. Moemy rwnie przesa wyjcie z generatora do funkcji zoonej, uywajc pomocniczej klasy Generate. Sprbuj- my uy tej metody do stworzenia zoonego generatora wytwarzajcego szereg logarytmw kwadratw kadej co trzydziestej liczby naturalnej, zaczynajc od 99. Zacznijmy od napisania generatora zwracajcego naturalne liczby ze skokiem rwnym 30, a potem bdziemy dodawa dalsz cz bazujc ju na nim: Generator every30thFrom99 = new Generator() { long count = 99; public Number gen() { long result = count; count += 30; return result; } }; UnaryFunctor log = new UnaryFunctor() { public Number fn(Number in) { double val = in.doubleValue(); return Math.log(val); } }; Zastosowania w naukach cisych i matematyczno-przyrodniczych 125
  • 11. UnaryFunctor square = new UnaryFunctor () { public Number fn(Number in) { double val = in.doubleValue(); return val*val; } }; Generate logOfSquareOfEvery30thFrom99 = new Generate(log.compose(square), every30thFrom99); Zagniedanie funkcji nie jest ograniczone do liczb. Funkcje zoone mog dziaa na obiektach dowolnego typu (na przykad String, Employee, Automobile, WebRowSet). Widzimy teraz, dlaczego tworzenie funktorw na moliwie niskim poziomie jest wane moemy potem je czy i wykorzystywa w innym kontekcie. Zanim napiszesz nowy funktor, sprawd, czy nie dasz rady osign tego samego efektu, czc kilka istniejcych. W chwili pisania tej ksiki oma- wiane API byo wci w fazie beta, wic pewne rzeczy mog ulec jeszcze zmia- nie dla pewnoci sprawd wic dokumentacj dostpn w internecie. COLT Co maj wsplnego ze sob matematyka, pistolety, konie i alkohol? Ot okazuje si, e oprcz producenta broni, gatunku alkoholu i nazwy modego konia colt JGA jest rwnie nazw API matematyczno-fizycznego. API to zostao stworzone w tym samym miejscu, gdzie narodzia si Sie w CERN, laboratorium czstek elementarnych w Szwajcarii. Strona CERN-u opisuje Colt jako wydajne i uyteczne struktury danych oraz algorytmy dla przetwarzania danych, algebry liniowej, tablic wielowymiarowych, statystyk, histogramw, symulacji Monte Carlo, programowania rwnolegego i wspbienego zarwno online, jak i offline. W tej czci rozdziau przyjrzymy si jednej z pomocniczych klas z biblioteki Colt, BitVector. Bdziemy modelowa funkcj logiki cyfrowej, tworzc funktor (jak to omawialimy wczeniej), ktry dziaa na wartociach typu BitVector. Jest to troch inna sytuacja od tej, z ktr mielimy do czynienia poprzednio, gdy uywalimy predykatw logicznych. Obecnie bdziemy starali si modelowa funkcj majc wiele bitw zarwno na wejciu, jak i na wyjciu. Nasza funkcja ma przyjmowa uporzdkowany zbir bitw i wytwarza inny uporzdkowany zbir bitw. Standardowa dystrybucja Javy dostarcza klas BitSet w celu pracy ze zbiorem bitw. Cho ta klasa moe by uyteczna w wielu aplikacjach, ma wiele wad, gdy zostanie uyta do modelowania funkcji logicznych. Po pierwsze, nie zapewnia ona staego rozmiaru zbioru. Przykadowo, jeli nasza funkcja mia- aby przyjmowa pi bitw na wejciu i zwraca trzy na wyjciu, potrzeba by byo przechowywa gdzie w osobnych zmiennych rozmiary wektorw wejcia- 126 Rozdzia 5
  • 12. -wyjcia. Po drugie, BitSet nie posiada metody do przeliczania podzbioru bi- tw na reprezentacj w postaci liczby cakowitej. Klasa BitVector z biblioteki Colt jest bardziej wydajna i lepiej przystosowana do modelowania funkcji tego typu. Zacznijmy od prostego przykadu demonstrujcego niektre z moliwo- ci tej klasy: BitVector vec1000 = new BitVector(1000); // rozmiar = 1000 bitw // pocztkowo wszystkie bity s ustawiane na false (0) vec1000.set(378); // ustaw bit 378 na true (1) System.out.println(vec1000.get(378)); // drukuje "true" na standardowym wyjciu vec1000.replaceFromToWith(1, 40, true); // ustawia bity od 1 do 40 na true // zwr bity z pozycji od 38 do 50 (wcznie) BitVector portion = vec1000.partFromTo(38, 50); //zwr warto typu long cigu bitw 3-10 long longValue = portion.getLongFromTo(3,10); Moemy uy tych metod do symulacji bramek logicznych ukadw mikro- elektronicznych stanowicych podstawowe cegieki tworzce komputer. Przy- kadem takich niskopoziomowych bramek s bramki AND, OR i NOT. Do oglnej reprezentacji bramki logicznej moemy wykorzysta instancj klasy BitVector jako wejcie i wyjcie funktora. Chocia Colt posiada wasne funktory oglnego zastosowania, uyjemy tutaj API omwionego wczeniej, aby unikn nieporo- zumie. Funktor dla bramki AND mgby wyglda tak: public class UnaryBitVectorAndFunction extends UnaryFunctor { public BitVector fn(BitVector in) { int oneBits = in.cardinality(); // ile bitw jest ustawionych na 1 int size = in.size(); // rozmiar wektora BitVector outVec = new BitVector(1); // jednobitowe wyjcie outVec.put(0, size == oneBits); // AND = same jedynki return outVec; } } W podobny sposb jestemy w stanie utworzy funkcj logiczn dowolnego typu. Zobaczmy jeszcze jeden przykad, tym razem z wiksz liczb bitw na wyjciu. Dekoder 1-do-4 (demultiplekser) jest blokiem logicznym z trzema wej- ciami i czterema wyjciami. Demultiplekser przesya sygna z wejcia (D) na jedno z czterech wyj (Q0, Q1, Q2, Q3). O tym, ktre jest to wyjcie, decyduj dwa bity sterujce (S0, S1). Tabela 5.1 pokazuje stan kadego z wyj dla kadej z moliwych kombinacji stanw wej. Tak tabel nazywa si tablic prawdy. Zastosowania w naukach cisych i matematyczno-przyrodniczych 127
  • 13. Tabela 5.1. Tablica prawdy dla demultipleksera dwuwejciowego D S1 S0 Q0 Q1 Q2 Q3 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 0 0 1 Pierwsze trzy kolumny przedstawiaj stany na wejciu, pozostae na wyj- ciu. Selektory S0 i S1 decyduj, ktre wyjcie przedstawia stan wejcia, a pozo- stae wyjcia s wyzerowane. Stwrzmy teraz model tego ukadu. Kademu sygnaowi trzeba przypisa indeks w obiekcie BitVector. W przypadku wej przyjmijmy, e indeks 0 odpowiada wejciu D, 1 S0 i 2 S1. Poniszy obiekt UnaryFunctor tworzy czterobitowy wektor zawierajcy wartoci sygnaw wyjciowych: public class QuadDemuxer extends UnaryFunctor { public BitVector fn(BitVector in) { // czterobitowy wektor wyjcia, domylnie wyzerowany BitVector outVec = new BitVector(4); // pobierz warto wejcia D boolean data = in.get(0); if (data) { // bity sterujce zwrcone jako zmienna int int selector = (int) in.getLongFromTo(1,2); outVec.set(selector); } return outVec; } } W nastpnym podrozdziale rozszerzymy t procedur i utworzymy prost implementacj tablicy prawdy dla funkcji logicznej. COLT W poprzednim podrozdziale utworzylimy demultiplekser, specyficzny rodzaj funkcji logicznej posiadajcej wiele bitw wejciowych i wyjciowych. Aby wy- jani jej dziaanie, uylimy tablicy prawdy przedstawiajcej wyjcia odpowia- dajce wszystkim kombinacjom wej. Tablica prawdy dziaa tak jak sownik typu 128 Rozdzia 5
  • 14. klucz-warto dla kluczy binarnych. Pewnie zauwaye rwnie, e nasza tablica prawdy wyglda jak macierz bitw. Moemy wykorzysta t obserwacj dla napi- sania uniwersalnego modelu tablicy prawdy. W podrozdziale utworzymy ta- blic prawdy, uywajc klasy BitMatrix, dwuwymiarowego kuzyna znanej nam BitVector, rwnie z biblioteki Colt. Wejciowe kombinacje bitw w tabeli s wymienione w kolejnoci rosncej: 000, 001, 010, 011 Poniewa kolejno bitw wejciowych w tablicach prawdy jest zawsze taka sama, ta cz tablicy jest zbdna moemy zaj si wycznie wyjciami. Liczba rzdw i kolumn bezporednio wynika z liczby wej i wyj. W ostatnim przykadzie, majc 3 wejcia i 4 wyjcia, otrzymalimy 4 kolumny i 8 rzdw. Liczba kolumn jest rwna liczbie wyj. Liczba rzdw jest rwna 2n, gdzie n oznacza liczb wej, poniewa musimy uwzgldni wszystkie moliwe kombinacje bitw na wejciu. Oczywicie pojedyncza tablica prawdy nie jest do- brym pomysem dla bardzo duej liczby wej. Jednake zoone systemy mog by stworzone przez wzajemne powizanie wielu prostszych komponentw, wic nie jest to powany problem. Jeli tylko pamitasz kolejno bitw wejciowych, moesz przekonwertowa je na liczby cakowite i uy jako indeksw dla rzdw zawierajcych bity wyjcio- we. Zademonstrujmy to na przykadzie, tworzc macierz bitw typu BitMatrix dla tablicy prawdy z tabeli 5.1: int inputSize = 3; int rows = 1 Object[], ktra oblicza warto wyjcia dla zadanych wartoci na wejciu. Komponent jest zaimplementowany jako interfejs w celu zwikszenia zakresu moliwych zastosowa: public interface Component { // zwraca ilo portw wejciowych public int getInputSize(); // zwraca ilo portw wyjciowych public int getOutputSize(); // zwraca port wejciowy o danym numerze identyfikacyjnym public InputPort getInputPort(int index); // zwraca port wejciowy o danym numerze identyfikacyjnym public OutputPort getOutputPort(int index); // zasadnicza metoda komponentu wykonujca funkcj outputs = f(intputs) public void process(); } W tej chwili mamy ju oglny szkielet dla czenia komponentw posiadaj- cych porty wejcia-wyjcia. Zaoyem tutaj, e komponent posiada jedn funkcj wykonujc ca prac, pobierajc Object[] jako parametr i zwracajc rw- nie Object[]. Jeli chcesz, moesz uczyni t funkcj na tyle elastyczn, e b- dzie ona potrafia zwraca pojedynczy obiekt na pierwszy port wyjciowy i null na pozostae. Na stronie internetowej ksiki znajdziesz implementacj klasy Component wzbogacon o moliwo uycia typw generycznych Javy 5 (ang. gene- rics). Zewntrzny proces kontroluje komponenty i zarzdza poczeniami midzy nimi zaimplementujemy go pniej, korzystajc z API grafw. Jednake wczeniej musimy zmieni nasz obiekt w jednostk przetwarzajc bity korzy- stajc z tablicy prawdy. Moemy napisa jednoargumentowy funktor (podtyp UnaryFunctor), ktry przetwarza tablic obiektw na bity, stosujc pewne proste reguy konwersji. Funkcja powinna by na tyle elastyczna, eby interpretowa kady obiekt w tabli- cy jako bit w ten sam sposb (Boolean, niezero, nie-null). Zamy, e metoda arrayToBits konwertuje tablic na bity. Przekonwertowane bity s interpreto- wane zgodnie z tablic prawdy i daj bity wyjciowe. Te z kolei s zwracane jako tablica Boolean[], tak aby komponent mg przesa rezultat na swoje porty wyj- ciowe. Zamy, e metoda bitsToArray potrafi tego dokona. Poniszy przykad jest uproszczon wersj faktycznej funkcji, ktra mogaby by uyta z nasz klas Component: 138 Rozdzia 5
  • 24. public class UnaryTruthTableFunction extends UnaryFunctor { public Boolean[] fn(Boolean[] in) { // zmie obiekty na bity (w jaki sposb) int convertedInput = arrayToBits(in); // znajd wyjcie w tabeli prawdy // (opis w podrozdziale "Tworzenie tablic prawdy za pomoc BitMatrix") long result = retrieve(convertedInput); //zmie wyjciowe bity na Boolean[] (w jaki sposb) return bitsToArray(result); } } Dokadniejsze rozwizanie jest dostpne na stronie internetowej ksiki. W biecej implementacji rezultaty musz by obliczane w sposb do przodu (tzn. tylko w kierunku od wej do wyj). Jeli komponenty s powizane ze sob cyklicznie, potrzebny bdzie jaki rodzaj synchronizacji. W kolejnym podrozdziale wprowadzimy API grafw i uyjemy go do poczenia portw midzy komponen- tami oraz uruchomienia symulacji. JGraphT W rozdziale 4. odkrywalimy Sie semantyczn. Standard RDF ktry omawiali- , my, modeluje te sieci jako etykietowane grafy skierowane. Grafy oznaczaj tu JAVA 5+ sie wzw lub wierzchokw. W teorii grafw etykietowany graf skierowany oznacza, e kada krawd midzy dwoma wierzchokami posiada opis i kierunek. Grafy Jena i RDF uyte przez nas wczeniej s implementacj grafw oznaczo- nych do specyficznych zastosowa, inne aplikacje mog jednak potrzebowa innych typw grafw do modelowania oraz wykonywania operacji na nich. W tym celu moesz wykorzysta JGraphT, atw w uyciu bibliotek do pracy z grafami rnego rodzaju. Koncentruje si ona na samym modelu grafu, jego pocze oraz wykonywaniu operacji na nim a nie na wizualizacji i wywietlaniu go. W rozdziale 6. omwimy inne API, ktrego gwnym celem jest wizualizacja grafw. Pki co jednak bdziemy budowa po prostu modele grafw. Wzy w JGraphT mog by dowolnymi obiektami Javy. Model grafu opisuje, w jaki sposb obiekty poczone s ze sob. Uywajc tego modelu, moesz zaj- mowa si poczeniami midzy obiektami, niezalenie od samych obiektw. Jest to bardzo podobne do zaoe modelu Model-View-Controller (MVC, model- -widok-kontroler) uytego w Swingu oraz frameworkach sieciowych. Teoria gra- fw jest uyteczna w symulacji i analizie wielu skomplikowanych systemw, takich jak sieci komputerowe, obwody cyfrowe, ruch na autostradzie czy przesy danych. Tworzenie grafu w JGraphT jest proste. Na pocztku tworzysz instancj wy- maganego typu grafu. Nastpnie wywoujesz metod addVertex, aby doda nowy obiekt Javy jako wierzchoek. Kiedy obiekt jest ju czci grafu, moesz wywoa Zastosowania w naukach cisych i matematyczno-przyrodniczych 139
  • 25. metody suce poczeniu go z innymi wierzchokami. Poniej mamy przykad modelu pocze niektrych organw i systemw w ciele ludzkim. Rysunek 5.2 pokazuje zalenoci miedzy elementami grafu. Rysunek 5.2. Organy i systemy w ciele ludzkim Uyjemy konstrukcji enum z Javy 5 (zobacz rozdzia 1.) do reprezentacji orga- nw i ukadw zawartych w grafie. Aby przechowywa zalenoci midzy tymi czciami, moemy stworzy graf nieskierowany: import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.SimpleGraph; enum Organs {HEART, LUNG, LIVER, STOMACH, BRAIN, SPINAL_CORD}; enum Systems {CIRCULATORY, DIGESTIVE, NERVOUS, RESPIRATORY}; SimpleGraph graph = new SimpleGraph(DefaultEdge.class); graph.addVertex(Organs.HEART); // serce graph.addVertex(Organs.LUNG); // puco graph.addVertex(Organs.BRAIN); // mzg graph.addVertex(Organs.STOMACH); // odek graph.addVertex(Organs.LIVER); // wtroba graph.addVertex(Organs.SPINAL_CORD); // rdze krgowy graph.addVertex(Systems.CIRCULATORY); // ukad krenia graph.addVertex(Systems.NERVOUS); // ukad nerwowy graph.addVertex(Systems.DIGESTIVE); // ukad pokarmowy graph.addVertex(Systems.RESPIRATORY); // ukad oddechowy 140 Rozdzia 5
  • 26. graph.addEdge(Organs.HEART, Systems.CIRCULATORY); graph.addEdge(Organs.LUNG, Systems.RESPIRATORY); graph.addEdge(Organs.BRAIN, Systems.NERVOUS); graph.addEdge(Organs.SPINAL_CORD, Systems.NERVOUS); graph.addEdge(Organs.STOMACH, Systems.DIGESTIVE); graph.addEdge(Organs.LIVER, Systems.DIGESTIVE); Zwr uwag, e kady z wierzchokw musi by dodany do grafu, zanim doczysz go do krawdzi, w przeciwnym razie otrzymasz wyjtek. Ten kod nie wywietla niczego, tworzy jedynie wewntrzn sie pocze. Dokadniej tworzy on list ssiadw dla kadego obiektu. W tym szczeglnym przypadku wszystkie krawdzie s traktowane jednakowo. Aby krawdzie stay si rozrnialne, moesz uy krawdzi etykietowanych. Wywoujc odpowiednie metody na grafie, moesz znale ssiadw danych obiektw. Znajdmy wic krawdzie dla jakiego wierzchoka z naszego przy- kadu i wywietlmy, co jest po drugiej stronie danej krawdzi. Wzy poczone bezporednio z wzem DIGESTIVE moemy znale za pomoc metody: import org.jgrapht.Graphs; import org.jgrapht.graph.DefaultEdge; Set digestiveLinks = graph.edgesOf(Systems.DIGESTIVE); for (DefaultEdge anEdge : digestiveLinks) { Enum opposite = Graphs.getOppositeVertex(graph, anEdge, Systems.DIGESTIVE); System.out.println(opposite); } Technika, ktrej tutaj uylimy, polega na uzyskaniu listy krawdzi, nastpnie dla kadej z nich trzeba znale wierzchoek, ktry nie jest wzem DIGESTIVE (czyli znale przeciwny wierzchoek). DefaultEdge (krawd) to bazowa klasa, po ktrej dziedzicz wszystkie krawdzie i ktra czy wierzchoek rdowy z docelowym. Moesz uy jednej ze standardowych implementacji dostpnych wraz z bibliotek JGraphT lub napisa wasn podklas, aby speniaa specyficzne zadania. JGraphT posiada implementacje innych operacji, ktre mona wykonywa na grafach. Wicej informacji znajdziesz w dokumentacji do API. Bdziemy korzy- sta jeszcze z JGraphT w nastpnej czci rozdziau. W rozdziale 6. uyjemy innego API do wizualizacji grafw. Zastosowania w naukach cisych i matematyczno-przyrodniczych 141
  • 27. JGraphT W czci powiconej czeniu wzw stworzylimy ogln jednostk oblicze- niow z portami wejcia i wyjcia, a w czci powiconej grafom poznalimy JAVA 5+ sposb na czenie dowolnych obiektw Javy w struktur grafw. W tej czci poczymy wejcia i wyjcia komponentw, uywajc JGraphT. Tym sposobem bdziemy mogli utrzymywa poczenia portw niezalenie od implementacji komponentw. W rzeczywistoci nie dbamy tutaj w ogle o to, co komponenty robi, lub nawet czy przetwarzaj one wartoci logiczne. Kady komponent ma metod process, ktra pobiera dane z portw wejciowych, przetwarza je i zwraca rezultaty na porty wyjciowe. Moemy wywoa metod process dla kadego z komponentw i wysa wynik na porty wyjciowe. Jeli uylimy grafu skie- rowanego, moemy przesa dane z wyj na wejcia kolejnych stopni poprzez iteracj po wszystkich krawdziach. Dla kadej krawdzi wywoujemy metod getValue na wierzchoku rdowym (OutputPort) i ustawiamy warto wyjciow na wierzchoku docelowym (InputPort) za pomoc metody setValue. Moemy teraz napisa klas, ktra zarzdza wierzchokami uywajc API grafw. public class MetaComponentSimple { private ListenableDirectedGraph graph; public MetaComponentSimple() { graph = new ListenableDirectedGraph(DefaultEdge.class); } public void connect(OutputPort out, InputPort in) { Component source = out.getParent(); Component target = in.getParent(); //dodaj nadrzdne komponenty do grafu if (!graph.containsVertex(source)) { graph.addVertex(source); } if (!graph.containsVertex(target)) { graph.addVertex(target); } // dodaj porty do grafu if (!graph.containsVertex(in)) { graph.addVertex(in); } if (!graph.containsVertex(out)) { graph.addVertex(out); } // dodaj krawd od komponentu-rda do portu wyjciowego graph.addEdge(source, out); // dodaj krawd od portu wyjciowego do wejciowego graph.addEdge(out, in); // dodaj krawd od portu wejciowego do komponentu-celu graph.addEdge(in, target); } 142 Rozdzia 5
  • 28. public void process() { processSubComponents(); propagateSignals(); } private void propagateSignals() { for (DefaultEdge edge : graph.edgeSet()) { Object source = graph.getEdgeSource(edge); Object target = graph.getEdgeTarget(edge); if (source instanceof OutputPort) { OutputPort out = (OutputPort) source; InputPort in = (InputPort) target; in.setValue(out.getValue()); } } } private void processSubComponents() { for (Object item : graph.vertexSet()) { if (item instanceof Component) { ((Component) item).process(); } } } } Aby uy tej klasy, musisz najpierw ustanowi poczenia pomidzy portami, wywoujc metod connect. Ta metoda dodaje nadrzdny komponent kadego portu do grafu, tak aby p- niej dany komponent mg wywoa metod process swoich subkomponentw. Klasa zarzdzajca ma wasn metod process, ktra najpierw wywouje analo- giczne metody wszystkich komponentw, a nastpnie przekazuje wyniki ich dziaa na wejcia kolejnego stopnia. Wybr tej samej nazwy dla tej metody nie jest przypadkiem. Jeli chciaby zaimplementowa inne metody interfejsu Compo- nent, mgby uy tej klasy do zbudowania komponentu zoonego z innych komponentw. Na stronie internetowej ksiki znajdziesz bardziej kompletny przy- kad. Poniej mamy kod, ktry korzysta z naszej nowej klasy do implementacji funkcji y=AND(OR(a,b),OR(c,d)). MetaComponentSimple manager = new MetaComponentSimple(); // Zamy, e stworzylimy komponent bramk typu AND, // uywajc technik opisanych wczeniej. Posiada ona dwa wejcia. Component and = createAndGateComponent(2); OutputPort y = and.getOutputPort(0); // uyjemy pary bramek OR, kada z nich jest dwuwejciowa Component or1 = createOrGateComponent(2); InputPort a = or1.getInputPort(0); Zastosowania w naukach cisych i matematyczno-przyrodniczych 143
  • 29. InputPort b = or1.getInputPort(1); Component or2 = createOrGateComponent(2); InputPort c = or2.getInputPort(0); InputPort d = or2.getInputPort(1); manager.connect(or1.getOutputPort(0), and.getInputPort(0)); manager.connect(or2.getOutputPort(0), and.getInputPort(1)); // ustaw wartoci wejciowe a.setValue(true); b.setValue(false); c.setValue(false); d.setValue(false); manager.process(); // potrzebujemy drugiego wywoania, gdy mamy komponent dwustopniowy manager.process(); System.out.println(y); // wynik: false Zauwa, e przetwarzanie sygnau moe zajmowa wicej ni jeden cykl, zanim osignie on porty wyjciowe. Tak te jest dla rzeczywistych obwodw, po- niewa kady komponent wprowadza opnienie, cho jest ono tak krtkie, e go nie zauwaamy. Dyskusj zalenoci czasowych zostawiamy do rozdziau 7. W nastpnej czci bdziemy zajmowa si innymi sieciami, przypominajcymi sie nerww w mzgu, zwanymi sieciami neuronowymi. JOONE Czy zastanawiae si kiedy, jak mona zbudowa mzg? C, w Javie jest to proste i wcale nie musisz si czu doktorem Frankensteinem. W terminologii informatycznej sieci neuronowe to grupa prostych komrek obliczeniowych cile powizanych ze sob i tworzcych jako cao system do przetwarzania danych. Niektrzy uywaj terminu sieci neuronowe na okrelenie dowolnych systemw konekcjonistycznych. Tutaj jednak bdziemy si zajmowa systemami o archi- tekturze zblionej do tej, ktr posiada ludzki mzg. Systemy takie s uywa- ne w wielu zadaniach takich jak rozpoznawanie mowy i obrazw oraz uczenie si maszyn. W sieci neuronowej pojedynczy wze nazywa si neuronem. Neuron taki odbiera dane wejciowe od ssiadw, przy czym kademu poczeniu z ssiadem (krawdzi) przypisana jest pewna waga. Poczenia takie w sieciach neuronowych nazwane s synapsami. Waga jest uwzgldniana przy pobieraniu danych z synap- sy, nastpnie dane te s przesyane do kolejnych neuronw docelowych. Sieci neuronowe s uyteczne, gdy mog by uczone rozpoznawania pewnych zale- noci (wzorcw) pord danych. Sie neuronow mona nauczy tego, co ma ona robi. Joone jest atwym w uyciu API dla pracy z sieciami neuronowymi w Javie. Posiada edytor graficzny dla tworzenia i uczenia sieci neuronowych. Cho jest rwnie moliwe stworzenie i nauka sieci w sposb programowy, uycie edytora 144 Rozdzia 5
  • 30. jest rozwizaniem prostszym. Gdy ju stworzysz w edytorze swoj sie i zako- czysz proces nauki, moesz zagniedzi t sie i silnik Joone w swojej aplika- cji. Rysunek 5.3 pokazuje edytor graficzny w uyciu oraz jedn z przykadowych sieci Joone. Rysunek 5.3. Edytor graficzny Joone Z pomoc edytora moesz tworzy, uczy i uruchamia sieci neuronowe. Eksportujc nauczon sie do pliku (uywajc menu File > Export NeuralNet), moesz wykorzysta j pniej we wasnym programie. Edytor Joone tworzy seria- lizowane pliki zawierajce sieci, ktre to pliki moesz nastpnie wczyta i urucho- mi za pomoc silnika Joone, uywajc poniszego kodu. import org.joone.net.NeuralNetLoader; import org.joone.net.NeuralNet; import org.joone.engine.Monitor; import org.jonne.io.FileOutputSynapse; NeuralNetLoader netLoader = new NeuralNetLoader("/projects/nn/ mynetwork.snet"); NeuralNet myNet = netLoader.getNeuralNet(); // pobierz warstw wyjciow sieci Layer output = myNet.getOutputLayer(); //dodaj wyjciow synaps (poczenie) do warstwy wyjciowej FileOutputSynapse myOutput = new FileOutputSynapse(); Zastosowania w naukach cisych i matematyczno-przyrodniczych 145
  • 31. // ustaw plik wyjciowy na mynetwork.out myOutput.setFileName("/project/nn/mynetwork/out"); output.addOutputSynapse(myOutput); Monitor monitor = myNet.getMonitor(); // wykonamy jeden cykl monitor.setTotCicles(1); // ustaw flag fazy uczenia na 0 monitor.setLearning(false); // uruchom warstwy sieci myNet.start(); // uruchom monitor monitor.Go(); Powyszy przykad aduje serializowan sie do instancji klasy NeuralNet, uywajc klasy pomocniczej NeuralNetLoader. Nastpnie tworzymy synaps File- OutputSynapse, ktra bdzie przechwytywa dane wyjciowe generowane przez sie. Dane wejciowe i wyjciowe s tablicami double[]. Klasa Monitor zarzdza sieci oraz pozwala na uruchamianie i zatrzymanie oraz ustawianie parametrw kontrolujcych jej zachowanie. Nie uwzgldniem tutaj kodu obsugi wyjtkw, aby pozostawi listing krtkim i prostym oraz aby skupi si na samym dziaaniu sieci. Jeli wszystko, co chcesz zrobi, to uruchomienie sieci neuronowej i zapisa- nie wynikw do pliku, nie musisz pisa takiej aplikacji. Istnieje klasa NeuralNet- Runner obsugiwana z wiersza polece, moesz te uruchomi sie z edytora Joone. Odnoniki do dokadniejszej dokumentacji Joone znajdziesz na stronie inter- netowej ksiki. Dokumentacja ta posiada wiele przykadw, z ktrymi moesz poeksperymentowa: rozpoznawanie obrazw, analiz szeregw czasowych, pro- gnozowanie kursw walut oraz wiele innych. Poniewa sieci mog by seriali- zowane, istnieje rwnie framework dla tworzenia rozproszonych sieci neuro- nowych. Jest on wystarczajcy do stworzenia globalnych mzgw to mogoby zapewne uszczliwi doktora Frankensteina! Sieci neuronowe s potn tech- nik, ktr mona zastosowa w wielu zadaniach zwizanych z rozpoznawaniem wzorcw, a Joone sprawia e tworzenie takich sieci i zagniedanie we wasnych aplikacjach jest bardzo atwe. JGAP Istniej problemy, dla ktrych nieatwo jest znale waciwy algorytm do ich rozwizania. Jest to szczeglnie problematyczne w wypadku procesw, ktre wy- COLT magaj czstych zmian algorytmu w celu uwzgldnienia zmiennych warunkw rodowiska programu. W takich przypadkach moesz sprbowa napisa pro- gram, ktry samodzielnie wypracowuje rozwizanie. Jest to tak zwany algorytm genetyczny (ang. Genetic Algorithm, GA). Ten typ programowania polega na wyprbowaniu wielu rozwiza i wybraniu najlepszego. W kadym cyklu prb najlepiej przystosowane elementy ze zbioru rozwiza (wedug wybranej funkcji oceny ang. fitness function) s wybrane do rozmnoenia i tworz nastpne 146 Rozdzia 5
  • 32. pokolenie. Nastpnie nowe pokolenie rozwiza jest poddawane mutacjom i krzy- owane z innymi, co prowadzi do powstania wielu nowych wersji rnicych si od poprzednich. Proces powtarza si dla kolejnych generacji. Czasami proces ten prowadzi do powstania precyzyjnie wykalibrowanego al- gorytmu ju po kilku iteracjach. By moe nawet trudno bdzie zrozumie, jak dokadnie dziaa wybrany algorytm i moe si on rni zdecydowanie od roz- wizania, ktre wybralibymy, piszc je rcznie, poniewa funkcja oceny wybie- ra w tym wypadku algorytmy najskuteczniejsze, takie te bd algorytmy wytwo- rzone przez ten proces. Istnieje wiele bibliotek dla algorytmw genetycznych stworzonych w Javie. Wiele odnonikw znajdziesz na stronie internetowej ksiki. W tej czci pu- blikacji przyjrzymy si jednej z nich JGAP (ang. Java Genetic Algorithms Package pakiet algorytmw genetycznych dla Javy). Zacznijmy od kilku pod- stawowych poj uywanych w dziedzinie algorytmw genetycznych. Terminy te s zapoyczone z genetyki, mimo e obiekty uywane w tych algorytmach maj raczej niewiele wsplnego z DNA. Chromosom (lub genom) przedstawia zbir moliwych podej do rozwizania problemu, a gen przestawia jednostk w chro- mosomie (allele s konkretnymi odmianami genu, podobnie jak z zalenoci klasa-instancja). Gen moe by acuchem tekstowym, liczb, drzewem, progra- mem lub dowoln inn struktur. Aby uywa JGAP musisz na pocztku wybra , genom, ktry odpowiednio reprezentuje przestrze twojego problemu. Nastpnie wybierasz funkcj oceny dla testowania indywidualnych osobnikw populacji. Na koniec tworzysz obiekt konfiguracji, aby opisa charakterystyk procesu, i mo- esz ju rozpocz proces rozmnaania osobnikw. Uyjemy kodu z naszego przykadu tablicy prawdy z czci Bity duego kalibru, gdzie stworzylimy demultiplekser 1-do-4. Stworzylimy wtedy tablic prawdy dla demultipleksera z dwoma wejciami adresowymi, pojedynczym wej- ciem danych i czterema wyjciami danych. Wymaga to dokadnie 32 bitw w tablicy prawdy. Moesz potraktowa to jako testowanie pojedynczego genu o staej dugoci rwnej 32 bity w naszej symulacji genetycznej. Jak si okazuje, nie dziaa to najlepiej w naszej aplikacji, poniewa przestrze poszukiwania jest rwna caemu zakresowi wartoci typu int. Moemy zaprojektowa to lepiej, uywajc genu czterobitowego reprezentujcego bity wyjciowe i chromosomu o dugoci 8. Poniewa cztery bity wyjciowe dziaaj jako cao, okazuje si to by duo lepszym wyborem dla genu. W wielu testach przeprowadzonych przy 100 000 pokole i populacji rwnej 200 gen 32-bitowy nie wytworzy pojedyncze- go dopasowania. Jednake z 4-bitowym genem zwycizca pojawia si szybciej ni w dwudziestym pokoleniu. Biblioteka JGAP posiada implementacj interfejsu Gene (gen) nazwan Integer- Gene. Jest ona atwa do konwersji na typ Integer, wic bdzie si ona dobrze integrowa z nasz tablic prawdy. Funkcja oceny w JGAP posiada metod evaluate z parametrem typu IChromosome, ktra zwraca warto double. Wysza war- to oznacza, e dany osobnik wykonuje zadanie lepiej. Tak wyglda nasza funk- cja oceny: Zastosowania w naukach cisych i matematyczno-przyrodniczych 147
  • 33. public class DemuxFitness extends org.jgap.FitnessFunction { private TruthTable tt; public DemuxFitness() { // to jest nasz cel, do ktrego chcemy wyewoluowa tt = new TruthTable(3,4); tt.store(4, 1); // 100 -> 0001 tt.store(5, 2); // 101 -> 0010 tt.store(6, 4); // 110 -> 0100 tt.store(7, 8); // 111 -> 1000 } public int correctBits(int data) { BitVector vecValue = new BitVector(new long[] {data}, 32); BitVector target = tt.getTruthMatrix().toBitVector(); // moemy znale liczb waciwych bitw za pomoc: // count(not(xor(target, vecValue))) vecValue.xor(target); vecValue.not(); return vecValue.cardinality(); } public double evaluate(IChromosome chrom) { int valueTotal = 0; for (int i = 7; i>=0; i--) { IntegerGene gene = (IntegerGene) chrom.getGene(i); Integer value = (Integer) gene.getAllele(); valueTotal += value; valueTotal