Tutorial 5: Re-entrant Line Modeling
This example models re-entrant lines where jobs re-enter a station multiple times, asking for different classes of service at each visit. The completes flag controls whether a class transition counts as a job completion.
model = Network('RL');
queue = Queue(model, 'Queue', SchedStrategy.FCFS);
K = 3; N = [1,0,0];
for k=1:K
jobclass{k} = ClosedClass(model, ['Class',int2str(k)], N(k), queue);
queue.setService(jobclass{k}, Erlang.fitMeanAndOrder(k,2));
end
P = model.initRoutingMatrix();
P{jobclass{1},jobclass{2}}(queue,queue) = 1.0;
P{jobclass{2},jobclass{3}}(queue,queue) = 1.0;
P{jobclass{3},jobclass{1}}(queue,queue) = 1.0;
model.link(P);
ncAvgTable = NC(model).avgTable()
ncAvgSysTable = NC(model).avgSysTable()
jobclass{1}.completes = false;
jobclass{2}.completes = false;
ncAvgSysTable2 = NC(model).avgSysTable()
from line_solver import *
model = Network('RL')
queue = Queue(model, 'Queue', SchedStrategy.FCFS)
K = 3
N = (1, 0, 0)
jobclass = []
for k in range(K):
jobclass.append(ClosedClass(model, 'Class' + str(k+1), N[k], queue))
queue.set_service(jobclass[k], Erlang.fit_mean_and_order(1+k, 2))
P = model.init_routing_matrix()
P.set(jobclass[0], jobclass[1], queue, queue, 1.0)
P.set(jobclass[1], jobclass[2], queue, queue, 1.0)
P.set(jobclass[2], jobclass[0], queue, queue, 1.0)
model.link(P)
ncAvgTable = NC(model).avg_table()
ncAvgSysTable = NC(model).avg_sys_table()
jobclass[0].completes = False
jobclass[1].completes = False
ncAvgSysTable2 = NC(model).avg_sys_table()
import jline.lang.ClosedClass;
import jline.lang.RoutingMatrix;
import jline.lang.processes.Erlang;
import jline.solvers.nc.NC;
Network model = new Network("RL");
Queue queue = new Queue(model, "Queue", SchedStrategy.FCFS);
ClosedClass jobClass1 = new ClosedClass(model, "Class1", 1, queue);
ClosedClass jobClass2 = new ClosedClass(model, "Class2", 0, queue);
ClosedClass jobClass3 = new ClosedClass(model, "Class3", 0, queue);
queue.setService(jobClass1, Erlang.fitMeanAndOrder(1, 2));
queue.setService(jobClass2, Erlang.fitMeanAndOrder(2, 2));
queue.setService(jobClass3, Erlang.fitMeanAndOrder(3, 2));
RoutingMatrix P = model.initRoutingMatrix();
P.set(jobClass1, jobClass2, queue, queue, 1.0);
P.set(jobClass2, jobClass3, queue, queue, 1.0);
P.set(jobClass3, jobClass1, queue, queue, 1.0);
model.link(P);
new NC(model).avgTable().print();
new NC(model).avgSysTable().print();
jobClass1.setCompletes(false);
jobClass2.setCompletes(false);
new NC(model).avgSysTable().print();
#include "line/solvers/nc/solver_nc_runner.h"
Network model("RL");
Queue queue(model, "Queue", SchedStrategy::FCFS);
const std::size_t K = 3;
const double N[3] = {1, 0, 0};
std::vector<std::size_t> jobclass(K);
for (std::size_t k = 0; k < K; ++k) {
jobclass[k] = model.add_closed_class(
"Class" + std::to_string(k + 1), N[k], queue);
queue.set_service(jobclass[k], Erlang(2.0 / double(k + 1), 2));
}
Routing P;
P.set(jobclass[0], jobclass[1], queue, queue, 1.0);
P.set(jobclass[1], jobclass[2], queue, queue, 1.0);
P.set(jobclass[2], jobclass[0], queue, queue, 1.0);
model.link(P);
nc::NcSolverOptions opt;
const mva::AvgResult<double> res =
nc::solver_nc_run_analyzer(model.get_struct(), opt);
model.raw_struct().classes[jobclass[0] - 1].completes = false;
model.raw_struct().classes[jobclass[1] - 1].completes = false;
Expected Output (Per-class metrics)
ncAvgTable =
Station JobClass QLen Util RespT ResidT ArvR Tput
_______ ________ _______ _______ _____ _______ _______ _______
Queue Class1 0.16667 0.16667 1 0.33333 0.16667 0.16667
Queue Class2 0.33333 0.33333 2 0.66667 0.16667 0.16667
Queue Class3 0.5 0.5 3 1 0.16667 0.16667
Expected Output (System metrics, completes=true)
ncAvgSysTable =
Chain JobClasses SysRespT SysTput
______ ______________________________ ________ _______
Chain1 {[Class1 Class2 Class3]} 2 0.5
Expected Output (System metrics, completes=false for Class1,2)
ncAvgSysTable2 =
Chain JobClasses SysRespT SysTput
______ ______________________________ ________ _______
Chain1 {[Class1 Class2 Class3]} 6 0.16667