Table of Contents
Górski punkt wycieczkowy organizuje wycieczki w góry o T>=1 stopniach trudności. Wycieczki prowadzą przewodnicy. Każdy przewodnik ma uprawnienia wyrażone liczbą od 1 do T, przy czym przewodnik o uprawnieniach t może kierować wycieczką o trudności nie większej niż t. Dla każdego 1<=t<=T jest co najmniej jeden przewodnik o uprawnieniach t.
Liczność grupy zależy od stopnia trudności wycieczki: na wycieczkę o trudności t może wyjść grupa od GMIN(t) do GMAX(t) (włącznie) uczestników i dokładnie jeden przewodnik. Wiadomo przy tym, że dla każdego t GMIN(t)<=t<=GMAX(t).
Uczestnik cyklicznie wykonuje WŁASNE SPRAWY, losuje poziom trudności kolejnej wycieczki (funkcja LOSUJ(T)) i, być może po oczekiwaniu na grupę i/lub przewodnika, wraz z grupą i przewodnikiem wybiera się na wycieczkę (procedura WYCIECZKA(nr_przewodnika :integer)).
Przewodnik cyklicznie wykonuje WŁASNE_SPRAWY, zgłasza się do pracy, zabiera na wycieczkę pewną skompletowaną (o liczności>=GMIN(t)) grupę, wybierając przy tym wycieczkę o największej trudności, spośród tych, które jest w stanie poprowadzić. Jeśli żadna grupa nie jest gotowa lub przewodnik nie ma wystarczających uprawnień, to przewodnik musi poczekać.
Gdy zbierająca się grupa osiągnie liczność GMIN(t) i czeka pewien przewodnik o uprawnieniach>=t, to jest budzony przewodnik o najniższych dostatecznych uprawnieniach spośród oczekujących przewodników. Zabiera on grupę na wycieczkę (procedura WYCIECZKA).
Po zakończeniu wycieczki każdy przewodnik i uczestnik (bez synchronizacji z innymi) rozpoczyna ponownie wykonanie WŁASNYCH_SPRAW. Zapisz treść procesów Przewodnik(nr: integer; upr: 1..T) i Uczestnik, używając do synchronizacji semaforów ogólnych i/lub binarnych. Parameter nr jest unikatowym numerem przewodnika, a upr określa jego uprawnienia. Pamiętaj o zainicjowaniu wszystkich zmiennych.
Rozwiązanie:
var przewodnik: array[1..T] of binary semaphore := {T times 0}; l_cz_przewodnikow: array[1..T] of integer := {T times 0}; uczestnik: array[1..T] of binary semaphore := {T times 0}; l_cz_uczestnikow: array[1..T] of integer := {T times 0}; gotowa_grupa: integer; przewodnik_id: integer; liczba_do_wpuszczenia: integer; process wycieczka_przewodnik(id: integer, stopien: integer) var i; begin P(ochrona); for i=stopien downto 1 do begin if (l_cz_uczestnikow>=GMIN(i)) then begin gotowa_grupa:=i; break end; end; if (gotowa_grupa=0) then begin l_cz_przewodnikow[stopien]++; V(ochrona); P(przewodnik[stopien]); l_cz_przewodnikow[stopien]--; end; przewodnik_id := id; liczba_do_wpuszczenia := MIN(l_cz_uczestnikow[gotowa_grupa], GMAX(gotowa_grupa)); if (liczba_do_wpuszczenia>0) V(uczestnik[gotowa_grupa]); else V(ochrona); end; process wycieczka_uczestnik(var id: integer, stopien: integer) var i: integer; st_przewodnik: integer := 0; begin P(ochrona); l_cz_uczestnikow[stopien]++; if (l_cz_uczestnikow[stopien]>=GMIN(stopien)) then begin for i:=stopien to T do begin if (l_cz_przewodnikow[i]>0) then begin st_przewodnik:=i; break; end; end; end; if (st_przewodnik!=0) then begin gotowa_grupa := stopien; V(przewodnik[st_przewodnik]); end; else V(ochrona); P(uczestnik[stopien]); id := przewodnik_id; l_cz_uczestnikow[stopien]--; liczba_do_wpuszczenia--; if (liczba_do_wpuszczenia>0) V(uczestnik[stopien]); else V(ochrona); end;