Tutorial 9: Departure Process Analysis

This example illustrates LINE's support for extracting simulation data about particular events, such as departures from a queue. We compute the squared coefficient of variation of inter-departure times and compare with Marshall's exact formula.

M/E/1 Queue Network Diagram
% Example 9: Studying a departure process
[model,source,queue,sink,oclass] = gallery_merl1;
%% Block 4: solution
solver = CTMC(model,'cutoff',150,'seed',23000);

sa = solver.sampleSysAggr(5e3);
ind = model.getNodeIndex(queue);

filtEvent = cellfun(@(c) c.node == ind && ...
    (isequal(c.event, EventType.DEP) || (isnumeric(c.event) && c.event == 2)), sa.event);
interDepTimes = diff(cellfun(@(c) c.t, {sa.event{filtEvent}}));

% Estimated squared coeff. of variation of departures
SCVdEst = var(interDepTimes)/mean(interDepTimes)^2

util = solver.getAvgUtil();
util = util(queue);
avgWaitTime = solver.getAvgWaitT();
avgWaitTime = avgWaitTime(queue);
SCVa = source.getArrivalProcess(oclass).getSCV();
svcRate = queue.getServiceProcess(oclass).getRate();
SCVs = queue.getServiceProcess(oclass).getSCV();

% Marshall's exact formula
SCVd = SCVa + 2*util^2*SCVs - 2*util*(1-util)*svcRate*avgWaitTime

fprintf('Simulated SCV:   %.6f\n', SCVdEst);
fprintf('Theoretical SCV: %.6f\n', SCVd);
// Example 9: Studying a departure process
val (model, source, queue, sink, oclass) = galleryMerl1()

// Block 4: solution
val solver = CTMC(model, "cutoff", 150)
val sa = solver.sampleSysAggr(5000)
val ind = model.getNodeIndex(queue)

// Filter departure events and compute inter-departure times
val depTimes = sa.event.filter { it.node == ind && it.event == EventType.DEP }
    .map { it.t }
val interDepTimes = depTimes.zipWithNext { a, b -> b - a }

// Compute estimated SCV
val mean = interDepTimes.average()
val variance = interDepTimes.map { (it - mean).pow(2) }.average()
val scvdEst = variance / mean.pow(2)

// Marshall's exact formula
val util = solver.avgUtil[queue][0]
val scva = source.getArrivalProcess(oclass).scv
val svcRate = queue.getServiceProcess(oclass).rate
val scvs = queue.getServiceProcess(oclass).scv
val avgWaitTime = solver.avgWaitT[ind]

val scvd = scva + 2*util*util*scvs - 2*util*(1-util)*svcRate*avgWaitTime
println("Simulated SCV: $scvdEst, Theoretical SCV: $scvd")
from line_solver import *
import numpy as np

model, source, queue, sink, oclass = gallery_merl1()

# Block 4: solution
solver = CTMC(model, cutoff=150, seed=23000)
sa = solver.sample_sys_aggr(5000)
ind = model.get_node_index(queue)

# Filter departure events
dep_times = []
for event in sa.event:
    if event.node == ind and event.event == "DEP":
        dep_times.append(event.t)

if len(dep_times) > 1:
    inter_dep_times = np.diff(dep_times)
    # Estimated SCV of departures
    scv_d_est = np.var(inter_dep_times) / np.mean(inter_dep_times)**2
    print(f"Simulated SCV of departures: {scv_d_est:.6f}")

Expected Output

=== Departure Process Analysis Results ===
Simulated SCV of departures:   0.899211
Theoretical SCV (Marshall):    0.875000
Relative error:                2.77%