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
Java. Programowanie, biblioteki open-source i pomysły na nowe projekty
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.
Citation preview
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