Generowanie diagramów struktury bazy danych

W poprzednim poście zamieściłem diagramy bazy danych. Pierwszy uzyskałem od osoby, od której dostałem rozwiązanie i bazę danych. Znajdował się tam diagram bazy danych stworzony w programie DIA. W ramach moich prac dodałem kilka pól do bazy danych. W celu przedstawienia tych zmian poprawiłem również otrzymany diagram. Wszystko to znajduje się w dwóch poprzednich postach.

Pewnego dnia przysiadłem nad drastycznymi zmianami w bazie danych, tzn. zmiana nazw, usunięcie niepotrzebnych pól, etc. Od programisty, który stworzył ten system, otrzymałem również SQLa generującego bazę danych. Wszystkie poprawki jej dotyczącej sprowadzały się tak naprawdę do edycji jednego pliku SQLowego, co bardzo ułatwiało prace (oczywiście równolegle wykonywałem zmiany w reszcie projektu, tzn. w plikach Javowych).

Wykonałem sporo zmian w bazie i chciałem narysować nowy diagram. Tych zmian było jednak tak wiele, że po chwili zrezygnowałem z pomysłu poprawiania diagramu programem DIA. Skoro mam już działającą bazę danych, pomyślałem, to wykorzystam narzędzie, które wygeneruje mi diagram przedstawiający jej strukturę. I tu zaczęły się małe schody:

  1. Znalazłem w internecie informację, że MS Visio wspiera database reverse engineering, tzn. z istniejącej bazy danych mogę wygenerować diagram przedstawiający jej strukturę.
  2. Ściągnąłem więc Visio i chciałem go zainstalować. Po małych kłopotach (za mało pamięci, trzeba usunąć niepotrzebne rzeczy) udało mi się to.
  3. Niestety, Visio w wersji 2016 nie wspiera już tego procesu. Szukamy więc narzędzia do baz MySQLowych, które zrobi diagram za mnie. Na moje szczęście MySQL Workbench ma to wbudowane. A właśnie tego narzędzia używam do zarządzania bazą.
  4.  Baza, z której korzystam, jest bazą relacyjną. Niestety, plik sqlowy nie przedstawiał tego (prócz używania tych samych nazw dla kluczy w różnych tabelach). Miałem więc dwa wyjścia: dorysować na diagramie połączenia lub napisać kilka linii w sqlu. Oczywiście wybrałem to drugie rozwiązanie. Plik sqlowy na początku miał usuwanie wszystkich tabel. Musiałem więc zadbać o odpowiednią kolejność ich usuwania, właśnie ze względu na dodane relacje.
  5. Po chwili miałem diagram przedstawiający strukturę nowej bazy danych. Przedstawię ją w następnym poście.

Podsumowując:

  • MS Visio 2016 nie wspiera tworzenia diagramów bazy danych na podstawie istniejącej bazy,
  • MySQL Workbench wspiera ten proces,
  • lepiej zrobić jest w bazie danych jawne relacje niż za każdym razem dorysowywać połączenia lub przeszukiwać wszystkie tabele w poszukiwaniu zależności.

Baza danych

W ramach zaadaptowania algorytmu układającego plan zajęć na uczelni do problemu harmonogramu urządzeń została trochę zmieniona baza danych. Przedstawia ją poniższy obrazek:

DatabaseDiagram

Dodano tabelę ElectricityBorder, która zawiera informację o ograniczeniu na prąd w danym dniu oraz czasie, przechowuje również wykorzystany już w tym czasie prąd oraz różnicę między tymi wartościami.

Tabela Teachers została rozszerzona o kolumnę electricity_value – wartość prądu, jaką zużywa nauczyciel.

Definicje tabel uległy zmianom. Można to zauważyć obserwując ich nazwy:

  • Tabela Teachers zmieniła się na Teachers_Devices – wiersze tabeli reprezentują konkretne urządzenie.
  • Groups -> Groups_Plugs – tabela reprezentuje wtyczkę urządzenia.
  • TeachGroup -> Teach_DeviceGroup  – relacja wiele do wielu dla tabeli Teachers_Devices  i Groups_Plugs, odpowiednio dodawane dane sprawią jednak, że ta relacja będzie 1-1.
  • SubjectTypes -> Subject_BuildingTypes – tabela zawiera typy budynków. W moim przypadku będą dwa typy: Administracja i Dom. Mają one różne priorytety w algorytmie układania harmonogramu.
  • Subjects -> Subjects_Buildings – wiersze tabeli reprezentują konkretne budynki na osiedlu.
  • Rooms -> Rooms_SocketHouses – wiersze reprezentują konkretne gniazdka.
  • Students – Students_Users -> tabela zawiera wpisy z konkretnymi użytkownikami konkretnego urządzenia.

Pozostałe tabele nie zmieniły pierwotnej funkcji swojego działania, więc ich nazwy też nie uległy zmianom.

Agent planner

W celu ułożenia harmonogramu dla urządzeń wykorzystuję kod źródłowy układający plan zajęć na Politechnice Gdańskiej. Kod ten stanowi pracę magisterską Rafała Tkaczyka. Oparty jest on o agentów programowych (zaimplementowanych w technologii JADE) oraz relacyjnej bazie MySQL. Poniższy rysunek przedstawia pierwotny model bazy danych:

databaseDiagram

Stan projektu

W trakcie tworzenia mojej pracy magisterskiej dotarłem do momentu stworzenia i zaimplementowania algorytmu tworzenia harmonogramu dla urządzeń bazujący na agentach programowych. Wykonałem jego okrojoną wersję, która wymagała jeszcze wiele pracy. Niespodziewanie mój promotor uszczęśliwił mnie działającym algorytmem rozwiązującym problem tworzenia harmonogramu zajęć na Politechnice Gdańskiej, który bazuje na agentach programowych.

Kod napisany jest w Javie i również korzysta z biblioteki JADE. Wykorzystuje on jednak relacyjną bazę danych MySQL. To jednak nie jest żaden problem. Zainstalowałem bazę danych, zmieniłem trochę otrzymany kod, aby działał na mojej maszynie, i po chwili miałem ułożony harmonogram dla uczelni gdańskiej.

Z otrzymanym rozwiązaniem zrobiłem kilka rzeczy:
– wykorzystałem moją klasę uruchamiającą agentów,
– scenariusz dla konkretnego problemu zapisałem w kodzie, a następnie zapisuję ten scenariusz w XMLu,
– usunąłem szkielet mojego algorytmu,
– rysuje wykresu dla planu w kontekście włączania urządzeń i zużywania prądu,
– w momencie uruchamiania środowiska agentów, usuwam dane z bazy danych i wczytuję wszystko z XMLa.

Obecnie jestem w momencie implementowania przystosowania modelu bazy danych z problemu uczelni na model z problemu osiedla.

Architektury systemów wieloagentowych

Jorg P. Muller w Control Architectures for Autonomous and Interacting Agents: A Survey wymienia architektury systemów wieloagentowych:

  1. Dla agentów reaktywnych:
    1. Broks: subsumpcja architektury – jest to dekompozycja systemu na aktywnych agentów będących producentami, którzy pracują równolegle.
    2. Steels: roboty  behawioralne – stawianie na samoorganizujący się świat, gdzie agenci składają się z obiektów, które mają wykonywać proste zadania (swarm intelligence).
    3. Arkim: architektura AuRA (Autonomous Robot Architecture) – rozszerza model Brooks’a o pięć komponentów. Jest podobny do Procedural Reasoning System oraz Firby’s RAP System.
    4. Maes: dynamiczny wybór – agent decyduje (dynamicznie) jaką akcję wykona w następnym momencie swojego życia.
  2.  Dla agentów deliberatywnych (naradzających się)
    1. Bratman: IRMA – architektura agentów ograniczonych zasobami. Opisuje jak agent wybiera swój kierunek działania na podstawie swoich doznań, wierzeń, pragnień i intencji.
    2. Rao i Georgeff: formalny model BDI – sformalizowany model BDI. Wierzenia, pragnienia i intencje opisywane są przez operatory modalne.
    3. Rao i Georgeff:interpretacja BDI – dodanie interpretera, który interpretuje BDI agentów, ponieważ wcześniej model mógł nie mieć pełnej listy aksjomatów.
    4. Shoham i Thomas: programowanie zorientowane na agentów – architektura AOP (Agent-oriented programming). Przedstawili agenta jako jeden obiekt, który posiada wierzenia, możliwości, wybory i zobowiązania.
  3. Dla agentów interaktywnych:
    1. Fisher: MAGSY – agenta reprezentuje zestaw faktów będący jego wiedzą, zestaw zasad będących strategia i zachowaniami, zestaw serwisów będących interfejsem zewnętrznym agenta. Jeden agent może zawołać serwis innego agenta.
    2. Jennings: GRATE – zawiera warstwę wiedzy powszechnej (znanej i dostępnej dla każdego agenta)
    3. Steiner: MECCA – agent składa się z ciała (aplikacja), głowy (cele agenta), komunikatora.
    4. Sundermeyer: COSY – opisuje agenta jako zachowania, zasoby i intencje
  4. Architektury hybrydowe.

Refaktoryzacja

Refaktoryzacja – z pewnością każdy, kto napisał już trochę kodu, zna to słowo.

W tym roku już drugi raz trafiła w moje ręce książka:

Refaktoryzacja. Ulepszanie struktury istniejącego kodu. Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts.

Bardzo polecam tę książkę. Osobiście dużo czasu poświęcam refaktoryzacji. Wynika to ze sposobu tworzenia przeze mnie oprogramowania: mało modelowania w początkowej fazie, najpierw zróbmy coś działającego, potem to uporządkujmy. Z czasem i doświadczeniem nie poświęcam wcale więcej czasu na modelowanie, lecz od razu tworzę lepsze modele. Często przez kilka dni nie tworzę żadnej wartości dodanej, prócz tego, że mój kod jest przejrzystszy, lżejszy i bardziej logiczny. Dlaczego to robię? Sprawia mi to przyjemność i daje sporo satysfakcji. Zabawne jest, gdy czytasz swój stary kod i myślisz sobie: kto to napisał?

Jak zabieram się do refaktoryzacji?

Robię to na trzy sposoby:

Przede wszystkim czytam kod i używam przekształceń z wyżej wymienionej książki.

Do mojego kodu piszę często dokumentację. Pisząc ją, można łatwo zauważyć, że coś z naszym kodem może być nie do końca w porządku.

Bardzo przydatne w procesie refaktoryzacji są diagramu UML: diagramy klas oraz przepływu. Daje nam to szerokie spojrzenie na tworzone oprogramowanie.

Zmiany

Po wielu napisanych linijkach kodu i rozmowach z promotorami, moja praca magisterska nabrała kształtów oraz nowego kierunku. Jej temat nie uległ zmianie, lecz jej zawartość.

Czego dotyczy aktualnie? Jaki problem chcę rozwiązać?

Problem stworzenia harmonogramu użycia urządzeń w taki sposób, aby funkcja ich zakumulowanego zużycia prądu miała jak najmniej skoków. Co mam na myśli? Nie chcę, aby wykres tej funkcji rwał się i aby nie miał nagłych skoków lub spadków.

Dla wyjaśnienia mały przykład:

Mamy dwa urządzenia:

Pralka – chcemy, aby pranie było zrobione we wtorek między 16 a 20 lub w środę między 14 a 20 (preferencje działania). Ma to być jedno pranie o czasie trwania 2h (sesja). Ma moc 200 W.

Piec – ma działać cały czas między godziną 6 a 18. Ma moc 800 W.

Najlepszym  rozwiązaniem, wedle moich powyższych kryteriów, jest włączenie pieca codziennie między 6 a 18 oraz pralki w środę o godzinie 16.

Gdybyśmy włączyli pralkę w innym momencie, to w stosunku do zaproponowanego wyżej rozwiązania, mielibyśmy jeden spadem z 200 W do 0 W oraz jeden skok z 0 W do 800 W. Ja proponuję zamiast tego jeden skok z 200 W na 800 W.

Problem stabilizacji i skalowania systemu wieloagentowego

Systemy agentowe, w których zmienia się w czasie liczba aktualnie działających agentów, borykają się z problemem stabilizacji oraz skalowalności.
Problem stabilizacji – liczba agentów w systemie zmienia się w czasie, jednak stabilność systemu wymaga, aby ich liczba była ograniczona. Ograniczenie to powinno definiować nie tylko maksymalną liczbę agentów, ale również minimalną.
Problem skalowalności – problem polega na dobraniu odpowiedniej liczby agentów do wielkości zadania. Podejście agentowe umożliwia precyzyjniejsze skalowanie dzięki doborowi odpowiedniej ilości agentów konkretnego typu. Zbyt wielka liczba agentów może sprawić, że zasoby maszyny (pamięć, czas procesora) są w głównej mierze przeznaczane na podtrzymywanie przy życiu agentów, a nie na ich pracę.
Jak radzić sobie z tymi problemami? W celu poradzenia sobie z powyższymi problemami, trzeba zająć się poniższymi kwestiami:
Utrzymanie minimalnej liczby agentów – należy utrzymać minimalną liczbę agentów, którzy mogą generować agentów.
Ograniczenie maksymalnej liczby agentów:
  • Liczba niektórych agentów może być stała.
  • Usuwać nadmiarowych agentów:
    • Droga samolikwidacji agenta, np. poprzez energię życiową agenta zwiększaną za każdym sukcesem, a zmniejszaną z czasem oraz przez porażkę.
    • Droga likwidacji agenta przez inne agenty – należy zidentyfikować agentów, którzy są nadmiarowi:
      • Ustalić kryterium identyfikacji agentów do usunięcia.
      • Ustalić ilu agentów należy usunąć.
Np. ustalamy ilu jest agentów danego typu i ilu chcemy ich usunąć, a następnie usuwamy ich losowo lub tych z najmniejszą energią życiową.
Ograniczenie liczby generowanych agentów – można wyposażyć agenta generującego innych agentów w mechanizm określający celowość generowania nowego agenta. Mechanizm powinien uwzględniać:
  • Potrzebę generacji, która wynika z konieczności zapewnienia konkretnej funkcjonalności.
  • Ocenę możliwości generacji wynikającej z oceny chwilowej liczby agentów danego typu i potrzebnych zasobów.
Agent generujący powinien zatem obserwować otaczające go środowisko.
Koncepcja agentów bezrobotnych – można wprowadzić agentów, którzy poszukują zadań do wykonania (są bezrobotni), a następnie przekwalifikować ich w konkretny typ agenta, który może wykonać znalezione zadanie. Po wykonaniu zadania agent znowu staje się bezrobotny [2].

[2] Cetnarowicz K. – Paradygmat agentowy w Informatyce. Koncepcje, podstawy i zastosowania. Wydawnictwo Akademicka Oficyna Wydawnicza EXIT, Warszawa 2012.

Klasyfikacja systemów agentowych

Ze względu na własności środowiska, możemy rozróżnić agentów na:

  • Mobilnych agentów softwaerowych – jeśli środowisko jest cyberprzestrzenią, to agenci są agentami softwaerowymi.
  • Agentów upostaciowionych – jeśli środowisko jest przestrzenią rzeczywistą, to agenci mogą być wbudowani w roboty mobilne.

Ze względu na złożoność środowiska, którego świadomy jest agent, można wyróżnić następujących agentów:

  • Agent reaktywny – w tym przypadku środowisko zrealizowane jest w oparciu o automat skończony.
  • Agent kognitywny –  środowisko jest bardziej złożone oraz agent uwzględnia innych agentów.
  • Agent deliberatywny – środowisko jest złożone, agent dostrzega innych agentów oraz jest świadomy swego istnienia [2 str. 77-78].

[2] Cetnarowicz K. – Paradygmat agentowy w Informatyce. Koncepcje, podstawy i zastosowania. Wydawnictwo Akademicka Oficyna Wydawnicza EXIT, Warszawa 2012.