Próbuję rozwiązać następujące ćwiczenie, ale tak naprawdę nie mam pojęcia, jak zacząć to robić. W mojej książce znalazłem kod, który wygląda tak, ale jest to zupełnie inne ćwiczenie i nie wiem, jak je ze sobą powiązać. Jak rozpocząć symulowanie przylotów i skąd mam wiedzieć, kiedy są one ukończone? Wiem, jak je przechowywać i obliczyć odpowiednio a, b, c, d. Ale nie wiem, jak mam symulować symulację Monte Carlo. Czy ktoś mógłby mi pomóc zacząć? Wiem, że nie jest to miejsce, w którym otrzymujesz odpowiedzi na twoje pytania, ale tylko rozwiązane. Problem w tym, że nie wiem jak zacząć.
Dział pomocy technicznej IT reprezentuje system kolejkowania z pięcioma asystentami odbierającymi połączenia od klientów. Połączenia odbywają się zgodnie z procesem Poissona ze średnią szybkością jednego połączenia co 45 sekund. Czasy obsługi dla 1., 2., 3., 4. i 5. asystenta to wszystkie wykładnicze zmienne losowe o parametrach λ1 = 0,1, λ2 = 0,2, λ3 = 0,3, λ4 = 0,4 i λ5 = 0,5 min − 1, odpowiednio ( jth asystent pomocy technicznej ma λk = k / 10 min − 1). Oprócz klientów objętych pomocą można wstrzymać do dziesięciu innych klientów. W chwili osiągnięcia tej pojemności nowi dzwoniący otrzymują sygnał zajętości. Użyj metod Monte Carlo, aby oszacować następujące parametry wydajności,
(a) część klientów, którzy otrzymują sygnał zajętości;
(b) oczekiwany czas reakcji;
(c) średni czas oczekiwania;
(d) część klientów obsługiwanych przez każdego asystenta pomocy technicznej;
EDYCJA: to, co do tej pory mam (niewiele):
pa = 1/45sec-1
jobs = rep(1,5); onHold = rep(1,10);
jobsIndex = 0;
onHoldIndex = 0;
u = runif(1)
for (i in 1:1000) {
if(u <= pa){ # new arrival
if(jobsIndex < 5) # assistant is free, #give job to assistant
jobsIndex++;
else #add to onHold array
onHoldIndex++;
}
}
źródło
Odpowiedzi:
Jest to jeden z najbardziej pouczających i zabawnych rodzajów symulacji do wykonania: tworzysz niezależnych agentów na komputerze, pozwalasz im na interakcję, śledzisz, co robią, i analizujesz, co się dzieje. Jest to cudowny sposób na poznanie złożonych systemów, zwłaszcza (ale nie tylko) tych, których nie można zrozumieć za pomocą analizy czysto matematycznej.
Najlepszym sposobem na zbudowanie takich symulacji jest projektowanie od góry w dół.
Na najwyższym poziomie kod powinien wyglądać mniej więcej tak
(Ten i wszystkie kolejne przykłady to kod wykonywalny
R
, a nie tylko pseudo-kod.) Pętla jest symulacją sterowaną zdarzeniami :get.next.event()
znajduje dowolne „zdarzenie” będące przedmiotem zainteresowania i przekazuje jego opisprocess
, który coś z nim robi (w tym rejestrowanie dowolnego informacje na ten temat). PowracaTRUE
tak długo, jak wszystko działa dobrze; po zidentyfikowaniu błędu lub zakończeniu symulacji wracaFALSE
, kończąc pętlę.Jeśli wyobrażamy sobie fizyczną implementację tej kolejki, na przykład osoby czekające na prawo jazdy w Nowym Jorku lub prawo jazdy lub bilet kolejowy prawie wszędzie, myślimy o dwóch rodzajach agentów: klientów i „asystentów” (lub serwerów) . Klienci ogłaszają się, pokazując się; asystenci ogłaszają swoją dostępność, włączając światło, znak lub otwierając okno. Są to dwa rodzaje zdarzeń do przetworzenia.
Idealnym środowiskiem do takiej symulacji jest środowisko zorientowane obiektowo, w którym obiekty są zmienne : mogą zmieniać stan, aby reagować niezależnie na otaczające je rzeczy.
R
jest do tego absolutnie okropny (nawet Fortran byłby lepszy!). Możemy jednak nadal z niego korzystać, jeśli zachowamy ostrożność. Sztuką jest utrzymanie wszystkich informacji we wspólnym zestawie struktur danych, do których można uzyskać dostęp (i je zmodyfikować) za pomocą wielu oddzielnych, oddziałujących na siebie procedur. Przyjmę konwencję używania nazw zmiennych WSZYSTKIMI KAPITAMI dla takich danych.Kolejnym poziomem odgórnego projektu jest kodowanie
process
. Odpowiada na pojedynczy deskryptor zdarzeniae
:Musi reagować na zdarzenie zerowe, gdy
get.next.event
nie ma żadnych zdarzeń do zgłoszenia. W przeciwnym razieprocess
implementuje „reguły biznesowe” systemu. Praktycznie pisze się z opisu w pytaniu. To, jak to działa, powinno wymagać niewielkiego komentarza, z wyjątkiem zaznaczenia, że w końcu będziemy musieli kodować podprogramyput.on.hold
irelease.hold
(wdrażanie kolejki obsługującej klientów) iserve
(wdrażanie interakcji klient-asystent).Co to jest „wydarzenie”? Musi zawierać informacje o tym, kto działa, jaki rodzaj działania podejmuje i kiedy ma miejsce. Mój kod wykorzystuje zatem listę zawierającą te trzy rodzaje informacji. Jednakże,
get.next.event
tylko musi sprawdzać czasy. Odpowiada tylko za utrzymanie kolejki zdarzeń, w którejKażde zdarzenie może zostać umieszczone w kolejce po jego odebraniu i
Najwcześniejsze zdarzenie w kolejce można łatwo wyodrębnić i przekazać dzwoniącemu.
Najlepszą implementacją tej kolejki priorytetowej byłaby kupa, ale to jest zbyt wybredne
R
. Zgodnie z sugestią w The Art of R Programming Normana Matloffa (który oferuje bardziej elastyczny, abstrakcyjny, ale ograniczony symulator kolejek), użyłem ramki danych do przechowywania zdarzeń i po prostu przeszukiwania go w celu znalezienia minimalnego czasu wśród jego rekordów.Można to zakodować na wiele sposobów. Ostateczna wersja pokazana tutaj odzwierciedla wybór, którego dokonałem przy kodowaniu, jak
process
reaguje na zdarzenie „Asystent” i jaknew.customer
działa:get.next.event
po prostu usuwa klienta z kolejki wstrzymania, a następnie siada i czeka na kolejne zdarzenie. Czasami konieczne będzie poszukiwanie nowego klienta na dwa sposoby: po pierwsze, aby sprawdzić, czy ktoś czeka (przy drzwiach), a po drugie, czy ktoś wszedł, gdy nie patrzyliśmy.Oczywiście,
new.customer
inext.customer.time
to ważne rutyny , więc niech się nimi zająć w przyszłym.CUSTOMERS
to tablica 2D z danymi dla każdego klienta w kolumnach. Ma cztery wiersze (działające jak pola), które opisują klientów i rejestrują ich doświadczenia podczas symulacji : „Przybył”, „Obsługiwany”, „Czas trwania” i „Asystent” (dodatni identyfikator numeryczny asystenta, jeśli taki był, który służył je, a poza tym-1
dla sygnałów zajętości). W bardzo elastycznej symulacji kolumny te byłyby generowane dynamicznie, ale ze względu na to, jakR
lubi pracować, wygodnie jest wygenerować wszystkich klientów na początku, w jednej dużej matrycy, a czasy ich przybycia są już generowane losowo.next.customer.time
może zajrzeć do następnej kolumny tej macierzy, aby zobaczyć, kto będzie następny. Zmienna globalnaCUSTOMER.COUNT
wskazuje ostatniego klienta, który przybył. Klientami zarządza się bardzo prosto za pomocą tego wskaźnika, przesuwając go w celu pozyskania nowego klienta i spoglądając poza niego (bez przechodzenia), aby zerknąć na następnego klienta.serve
implementuje reguły biznesowe w symulacji.To jest proste.
ASSISTANTS
to ramka danych z dwoma polami:capabilities
(podająca stawkę usługi) iavailable
, która oznacza następny czas, w którym asystent będzie wolny. Klient jest obsługiwany przez generowanie losowego czasu trwania usługi zgodnie z możliwościami asystenta, aktualizowanie czasu, kiedy asystent będzie następny dostępny, i rejestrowanie interwału usługi wCUSTOMERS
strukturze danych.VERBOSE
Flaga jest przydatny do testowania i debugowania: gdy prawdziwe, to emituje strumień angielskich zdań opisujących kluczowych punktów przetwarzania.Sposób przydzielania asystentów do klientów jest ważny i interesujący. Można sobie wyobrazić kilka procedur: losowe przydzielanie, pewne stałe porządkowanie lub według tego, kto był wolny najdłużej (lub najkrócej). Wiele z nich zostało zilustrowanych w skomentowanym kodzie:
Reszta symulacji to tak naprawdę zwykłe ćwiczenie polegające na przekonaniu
R
do wdrożenia standardowych struktur danych, głównie okrągłego bufora dla kolejki wstrzymania. Ponieważ nie chcesz uruchamiać amoku z globalsami, umieściłem je wszystkie w jednej procedurzesim
. Argumenty opisują problem: liczbę klientów do symulacji (n.events
), wskaźnik przybycia klientów, możliwości asystentów i wielkość kolejki wstrzymania (którą można ustawić na zero, aby całkowicie wyeliminować kolejkę).CUSTOMERS
R
Doświadczenie każdego klienta jest wykreślane jako pozioma linia czasu, z okrągłym symbolem w momencie przybycia, ciągła czarna linia dla każdego oczekującego oczekiwania i kolorowa linia na czas interakcji z asystentem (kolor i rodzaj linii rozróżniać asystentów). Pod spiskiem Klientów znajduje się fabuła pokazująca doświadczenia asystentów, oznaczająca czasy, w których byli i nie byli zaangażowani z klientem. Punkty końcowe każdego przedziału aktywności są ograniczone pionowymi paskami.
Po uruchomieniu z
verbose=TRUE
tekstem symulacji wygląda następująco:Możemy badać doświadczenie klientów zawieszonych, wykreślając czasy oczekiwania według identyfikatora klienta, używając specjalnego (czerwonego) symbolu, aby pokazać klientom odbierającym sygnał zajętości.
(Czy wszystkie te wykresy nie byłyby wspaniałym pulpitem nawigacyjnym w czasie rzeczywistym dla każdego, kto zarządza tą kolejką usług!)
Porównywanie wykresów i statystyk, które uzyskujesz po zmianie parametrów, jest fascynujące
sim
. Co się stanie, gdy klienci pojawią się zbyt szybko, aby je przetworzyć? Co się stanie, gdy kolejka wstrzymania zostanie zmniejszona lub wyeliminowana? Jakie zmiany, gdy asystenci są wybierani na różne sposoby? Jak liczba i możliwości asystentów wpływają na doświadczenie klienta? Jakie są krytyczne punkty, w których niektórzy klienci zaczynają się odwracać lub zaczynają być zawieszani na długi czas?Zwykle w przypadku oczywistych pytań do samodzielnego studiowania, takich jak to, zatrzymalibyśmy się tutaj i pozostawiliśmy pozostałe szczegóły jako ćwiczenie. Nie chcę jednak zawieść czytelników, którzy mogli zaatakować tak daleko i są zainteresowani wypróbowaniem tego na własną rękę (i być może modyfikacją i rozbudowaniem go do innych celów), dlatego poniżej znajduje się pełny działający kod.
źródło
R
którzy chcą nowej (ale dość podobnej) perspektywy na symulacje kolejek. Pisząc ten mały symulator, dużo myślałem o tym, czego się nauczyłem, studiując kod w (pierwszym wydaniu) tekstu Andrzeja Tanenbauma Systemy operacyjne / Projektowanie i implementacja. Dowiedziałem się także o praktycznych strukturach danych, takich jak stosy, z artykułów Jona Bentleya w CACM i jego serii książek Programming Pearls . Tanenbaum i Bentley to wspaniali autorzy, których każdy powinien przeczytać.