Simulating a Process

Overview


In order to understand the distribution of the amount of time a typical process may take, it is often useful to simulate the process several times and average the results.

For the purposes of this page, a process is a series of steps, each that takes an amount of time. Each step may have dependencies on other steps, and the amount of time taken to complete a step can be random.

The simplified method we will use assumes that a tasks can start as soon as all the tasks that it depends on are complete. If no dependencies are specified, the process length will be the length of the longest task.

Building a Process Tree


In the following code, we begin to set up a process tree for a project. Each task is given a unique name, and function that computes the length of the task in the current simulation.

Notice that the second task specifies a list of dependencies, where the name of the first task is included as a dependency.


let tasks = [
    {name:'set up server', length:function(){
        return 5;
    }},
    {name:'set up database', dependencies:['set up server'], length:()=>{
        return 10*Math.random();
    }}    
];
					


Once we have this information, we can run a simulation of the entire process.


let sim = await import('/lib/process/v1.0.0/simulate.mjs');

let results = sim.simulate(tasks);
					
Try it!

Setting the Distribution Functions





tasks['set up database'] = {
  length: 10*Math.random()
};
						 




Typically you will want to provide a function has some randomness and has an average and standard deviation that matches what you expect for the given step. For example, you could choose a Guassian (normal or bell curve) distribution with the appropriate mean and standard deviation. There are some downsides to using the normal, i.e., the normal distribution can go negative. This means you could generate steps with a negative amount of time. This may not be much of problem, as it may be unllikely, and as you will average the statistics over a largen number of samples, this ill defined samples may not influence the result that much. However, you could choose a better suited distribution, such as the lognormal distribution.


let ln = await import('/lib/statistics/distributions/lognormal/v1.0.0/lognormal.js');
tasks['set up database'] = {
  length: ln.generate(1,1)
};

					


Other distributions can be found: distribution.

Calculating the Process Statistics


After running a simulation, various aggregate statistics can be calculated from the simulated set of tasks. The following demonstrates calculating the sum total of all the lengths of the tasks, and the length of the process as a whole.


let totalLength = $list(results).map(p=>p.length).sum();

let length = $list(results).map.(p=>p.start + p.length).max();
					
Try it!