This article describes the new components of the framework for simulation, previously presented in the article
"Simple simulation system on Go" . As the framework has expanded, it has become possible to model more complex systems, for example, to simulate a restaurant’s work.
New components
There are several new components:
Bifacility ,
Split ,
Aggregate ,
Count ,
Assign ,
Check . Consider them in more detail.
Bifacility is essentially the same as
Facility , but its meaning is that the transaction does not take one component for a while, but a chain of components. For this, the
Bifacility constructor forms two components - IN and OUT. After hitting the transaction in the IN component,
Bifacility is considered to be occupied and another transaction cannot take it anymore. When a transact gets into an OUT component,
Bifacility is released and now another transact can take it.
Bifacility can be released only transaction that took him. The simplest analogy of
Bifacility can be considered a kind of technological installation that performs a series of operations on a single part. Until the item leaves the installation, you cannot send another part to it.
Split is a component intended for splitting a transaction into parts — other transactions that are further processed in parallel. For example, if we consider a transaction as an order, then its parts are items in the order. By default, in the absence of any parameters,
Split divides the received transaction into 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) will be split. Since in practice it may be necessary for splitting into parts to be carried out according to a certain law,
Split has the ability to connect its handler for splitting.
')
In a pair with
Split goes
Aggregate , as the name implies, it aggregates a number of transactions into one. Its functionality is quite simple, having received any of the parts of the previously broken TRANSACT, he waits for all the other parts and after receiving them sends the TRANSACT further.
Count - component for counting. The
Count constructor forms two components, INC and DEC. When a transaction enters INC, the counter
Count increases, when it enters the DEC it decreases. In the
Count constructor, the values are set for which the counter increases and decreases when it hits INC and DEC, respectively.
Assign - is designed to set some parameter of a transaction. Transaction has a list of parameters, each parameter has a name and value. The value can be a string, number, structure. If you assign a nil parameter, it is removed from the list.
Check - a component designed to verify the fulfillment of a certain condition and passes the transaction only when it is executed. By default, the equality of the transaction parameter with the specified value is checked. In the
Check constructor, you can specify a block to which a transaction will be sent in case the test result is
false . To increase flexibility, you can connect your handler to check the conditions of the pass transaction.
It is worth noting that the development of the framework was not intended to completely copy GPSS, so with the identical name of the components, their functionality may differ.
Restaurant model
The decision to try to build a model of the restaurant came not from scratch. Firstly, quite a few people visit them, secondly, this is a rather complicated queuing system, thirdly, my spouse has been working in the restaurant business for many years, and I could consult with her.
So, let's begin to describe the model of the restaurant. The restaurant will be on the 24 table. Visitors to the restaurant are called "guests", guests come randomly, it will be generated TRANSACT. But a transaction is not one person, it can be a group of people who just occupied one table. To increase the realism, if there are more than 6 guests in the queue (you need 6 tables) waiting for a table, then the new guests leave and not wait.
Guests are met at the entrance by a hostess, in large restaurants there are often two or more, there will be two of them in the model. If there are free tables, the hostesses will hold them to the table, if there are no free tables, guests wait. In real restaurants there are reservations and VIP-guests, for simplicity, they will not be in the constructed model, but plans should take into account such moments.
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 to three tables. As in the usual restaurant, the waiter can not immediately serve several tables, and serves them alternately. During the service the waiter receives an order from the guests. Under the order means several dishes of different types and drinks. How much food and drinks will be ordered is not known in advance, but we will count at least one and not more than five, including the order at the bar. The waiter, having received the order passes it to the chefs and bartenders.
Traditionally, there are specialties among chefs: snacks and salads, meats, cakes and desserts, sushi. There will also be a simulated restaurant - four chefs preparing different dishes. Bartenders will be two.
The usual practice is that not all dishes are brought immediately, but as soon as they are ready. Accordingly, guests do not eat them all at once, but gradually. And only when eaten all the dishes you can complete the payment of the order. After that, the table can be released.
Specific timing parameters can be viewed in the
code .
Modeling
In fig. 1 shows the structural diagram of the model. Almost the entire set of components of the framework is used for modeling. So, to estimate the number of guests in the queue, the
Check component is used. By means of a specialized handler, he checks the number of guests in the queue and, in case of exceeding the specified number, sends them to the exit. Also with the help of
Check it is checked whether free tables appeared.
Fig. 1. The structural scheme of the restaurant modelWith the help of
Bifacility, the table is
seized and cleared. And
Assign paired with
Check allows you to specify whether the waiter is transferring an order from the table to the kitchen or is already delivering ready meals.
As can be seen from fig. 1 each of the cooks has a queue of orders, in reality, of course, parallel cooking of several dishes is possible, but in the presented model this is omitted. For bartenders, the total order of orders.
Simulation results
The simulation results can be found
here . From the report you can see:
- 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 visiting the restaurant;
- visitors did not have to wait in line;
- at the end of the simulation, 12 visitors received part of their order and waited for the remaining dishes;
- Cook 1 and 4 have a very large load (91.46%, 88.33%);
- Barman 2 is not busy (1.67%);
- half of the waiters are not particularly busy;
- Hostess 2 is almost not busy (9.38%).
The result, the restaurant is big and there are a lot of superfluous staff. Or the restaurant is open in a place with poor traffic (in the presented model, visitors stop every 10 ± 5 minutes). If we test with a higher cross (5 ± 3), the staff load increases significantly, but some of the visitors leave without waiting for the table.
Conclusion
The presented model, despite a number of simplifications, quite tolerably allows you to simulate the work of a restaurant and perhaps even has practical value. But the components, both new and old, certainly need to be further refined. Not all exceptions are handled or processed incorrectly. It is necessary to cover the framework code with tests and the most important documentation. All this in the plans and as far as possible will be implemented.