Introduction to SIM.JS

Discrete Event Simulation

There is a lot to be said on Discrete Event Simulations that can be covered here. We refer the readers to the excellent article at Wikipedia and the references therein as an entry point to this interesting field of Computer Science.

Briefly speaking, Discrete Event Simulation (DES) is a technique to model a complex system in order to study its behavior. The system is modeled as a collection of states that change over time. Within DES, the time advances in discrete steps.

A typical model of a system includes (a) entities, which are the active actors in the system and encapsulate the state and logic of the system components, (b) resources, which are consumed by the entities, (c) communication primitives, to coordinate actions between entities across time, and of course, (d) statistics, which is the output of a simulation run.

As we will see shortly, the SIM.JS library provides support for entities, resources (Facility, Buffers and Stores), communication (via Timers, Events and Messages) and statistics (with Data Series, Time Series and Population statistics).

SIM.JS Design Principles

The most common design pattern that appears in DES models is as follows:

1. entity::
2.  do_some_local_computation
3.  resource = request_some_shared_resource
4.  do_more_local_computation

It is possible that the said resource is not available currently, in which case the request cannot be immediately satisfied and the entity must, therefore, “block” from further execution.

Waiting for resources is only one examples where entities may need to wait. There are other cases as well, for example, wait for a timer to expire, wait to receive message from other entities, wait for a predicate condition to become true, and so on.

There are two broad categories for implementing this “blocking” behavior:

  1. Process-based simulation.
  2. Event-based simulation.

In process-based simulation, the entities behave very much like regular operating system processes. Each entity runs on a separate thread, and when an entity executes a command for which it must block, the entire thread is suspended. When the waiting condition is satisfied, the thread is resumed. In the example given above, the entity thread will block at line 3 until the resource is free, and then will resume to line 4.

In event-based simulation, the entities all run in a single thread. At the time of making a request, the entities provide a callback function that must be invoked when the waiting condition is over. This style of programming is widely used in Graphical User Interface designs where preconfigured callback functions are called by the system when any event of interest occurs (e.g. mouse click). However, it also means that the code must be restructured a little. The above example must be written as:

entity::
    do_some_local_computation
    request_some_shared_resource_with_callback(entity_get_resource)
    return

entity_get_resource (resource)::
    do_more_local_computation

The proponents of process-based programming claim that their design leads to a better readability of code. Whereas the adherents of event-based programming argue that their approach is more structured since the actions for each different kind of events are encapsulated as different functions.

The SIM.JS library provides event-based programming model, for the following reasons:

  • At the time of writing, only Mozilla Firefox with JavaScript version 1.7 supports process-based programming model via the yield keyword (New is JavaScript 1.7). There are plans to add this support in the next version of ECMAScript Harmony (the wiki page); however, as of today, process-based programming is not a portable paradigm across all platforms.
  • The process-based designs are resource intensive, since each entity must run as separate thread and at the time of context switch, the entire call stack must be stored (and later restored).
  • Process-based programming is not idiomatic JavaScript. Practitioners of JavaScript largely follow the event-based programming, and specially so given the powerful features of JavaScript, such as first class functions, closures, anonymous functions, function call chains and so on.

The SIM.JS Library

The SIM.JS library introduces two class variables in the global namespace: Sim and Random. The Sim class provides all functionality for Discrete Event Simulation, while the Random class provides random number generation capability.

The Sim namespace further provides following classes:

Class Purpose
Sim The simulator kernel.
Sim.Facility Facility is a resource that is used by entities for a finite duration. There is a limit on the number of entities that can use the facility at a given time. As an example, consider a barbershop (the facility) with m barbers (capacity of facility). The customers arrive at shop and wish to ‘use’ the resource (barber); if all barbers are busy, the customers wait until one barber is available.
Sim.Buffer Buffer is a resource that can store a finite number of tokens. Any entity can store tokens in the buffer if there is free space, or retrieve existing tokens from the buffer if some are available.
Sim.Store Store is a resource that can store a finite number of JavaScript objects (actually any datatype: number, string, function, array, object etc). Any entity can store objects in the store if there is free space, or retrieve existing objects from the store if some are available.
Sim.Event Events are external objects that start out in passive state, and at some point in time will be activated or fired. Entities ‘attach’ themselves to events and wait until the event is fired.
Sim.Request When an entity makes a request to the simulation – such as set a timer, use a facility, etc – the simulator returns back a Request object. The entity can use this Request object to further modify the original request.
Sim.DataSeries Data Series is a collection of discrete, time-independent observations, for example, grades of each student in a class, length of rivers in United States. The DataSeries class provides a convenient API for recording and analyzing such observations, such as finding maximum and minimum values, statistical properties like average and standard deviation and so on.
Sim.TimeSeries Time Series is a collection of discrete time-dependent observations. That is, each observation value is associated with a discrete time instance (the time at which the observation was made). For example, the size of queue at time t during the simulation run, number of customers in a restaurant at time t during evening hours.The TimeSeries class provides a convenient API for recording and analyzing such observations, such as finding maximum and minimum values, statistical properties like time-averaged mean and standard deviation and so on.
Sim.Population Population is actually a composite of the above two statistics, which models the behavior of population growth and decline.

The Random library uses the Mersenne Twister algorithm for generating random number stream, and is based on the JavaScript implementation by Makoto Matsumoto and Takuji Nishimura (code). The Random class supports following probability distribution functions:

  • exponential()
  • gamma()
  • normal()
  • pareto()
  • triangular()
  • uniform()
  • weibull()

Using SIM.JS

Take a look at tutorials and examples to get a feel for writing simulation models with SIM.JS.

Table Of Contents

Previous topic

SIM.JS – Discrete Event Simulation in JavaScript

Next topic

SIM.JS Tutorial