In this example, we will model as buffet-style restaurant. Customer arrive at restaurant, pick up food from buffet area (we will will assume only one food item: salad), reach cashier for payment and leave the restaurant. The salad buffet is a finite resource, and is replenished every few minutes by the chef. In this restaurant the customers may have to wait at two places:
The customizable parameters for this restaurant model are:
Simulation Objectives. We would like to find out:
We observe first that the system has two resources:
There will be two entities in the system: the chef and the customers. As in the earlier example, we will model customers as one entity object.
We will use Population Statistics to record the arrival and departure of customers.
The following code lists all the global variables we will need in our simulation:
var sim = new Sim();
var stats = new Sim.Population();
var cashier = new Sim.Facility('Cashier');
var buffet = new Sim.Buffer('Buffet', BuffetCapacity);
var random = new Random(Seed);
Lets start with the Entity Prototype for Chef first. The chef replenishes the salad buffer every PreparationTime interval. The code is very simple:
var Chef = {
start: function () {
this.putBuffer(buffet, BuffetCapacity - buffet.current());
this.setTimer(PreparationTime).done(this.start);
}
};
Note here that the chef fills only the empty portion in the buffet.
Next, let us look at the Customer entity. This entity prototype will generate request for all customers, where the time interval between customer arrivals is exponentially distributed. We will first look at the start function, which is somewhat similar to the start function of Chef. The customer will order (this.order(), which we will see next), and the function is called again after an exponentially distributed random delay:
var Customer = {
start: function () {
this.order();
var nextCustomerAt = random.exponential (1.0 / MeanArrival);
this.setTimer(nextCustomerAt).done(this.start);
},
...
The Customer.order() function models the actions of customers inside the restaurant. First we will log the arrival of customer (line 3) and record in the statistics object (line 6). The customer then request to get one unit from the buffer (line 8) and will execute the anonymous function (argument to done() function) when the request is satisfied. The request may be satisfied immediately, if the buffer not empty, or wait otherwise. In the callback function, we log again that the customer has cleared the buffer stage and will now proceed to the cashier (line 10). The service time at cashier is also exponential distributed (line 13), and we use the this.useFacility() function to request service from the cashier (line 14). The callback function here will log that the customer will not leave the restaurant (line 16) and we also record this time in the statistics (line 20). Note also that we are using the Request.setData() function to remember the arrival time (which is read later on from this.callbackData attribute).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | order: function () {
// Logging
sim.log("Customer ENTER at " + this.time());
// statistics
stats.enter(this.time());
this.getBuffer(buffet, 1).done(function () {
// Logging
sim.log("Customer at CASHIER " + this.time()
+ " (entered at " + this.callbackData + ")");
var serviceTime = random.exponential(1.0 / CashierTime);
this.useFacility(cashier, serviceTime).done(function () {
// Logging
sim.log("Customer LEAVE at " + this.time()
+ " (entered at " + this.callbackData + ")");
// Statistics
stats.leave(this.callbackData, this.time());
}).setData(this.callbackData);
}).setData(this.time());
}
|
Finally, we create entities (lines 1 and 2), optionally set a logger function (lines 5-7), start the simulation (line 9) and report back the statistics (line 11).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | sim.addEntity(Customer);
sim.addEntity(Chef);
sim.setLogger(function (msg) {
document.write(msg);
});
sim.simulate(Simtime);
return [stats.durationSeries.average(),
stats.durationSeries.deviation(),
stats.sizeSeries.average(),
stats.sizeSeries.deviation()];
|
This javascript code can be executed where ever javascript can run. This includes:
We will run our model as a web page on a web browser. For this we have created the following web page:
<html>
<head>
<title>Tutorial: Customers at a Buffet Restaurant</title>
<script type="text/javascript" src="sim-0.1.js"></script>
<script type="text/javascript" src="buffet_restaurant.js"></script>
</head>
<body></body>
</html>
You can play with this simulation model. Try out different values of input parameters and compare the output statistics of model.