One day in the life of a restaurant model
This article describes the new components of the framework for simulation, previously presented in the article “A Simple System of Simulation on Go” . As the framework expanded, it became possible to model more complex systems, for example, to simulate the work of a restaurant.
There are several new components: Bifacility , Split , Aggregate , Count , Assign , Check . Let's consider them in more detail.
Bifacility is essentially the same as Facility , but its purpose is to make the transaction take up not a single component for a while, but a chain of components. For this, the Bifacility constructor forms two components - IN and OUT. After a transaction enters the IN component, Bifacility is considered busy and another transaction can no longer take it. When a transaction hits the OUT component, Bifacility is freed and now another transaction can take it. To freeBifacility can only transaction that occupied it. The simplest analogy of Bifacility can be considered a technological installation that performs a number of operations on one part. Until the part leaves the installation, it is impossible to send another part to it.
Split - a component designed to split a transaction into parts - other transactions processed in parallel in the future. For example, if we consider a transaction as an order, then its parts are positions in the order. By default, in the absence of any parameters, Splitdivides the resulting transaction by an amount equal to the components after it. It is possible to specify how many parts and with which modifier (to generate a random value) the partition will be performed. Since in practice it may be required that the splitting into parts is carried out according to some law, in Split there is the opportunity to connect your own handler for splitting.
In tandem with the Split goes the Aggregate , as the name implies, it aggregates a number of TRANSACT one. Its functionality is quite simple, having received any of the parts of a previously broken transaction, it waits for all the other parts and, after receiving them, sends the transaction further.
Count - component for counting. Constructor Countforms two components - INC and DEC. When a transaction enters INC, the Count counter increases; when it enters a DEC, it decreases. In the constructor of Count, values are set by which the counter increases and decreases when it enters INC and DEC, respectively.
Assign - designed to set some transaction parameter. A transaction has a list of parameters, each parameter has a name and a value. The value can be a string, number, structure. When assigning nil to a parameter, it is removed from the list.
Check - a component designed to verify the fulfillment of a certain condition and skips a transaction only when it is executed. By default, the equality of the transaction parameter to the specified value is checked. In the constructor of CheckYou can specify the block to which the transaction will be sent if the result of the check is false . To increase flexibility, it is possible to connect its own handler to check the condition of the transaction skipping.
It is worth noting that when developing the framework, the goal was not to completely copy GPSS, therefore, with the identical name of the components, their functionality may vary.
The decision to try to build a restaurant model arose not from scratch. Firstly, quite a lot of people visit them, secondly, this is a rather complicated queuing system, thirdly, my wife has been working in the restaurant business for many years, and I could consult with her.
So, we will begin to describe the model of the restaurant. The restaurant will be at 24 tables. Restaurant visitors are called “guests”, guests come randomly, these will be generated transactions. But the transaction is not one person, it can be a group of people who just took one table. To increase realism, if there are more than 6 guests in the queue (6 tables are needed) waiting for a table, then new guests leave, not wait.
Hostesses meet guests at the entrance, in large restaurants there are often two or more, there will be two in the model. In case there are free tables, hostesses lead them to the table, if there are no free tables, guests are waiting. In real restaurants there is a reservation and VIP-guests, for simplicity, they will not be in the constructed model, but such plans must be taken into account.
After the guests are seated at a table, they are served by a waiter, usually one waiter for several tables, in the model there will be one for three tables. As in a regular restaurant, the waiter cannot serve several tables at once, but serves them one at a time. During the service, the waiter receives an order from the guests. By order is meant several dishes of various types and drinks. How many dishes and drinks will be ordered is not known in advance, but we will count at least one and no more than five, including ordering at a bar. The waiter, having received the order, passes it to the cooks and bartenders.
Traditionally, among cooks there are specializations: appetizers and salads, meat, cakes and desserts, sushi. There will also be in the simulated restaurant - four chefs preparing different dishes. There will be two bartenders.
It is a common practice that not all dishes bring immediately, but as soon as ready. Accordingly, the guests do not eat them all at once, but gradually. And only when they ate all the dishes can you pay for the order. After that, the table can be vacated.
Specific time parameters can be viewed in the code .
In fig. 1 shows the structural diagram of the model. For modeling, almost the entire set of components of the framework is involved. So, to estimate the number of guests in the queue, the Check component is used . Using a specialized handler, he checks the number of guests in the queue and, if the specified number is exceeded, sends them to the exit. Also, using the Check checks whether the free table there.
Fig. 1. Structural diagram of the restaurant model.
Using Bifacility, the table is occupied and set free. And Assign paired with Check allows you to specify whether the waiter transfers the order from the table to the kitchen or already delivers the finished dishes.
As can be seen from fig. 1 each of the chefs has a queue of orders, in reality, of course, it is possible to cook several dishes in parallel, but in the presented model this is omitted. For bartenders, the order queue is common.
The simulation results can be found here . The report shows:
- two tables were not used (23 and 24), and in general, a quarter of the tables are practically not used;
- the restaurant served 29 visitors and none of the visitors left without ever entering the restaurant;
- visitors did not have to wait in line;
- at the end of the simulation, 12 visitors received part of their order and expected the remaining dishes;
- cook 1 and 4 have a very large load (91.46%, 88.33%);
- Barman 2 is not loaded with work (1.67%);
- half of the waiters are not particularly busy;
- hostess 2 is almost not busy (9.38%).
Bottom line, the restaurant is large and has a lot of extra staff. Or the restaurant is open in a place with poor traffic (in the presented model, visitors enter every 10 ± 5 minutes). If you test with greater traffic (5 ± 3), the load of staff increases significantly, but some of the visitors leave without waiting for a table.
The presented model, despite a number of simplifications, pretty tolerably allows you to simulate the work of the restaurant and possibly even has practical value. But components, both new and old, certainly need to be further developed. Not all exceptions are handled or handled incorrectly. It is necessary to cover the framework code with tests and the most important documentation. All this is planned and to the extent possible will be realized.