Pivovar Chmelokvas KIV/PT Semestrální práce student: Petr Neužil studijní číslo: P13B0377P email: syberij@students.zcu.cz datum: 15.12.2014
Standardní zadání semestrální práce pro PT 2014/2015 Zadání je určeno pro dva studenty. Práce zahrnuje dvě dílčí části - vytvoření funkčního programu diskrétní simulace a napsání strukturované dokumentace. Zadání: Pivovar "Chmelokvas" zásobuje pivem území o rozloze 500x500km a nachází se přibližně v centrální části. Pivovar je schopen vyprodukovat maximálně 7000hl piva za den. Na území se nachází celkem 4000 hospod, které musí být neustále zásobeny pěnivým mokem. 5% hospod točí pivo z tanku, ostatní používají sudové pivo. Vzdálenost mezi hospodami je minimálně 2km. Z pivovaru je pivo nejdříve rozvezeno kamiony do 8 překladišť, které pak distribuují pivo nákladními vozy do jednotlivých hospod. Hospody s tankovým pivem jsou zásobovány malými cisternami přímo z pivovaru. Každé překladiště zásobuje území o minimální rozloze 80x80km a vzdálenost mezi překladišti je minimálně 100km. Žádné překladiště se nenachází v centrální oblasti. Z každého překladiště vede přímá cesta do 50 hospod. Každá hospoda je spojena silnicí s 15 nejbližšími hospodami. Kamiony jezdí průměrnou cestovní rychlostí 90km/h a jsou schopny pojmout maximálně 100 sudů. Cisterny jsou schopny přepravit 50hl piva a jezdí průměrnou rychlostí 60km/h. Každé překladiště je schopno pojmout maximálně 2000 sudů. Každý nákladní vůz je schopen pojmout 30 sudů. Průměrná rychlost nákladního vozu je 70km/h. Hospoda spotřebuje 1 až 6 sudů piva denně, pokud využívá sudové pivo respektive 1-6hl piva, pokud točí pivo z tanku (viz pravděpodobnosti uvedené níže). Naložení/vyložení jednoho sudu trvá 5 minut a načerpání/přečerpání jednoho hektolitru piva 2 minuty. Pivo je nutné dovézt do 24 hodin od doby objednávky. Doba objednávky se řídí normálním rozdělením pravděpodobnosti. Nejvíce objednávek chodí kolem 10h dopolední. Objednávky lze podávat v době od 8:00 do 16:00. Rozvoz piva probíhá ve stejném čase jako příjem objednávek. Nákladní automobily samozřejmě svážejí prázdné sudy zpět do překladišť a z nich jsou sváženy kamiony zpět do pivovaru na naplnění. Počet kamionů, nákladních aut a cisteren není omezen. Cílem je simulovat a řídit provoz zásobování hospod tak, aby každé hospodě dorazilo objednané pivo do 24h od objednání. Vzhledem k nenasytnému obyvatelstvu a cenám zdrojů je třeba, aby náklady na převoz piva byly minimalizovány. Vytvoření funkčního programu: Připravte rozumná vstupní data (hospody, silnice, překladiště, pivovar, vzdálenosti) a uložte je ve vhodném formátu (10b.), zvolte a implementujte vhodné datové struktury pro reprezentaci vstupních dat, důsledně zvažujte paměťovou náročnost zvolených struktur a časovou náročnost algoritmů pro následovné výpočty (10b.), proveďte základní simulaci pro první den, vypište, která hospoda je zásobována z kterého překladiště, v jakém čase a množství, průběh simulace (všechny důležité hodnoty) zapisujte na obrazovku a do souboru (10 b.). Výše popsaná část bude váš minimální výstup při kontrolním cvičení cca v polovině semestru.
Vytvořte prostředí pro snadnou obsluhu programu (menu, ošetření vstupů) - nemusí být grafické, umožněte manuální zadání objednávky (5b.) umožněte sledování (za běhu simulace) aktuálního stavu zásobování hospody a sledování aktuálního stavu přepravního prostředku nákladního vozu, kamionu či cisterny (5b.), proveďte simulaci pro 7 dnů a vygenerujte do souborů následující statistiky (uložte je do vhodných souborů 10b.): o přehled jednotlivých hospod s uvedením zavezeného objemu/množství piva rozepsané do jednotlivých dnů, v rámci dnů pak rozepsané dle jednotlivých nákladních vozů či cisteren, které na místo dorazily. Na konci uveďte souhrnná čísla za celou dobu simulace a za každé tři dny simulace o přehled jednotlivých nákladních vozů, kamionů a cisteren s uvedením jejich jednotlivých cest, zavezeného piva a svezených prázdných sudů, na konci uveďte souhrnná čísla za celou simulaci vytvořte dokumentační komentáře ve zdrojovém textu programu a vygenerujte programovou dokumentaci (Javadoc) (10b.), vytvořte kvalitní dále rozšiřitelný kód pro kontrolu použijte softwarový nástroj PMD (více na http://www.kiv.zcu.cz/~herout/pruzkumy/pmd/pmd.html), soubor s pravidly pdmrules.xml najdete na portálu v podmenu Samostatná práce (10b.) o mínus 1 bod za vážnější chybu, při 6 a více chybách nutno opravit, o mínus 2 body za 10 a více drobných chyb. V rámci dokumentace: připojte zadání (1b.), popište analýzu problému (6b.), popište návrh programu (např. jednoduchý UML diagram) (6b.), vytvořte uživatelskou dokumentaci (5b.), zhodnoťte celou práci, vytvořte závěr (2b.). Poznámky: Příslušná data (hospody, silnice, překladiště, pivovar) si vygenerujte. Simulaci rozvozu piva simulujte po dobu sedmi dnů (7*24 hod) po hodinách. Počet vozidel sice není omezen, vozidla ale samovolně nezanikají. Vozidla se po vyložení celého nákladu vrací nejkratší cestou zpět do depa a po vyložení svezených sudů jsou připravena na další jízdu. Začínáte v čase 0:00 prvního dne, předpokládejte, že v tomto čase je na každém překladišti připraveno 2000 sudů k dalšímu rozvozu. Pravděpodobnostní rozdělení počtu spotřebovaných sudů/hl na den: 1 25% 2 25% 3 20% 4 15% 5 10% 6 5%
Analýza problému Úkolem je vytvořit program, který umožní simulování provozu pivovaru. Konkrétně zásobování jednotlivých hospod na vygenerované mapě. Nejprve je třeba vytvořit mapu hospod a překladišť podle zadaných podmínek - omezení minimálních vzdáleností mezi hospodami a také překladišti. V tomto programu je vše řešené pomocí pole 500x500, což je velikost celé mapy. Při každém přidání hospody se v okruhu 2km zaplní místa tak, aby nebylo možné přidat jinou hospodu. Jinak probíhá generování umístění nové hospody náhodně. Překladiště a pivovar jsou umístěny ručně tak, aby splňovali podmínky zadání. Dále je nutné vytvořit cesty a spojit každou hospodu s 15 nejbližšími. K nalezení 15 nejbližších sousedů je nutné nejprve určit vzdálenosti a poté najít 15 nejnižších hodnot. Toto je řešené pomocí grafu. Graf je procházen pomocí Dijkstrova algoritmu z důvodu minimalizování času generování. Pokud bychom použili například obyčejné prohledávání do šířky, časová náročnost by se u tak velkého grafu razantně zvedla. Po vytvoření grafu cest si určíme vzdálenosti mezi všemi budovami na mapě. Znovu je použit Dijkstrův algoritmus z důvodu menší časové náročnosti. Na konci celého generování vznikne více souborů, programu však ke správné funkčnosti stačí pouze dva uzemi.txt a vzdalenosti.txt. Z názvů je patrné, že první zmiňovaný obsahuje informace o všech budovách na mapě. Druhý soubor obsahuje vzdálenosti mezi všemi budovami. Oba tyto soubory jsou načteny na začátku programu. Prvním problémem v samotné simulaci chodu je generování objednávek. Pro tuto činnost je použito dvojrozměrné pole objednávek, kdy první souřadnice určuje den objednávky a druhá číslo objednávky. Funkce zamichejpole v třídě Aplikace zajišťuje, že objednávky přijdou každý den v jiném pořadí. Dalším problémem je vyřízení objednávky. Program určí potenciální vzdálenosti již existujících vozidel a pokud ani jedno z nich nestihne do 16 hodin dorazit na místo určení, vytvoří se nové vozidlo v nejbližším překladišti/pivovaru. Naloží maximální počet sudů, co může a vydá se na cestu. Ke zbývající vzdálenosti vozidla se připočte i čas za nakládání/vykládání/přečerpání. Objednávka je v tu dobu považována za vyřízenou. Pokud se nepodaří vyslat žádné vozidlo, objednávka toho dne se nastaví jako vyřízená, ale další den se připočte k nové objednávce staré množství. Tím je zajištěno doručení každé objednávky. Pokud se v hospodě nachází prázdné sudy, nákladní auto je naloží a odveze zpět na překladiště. Odtud jsou vozeny kamiony zpět do pivovaru, pokud se zde nějaký kamion nachází. Dalším problémem je zajištění toho, aby se vozidla po 16. hodině nebo pokud jsou prázdná vracela do překladiště/pivovaru. Vše je řešené jednoduchou podmínkou v metodě dostep třídy Aplikace pro jednotlivé typy vozidel. Posledním problémem bylo generování statistik. Bylo nutné vytvořit nové pole třídy Cesty a zde zaznamenávat všechny informace o jednotlivých cestách všech vozidel. Zejména vykládání prázdných sudů, které by jinak bylo nedohledatelné vzhledem k návrhu programu a nepřítomnosti sudů jako objektů. Celý program je řešen hlavně ve třídě aplikace, která tak spojuje ostatní třídy. Všechny posuny jsou řešené v metodě dostep, která obstarává jak posun času, tak pohyb vozidel. Zároveň je zde každý nový den tzv zamícháno pole objednávek.
UML Diagram
Uživatelská dokumentace Program rovnou při spuštění začne v čase 0:00 prvního dne a zobrazí tyto základní informace. Pokud zadáme h nebo n, zobrazí se seznam se všemi možnými příkazy. Pro krok v programu stačí stisknout ENTER či zadat jakýkoliv řetězec, kromě zmíněných v nápovědě. Jednotlivé příkazy: Příkaz o Pokud nejsme v čase 8-16 zobrazí se hláška, že nelze zadávat objednávky. V tomto případě lze jen zjišťovat informace o již zadaných objednávkách tohoto dne, pokud zadáme platné ID hospody. Výsledkem je buď hláška, že hospoda nemá objednáno Nebo požadované informace Pokud zadáme o v době, kdy lze objednávat, tak může dojít ke dvěma situacím. Hospoda již má objednáno, v tom případě dostaneme informace o její objednávce: Nebo nám je nabídnuto zadat ruční objednávku. Pokud zadáme číslo, dojde k objednávce, při zadání čehokoliv jiného dojde ke STORNOvání zadávání a k objednávce nedojde Došlo k objednávce: Nedošlo k objednávce:
Příkazy b a v Při zadání jednoho z těchto příkazů se nás program zeptá na ID budovy nebo vozidla, které chceme vypsat, možné výstupy jsou buď informace o budově/vozidle (v případě zadání existujícího ID) nebo hláška o špatném vstupu (v případě zadání neexistujícího ID nebo čehokoliv jiného) Při dokončení simulace začne generování výstupu. Pokud je proměnná Pocet_hospod nastavena na velké číslo je třeba mít při generování trpělivost a počkat na oznámení KONEC SIMULACE Konečný výstup lze nalézt v souborech statistika_hospod*datum A CAS*.csv statistika_vozidel*datum A CAS*.csv Jako oddělovač je použit znak ^ Hodnocení a závěr Podařilo se mi splnit hlavní úkol, i přesto, že kód programu je velice nepřehledný a díky tomu, že se program snaží o doručení všech objednávek ještě ten samý den, je generováno větší množství aut, než by bylo potřeba. V programu je elegantně vyřešené hledání cesty, kdy místo toho, aby vozidlo pokaždé hledalo podle cest nejkratší cestu, už ji dopředu zná a tím se výrazně snižuje časová náročnost při simulaci. Prostor pro zlepšení je každopádně ve zpřehlednění kódu, předělání návrhu programu tak, aby se více užívalo metod jiných tříd, než třídy Aplikace. Dále by bylo možné přesouvat objednávky na další den a tím eliminovat některá vozidla, která jedou jen jednou během simulace, ale vzhledem k tomu, že takových vozidel je velmi malý počet funkčnost je zcela zachována. A v neposlední řadě by bylo vhodné mít generátor i aplikaci v jednom balíku. Celkově se dá říct, že se podařilo splnit zadání semestrální práce.