Tutorial 1: M/M/1 Queue

The M/M/1 queue is a classic model of a queueing system where jobs arrive into an infinite-capacity buffer, wait to be processed in first-come first-served (FCFS) order, and then leave after service completion. Inter-arrival and service times are assumed to be independent and exponentially distributed random variables.

M/M/1 Queue Network Diagram

The general structure of a LINE script consists of four blocks: (1) definition of nodes, (2) definition of job classes and associated statistical distributions, (3) instantiation of model topology, and (4) solution.

% Example 1: A M/M/1 queue
model = Network('M/M/1');
%% Block 1: nodes
source = Source(model, 'Source');
queue = Queue(model, 'Queue', SchedStrategy.FCFS);
sink = Sink(model, 'Sink');
%% Block 2: classes
jobclass = OpenClass(model, 'Class1');
source.setArrival(jobclass, Exp(1));
queue.setService(jobclass, Exp(2));
%% Block 3: topology
model.link(Network.serialRouting(source,queue,sink));
%% Block 4: solution
AvgTable = LDES(model,'seed',23000,'samples',10000).avgTable();
%% select a particular table row using direct indexing
ARow = AvgTable(queue, jobclass)
from line_solver import *

model = Network('M/M/1')
# Block 1: nodes
source = Source(model, 'mySource')
queue = Queue(model, 'myQueue', SchedStrategy.FCFS)
sink = Sink(model, 'mySink')
# Block 2: classes
jobclass = OpenClass(model, 'myClass')
source.set_arrival(jobclass, Exp(1))
queue.set_service(jobclass, Exp(2))
# Block 3: topology
model.link(Network.serial_routing(source, queue, sink))
# Block 4: solution
AvgTable = LDES(model, seed=23000, samples=10000).avg_table()
# select a particular table row
print(tget(AvgTable, queue, jobclass))
import jline.lang.Network;
import jline.lang.OpenClass;
import jline.lang.constant.SchedStrategy;
import jline.lang.nodes.Queue;
import jline.lang.nodes.Sink;
import jline.lang.nodes.Source;
import jline.lang.processes.Exp;
import jline.solvers.NetworkAvgTable;
import jline.solvers.ldes.LDES;

public class Tutorial1 {
    public static void main(String[] args) {
        Network model = new Network("M/M/1");
        // Block 1: nodes
        Source source = new Source(model, "Source");
        Queue queue = new Queue(model, "Queue", SchedStrategy.FCFS);
        Sink sink = new Sink(model, "Sink");
        // Block 2: classes
        OpenClass jobclass = new OpenClass(model, "Class1", 0);
        source.setArrival(jobclass, new Exp(1.0));
        queue.setService(jobclass, new Exp(2.0));
        // Block 3: topology
        model.link(Network.serialRouting(source, queue, sink));
        // Block 4: solution
        NetworkAvgTable avgTable = new LDES(model, "seed", 23000,
                "samples", 10000).avgTable();
        avgTable.print();
        avgTable.tget(queue, jobclass).print();
    }
}
#include "line/lang/qn/network_builder.h"
#include "line/lang/qn/nodes.h"
#include "line/lang/distributions.h"
#include "line/solvers/solver.h"
#include "line/solvers/wrappers/ldes/solver_ldes.h"
using namespace line;
using namespace lang;

Network model("M/M/1");
// Block 1: nodes
Source source(model, "Source");
Queue queue(model, "Queue", SchedStrategy::FCFS);
Sink sink(model, "Sink");
// Block 2: classes
OpenClass jobclass(model, "Class1");
source.set_arrival(jobclass, Exp(1.0));
queue.set_service(jobclass, Exp(2.0));
// Block 3: topology
Routing P;
P.set(source, queue, 1.0);
P.set(queue, sink, 1.0);
model.link(P);
// Block 4: solution
ldes::LdesOptions opt;
opt.samples = 10000;
opt.seed = 23000;
const ldes::LdesResult res = ldes::solver_ldes(model.get_struct(), opt);

Expected Output

ARow =
  1x8 table
    Station    JobClass     QLen      Util       RespT     ResidT      ArvR       Tput
    _______    ________    ______    _______    _______    _______    _______    _______
     Queue      Class1     0.9799    0.49595    0.98576    0.98576    0.99486    0.99386