Komentáře k projektům z roku 2017/18
Vazeni studeni,
behem cteni Vasich projektu jsem narazil na par perel hodnych publikovani. Pokud se v tom najdete, berte to prosim s humorem a pokuste se nad sebou zamyslet
Zduraznuju, ze vsichni autori prisahali na validitu svych modelu.
mh
1) Passivate - kdyz je v kodu Passivate, tak tam musi byt i Activate a pasivovany proces musi byt nekde referencovany. V tomto programu se 80 procent kodu nemelo sanci nikdy vykonat, nebot byl za prikazem Passivate. Do kodu si vkladejte printf hlasky, at vidite, ze se tam program vubec kdy dostane. Pochopitelne "jeho validita byla overena experimenty".
Kdyby se kod dostal pres prvni Passivate, tak by narazil na:
...
Passivate()
...
while(pracovni_den(Time) == 1){
Passivate();
Activate(Uniform(0,8));
}
coz je dalsi zahada. Asi namisto toho Activate melo byt Wait, ale to za tim prvnim Passivate mate jedno
2) Curaci proces.
Byla potreba u zamestnance modelovat jeho pauzy na vycurani. Za tim ucelem vznikal periodicky proces, ktery dlouze cekal, az transakce zabere linku zamestnance, aby ji pak prerusil s vyssi prioritou obsluhy na moceni.
Takze linka (zamestnanec) ceka nepouzivana, zachce se ji curat, ale nejde, ceka na zakaznika a kdyz prijde, tak to propukne.
3) Semafor zpusobuje poruchy v casoprostoru
Auto projizdi krizovatkou. Kdyz behem toho prepne semafor svuj stav, tak auto zmizi.
Asi proto:
Seize(semafor);
Wait(jizda)
if (semafor.in == this) { Release(semafor); }
Transakce zabere linku, ale to neznamena, ze ji ma.
Prepnuti semaforu totiz provede:
Seize(semafor, 1);
if (semafor.Q2->Empty()==false) { semafor.Q2->getFirst()->Activate(); }
V tom okamziku transakce v nulovem case opusti system, aniz by dokoncila obsluhu.
Kdyby semafor prepinal kazdou 1ms, pak by mohla krizovatka dosahovat zavratne propustnosti.
4) 2000 let zeleznice v Presove
Simulace ukazala provoz vlaku Presov-Svidnik za 2000 let a pocet prepravenych osob. Podle studie se navratnost dotace na zrizeni spojeni vrati za 6910 roku Beru to jako vtipny komentar z oblasti verejnych investic.
Model vsak byl zajimavy tim, ze vlak zvladl na sve ceste v nulovem case dorazit do Presova, nalozit cestujici a opustit Presov. Pocet cestujicich na kazde ceste byl konstantni.
Veskera data mezi procesy se predavala prostrednictvim globalnich promennych.
5) makro a koncept strukturovaneho programovani
Nekolikaradkovy algoritmus s cyklem while jako jedno velke makro. To jsem jeste nevidel. Makro bylo vkladano na mnoha mistech programu. Procedury uz nefrci.
6) Mliko vydrzi v trubkach i nekolik dni
Kdysi jsem potkal hostinskeho, ktery mi pri toceni piva nadsene vykladal, ze ta Plzen vydrzi v trubkach i 3 a vice dni. Bylo to poznat.
Proces mliko (reprezentuje kvantum mleka) si vystoji frontu na zpracovatelskou linku, ale kdyz se k ni dostane az po pracovni dobe, uvolni tu linku, naplanuje si par dni pauzu a pak se vrati na konec fronty k lince. Jak to v tech trubkach delaji, je zahada.
7) hromadna sebevrazda
void Bottle::Pack() {
packageQueue.Insert(this);
if (packageQueue.Length() != BOTTLE_PACK) {
Passivate();
}
for (int i = 1; i BOTTLE_PACK; i++) {
packageQueue.GetFirst()->Cancel();
}
(new Group)->Activate();
}
Zamerem bylo napocitat XX vyrobenych lahvi a pak spustit proces baleni. Vsimnete si zejmena nevhodneho pouziti operatoru !=, tj. pokud by byl z libovolneho duvodu napr. packageQueue.Length() > BOTTLE_PACK, pak dale program nefunguje. Zrejme melo byt " BOTTLE_PACK".
Posledni vstoupivsi lahev NEvytahne vsechny z fronty, ale pouze BOTTLE_PACK a ty zabije.
Pritom stacil jeden integer counter.
8) Jak se da inkrementovat promenna
Uvazujme promennou a potrebu ji v urcitem okamziku inkrementovat. Za tim ucelem se musi do kalendare naplanovat udalost.
class Krmenie_siepok : public Event {
void Behavior() {
pocet_krmeni_sliepok++;
}
};
Jeste bych pochopil, kdyby se to melo naplanovat na nejaky budouci cas. Ono to vsak bylo v Activate(=Time).
9) Kohout nema pohlavi, popr. jeho pohlavi je false
Davejme objektum v programech lepe srozumitelny vyznam. Identifikator "jeSlepice" s hodnotami true (ano, je slepice) a false (ne, neni to slepice, zrejme je to kohout) davaji lepsi prehled. Taky mame typ vycet (enum).
if(Random()0.5) {
///50% sanca ze to je kohut
pohlavie = false;
} else {
///50% sanca ze to je sliepka
pohlavie = true;
sliepky++;
}
10) Novy koncept v SHO - pravdepodobnostni SHO
Uvazujme bezlinkove SHO. Proste nejsou linky, fronty apod.
Autorum se nechtelo modelovat linku, ale linku bylo treba zabirat. Proto prohlasili, ze jejich NEmodelovana linka je v okamziku potreby dostupna s jakousi pevne stanovenou pravdepodobnosti.
V cyklu si tedy hazeli minci, a kdyz jim linka vysla jako pravdepodobne zabrana, tak cekali konstantni dobu a pak experiment s minci opakovali. Zamerem bylo se vyhnout existenci jine vyroby v provozu, kterou autori modelovat nechteli.
O validite modelu se nedalo rict nic rozumneho.
11) Mame na to model
Kdyz nedate slepicim nazrat, tak uhynou. Mame na to model a experimenty to jasne dokazuji. V technicke zprave se ruzne pojmenovavala smrt slepice: slepice umrela, zahynula, uhynula. Jinak dobry.
12) Rekurzivni Behavior
Prace byla zajimava tremi aspekty:
zacinala slovem "jelikoz". To se casto nevidi.
nebyla v ni zadna linka. Byl tam fakticky jenom jeden proces, ktery aspon provadel Wait.
popis procesu v metode Behavior koncil rekurzivnim volanim Behavior. Kdyz lze snadno formulovat cyklus, vyhnete se rekurzi. Zasobnik to oceni.
13) Sklenka zive vody tesne pred smrti
Proces jako svuj posledni prikaz metody Behavior() provede Activate(). Predpokladam zamerem bylo ho po jeho ukonceni znovu spustit. To se nestalo a autori to ani nemeli potrebu overovat.
Fakt se hodi si podobne konstrukce overit logovacimi hlaskami.
Activate() u procesu (!!!) ma nasledujici semantiku:
zapise zaznam o aktivaci do kalendare,
pokud je to aktivace sebe sama (divne, ale proc ne), tak se proces prerusi.
Fakticky se proces v tomto pripade naplanuje na cas Time, prerusi, znovu obnovi za prikazem Activate(), a jelikoz byl poslednim prikazem Behavior(), proces opousti Behavior a tim ZANIKA.
Vidam casto jako posledni prikaz procesu prikaz Passivate(). Tam si reknu, eh co, studenti proste chteji nechat mrtvy proces v pameti, protoze pameti mame dost. Proc riskovat uvolnovani pameti, na tom se zbytecne pada.
14) copy-paste je metoda extensivniho programovani
Uvazujme dva procesy: maly traktor a velky traktor. Kazdy ma svoje chovani. Kdyz je srovnate, zjistite, ze se lisi v jedne jedine konstantne: transportni kapacite traktoru. Copy-paste vsak dava dalsi radky kodu a to se hodnoti.
15) Minimalizmus jako umelecky smer
class PaletaOdvoz : public Process
{
void Behavior() { // popis chování dilu
double Prichod=Time;
Tabulka(Time-Prichod); // doba obsluhy a čekání
}
};
V modelu bylo 24 procesu, z toho 6 tohoto minimalistickeho formatu. Jejich pouziti bylo nasledujici:
OdvozPaleta.Insert(new PaletaOdvoz);
if(OdvozPaleta.Length() == 8)
{
for (int i = 0; i 8; i++)
{
OdvozPaleta.GetFirst()->Activate();
}
(new PrepravaAuto)->Activate();
}
Instanciaci PaletaOdvoz vznikne objekt-proces, ktery se ovsem neaktivuje. Az se jich ve fronte nasbira 8, tak se tyto vsechny aktivuji (tzn. spusti se Behavior a v zapeti ukonci).
Ne, rozhodne by tuto funkcionalitu nezajistil jeden citac typu integer.
Vsech 24 procesu zapisuje do histogramu Tabulka. Tabulka se neexportuje a zrejme v modelu nema zadny vyznam. Asi relikt copy-pastingu.
16) on si nestoupne do fronty, ho do te fronty stoupnout proste nedonutite. Fronty v SHO jsou zlo.
if(Ramp.Full()) {
WaitUntil(!Ramp.Full());
}
double time = Time;
Enter(Ramp, 1);
Vtipne je, ze vsechny procesy ve WaitUntil naraz opusti WaitUntil a vlezou si do fronty Ramp. Nad smyslem teto konstrukce muzeme vahat.
17) "cokolada ma prednost pred poruchou", sic, to je citace zpravy
proces cokolada zabiral linku s vysokou prioritou obsluhy a dle potreby vyhazoval z obsluhy veskere servisni cinnosti.
18) chytit a nepustit
Uvazujme:
Enter(zam, 1)
Wait(objednavka);
Leave(zam, 1);
Enter(pec, 4);
Enter(zam, 1);
Transakce zabere zamestnance a vyridi objednavku. Pak ho propusti a testuje dostupnost pece. Az dostane kapacitu, tak si zacne shanet zamestnance.
V dusledku to znamena, ze transakce vyridi objednavku, ale pokud ve fronte na zamestnance nekdo stoji, pak i pres dostupnou kapacitu pece je prerusena a musi si vycekat znovu-uvolneni zamestnance.
19) Gigamesto Bratislava
Model predpoklada zalidnenost Bratislavy 1160 lidi na metr ctverecny. V indickem Dilli na tom byli osmkrat hur. Nastesti ten pocet nebyl stanoven na metr kubicky, to by totiz hustota latky dosahovala hustoty neutronove hvezdy.
Ale jak rikala moje slovenska babicka, dobrych ludi sa zmesti neurekom.
20) Tohle bylo v programu opakovane. Perlicka pro milovniky exceptions. Opravdu vas snazne prosim, piste programy, ktere davaji smysl
double bandwidth;
for(;;)
{
cout "Server max. bandwidth [Mbps]: ";
cin >> input;
try
{
bandwidth = stod(input);
if (bandwidth 10)
{
throw 1;
}
}
catch (...)
{
cerr "Invalid input\n";
continue;
}
break;
}
21) Bez exponencialniho rozlozeni by to nefungovalo.
Cinnost XY ma zjevne trvat asi 5 hodin (jeden by rekl 5 hodin plus minus par minut). Tak aby to vypadalo vic vedecky, dame exp(5 hodin), tj. napr. 2 hodiny, 12 hodin, 8 hodin...
22) Lustime rebusy
uvazujme dve promenne typu unsigned. Co ma znamenat nasledujici kod?
WAITED += CREAM_STORED;
CREAM_STORED -= WAITED;
Dejme tomu WAITED=2, CREAM=3. Pak prvni prikaz WAITED = WAITED + 3 => WAITED=5.
Druhy prikaz CREAM = CREAM (3) - 5, zaporne cislo, v unsigned zustane nejaka blbost.
Vidam ve vasich programech unsigned hodne casto. Proc ne, ale kdyz od promenne unsigned odcitate, zkuste nad tim vic premyslet. V budoucnu se to fakt vyplati.
23) Dodavatelsko-odberatelske vztahy
Za socializmu to byl znacny problem. Ve vyrobnim retezci byly nespolehlive dodavky surovin, tudiz nemohla jet vyroba, tudiz navazujici clanek retezu nemohl navazat. Celek nefungoval.
Tak si predstavme fabriku na zpracovani mleka. Farmar kazde rano vstane (ve stejnou dobu), podoji kravky a pak veze mliko do fabriky, kam dorazi kazdy den plus minus ve stejnou dobu. V modelu vsak mame intervaly exp(8 hodin). Validita je vsak nepochybna.
24) Vyroba orezana kapacitou stroju
Dovezli mliko. Mliko, na ktere se v dany okamzik nedostala kapacita stroju, opoustelo system. Proste nejak preteklo a odteklo. Nekam.
25) Genocida v kravine
System obsahoval proces, ktery periodicky zabijel kravy v kravine. Vybral par krav a zabil je. Pokud vybrana krava byla zrovna "tehotna", pak proces nejprve zabil kravu a nasledne pak i jeji "tehotenstvi". V rimskych legiich se tomu rikalo decimace :)
26) Geograficky limitovana validita modelu
"Nas model je validni predevsim v ceskem prostredi".
27) Poruchu ocekavame a jsme na ni dobre pripraveni
Porucha se do systemu generovala periodicky kazdych 300 dni na sekundu presne.
Porucha si stoupla do front vsech zarizeni a vyckala, az se na nich dodela prace.
Kazdy vyrobak by skakal nadsenim, kdyby poruchy v jeho provozu mely tento charakter. Mozna tim byla minena pravidelna planovana servisni odstavka.
28) Holky, kde jste?
Proces Krava se rozhlidne po kravine, a kdyz uvidi volna mista, tak je zaplni nove vygenerovanymi dalsimi kravami. Je ovsem striktne konzervativni, nebot generuje pouze kravy sveho plemene.
29) Co na to rict?
for (unsigned i = 0; true; i++) { // dojicka se ujme kravky
if (i == pocetDojicek) {
i = 0;
Wait(1);
}
if(!Dojicka[i].Busy() & pracujeSe(Time) & !praveDodojene & !cekajiciNaUdrzbu & !karantena){
Seize(Dojicka[i]);
break;
}
}
Link to this Page