Tutorial 12: Random Environments

This example demonstrates how to model a queueing system operating in a random environment, where system parameters change according to an underlying environmental process. A server alternates between "Fast" and "Slow" modes with different service rates.

Random Environment Network Diagram
warning off;

% Example 11: Random environments and ENV solver
%% Block 1: Create base network model
baseModel = Network('BaseModel');
delay = Delay(baseModel, 'ThinkTime');
queue = Queue(baseModel, 'Server', SchedStrategy.FCFS);

N = 5;
jobclass = ClosedClass(baseModel, 'Jobs', N, delay);
delay.setService(jobclass, Exp(1.0));
queue.setService(jobclass, Exp(2.0));
baseModel.link(Network.serialRouting(delay, queue));

%% Block 2: Create the random environment
env = Environment('ServerModes');

% Stage 1: Fast mode (service rate = 4.0)
fastModel = baseModel.copy();
fastQueue = fastModel.getNodeByName('Server');
fastQueue.setService(fastModel.classes{1}, Exp(4.0));
env.addStage('Fast', 'operational', fastModel);

% Stage 2: Slow mode (service rate = 1.0)
slowModel = baseModel.copy();
slowQueue = slowModel.getNodeByName('Server');
slowQueue.setService(slowModel.classes{1}, Exp(1.0));
env.addStage('Slow', 'degraded', slowModel);

% Define transitions
env.addTransition('Fast', 'Slow', Exp(0.5));
env.addTransition('Slow', 'Fast', Exp(1.0));

%% Block 3: Solve using SolverENV
env.init();
solverFactory = @(m) FLD(m);
envSolver = ENV(env, solverFactory);
envAvgTable = envSolver.getAvgTable()
from line_solver import Network, ClosedClass, Delay, Queue
from line_solver import Environment, ENV, FLD, MVA
from line_solver.constants import SchedStrategy
from line_solver.distributions import Exp

# Block 1: Create base network model
base_model = Network('BaseModel')
delay = Delay(base_model, 'ThinkTime')
queue = Queue(base_model, 'Server', SchedStrategy.FCFS)

N = 5
jobclass = ClosedClass(base_model, 'Jobs', N, delay)
delay.setService(jobclass, Exp(1.0))
queue.setService(jobclass, Exp(2.0))
base_model.link(Network.serialRouting(delay, queue))

# Block 2: Create the random environment
env = Environment('ServerModes', 2)

# Stage 0: Fast mode (service rate = 4.0)
fast_model = base_model.copy()
fast_queue = fast_model.getNodeByName('Server')
fast_queue.setService(fast_model.classes[0], Exp(4.0))
env.addStage(0, 'Fast', 'operational', fast_model)

# Stage 1: Slow mode (service rate = 1.0)
slow_model = base_model.copy()
slow_queue = slow_model.getNodeByName('Server')
slow_queue.setService(slow_model.classes[0], Exp(1.0))
env.addStage(1, 'Slow', 'degraded', slow_model)

# Define transitions
env.addTransition(0, 1, Exp(0.5))  # Fast -> Slow
env.addTransition(1, 0, Exp(1.0))  # Slow -> Fast

# Block 3: Solve using SolverENV
env_solver = ENV(env, lambda m: FLD(m))
env_avg_table = env_solver.getAvgTable()
print(env_avg_table)
import jline.lang.ClosedClass;
import jline.lang.Environment;
import jline.lang.nodes.Delay;
import jline.solvers.env.ENV;
import jline.solvers.fluid.FLD;

Network baseModel = new Network("BaseModel");
Delay delay = new Delay(baseModel, "ThinkTime");
Queue queue = new Queue(baseModel, "Fast/Slow Server", SchedStrategy.FCFS);
ClosedClass jobclass = new ClosedClass(baseModel, "Jobs", 5, delay, 0);
delay.setService(jobclass, new Exp(1.0));
queue.setService(jobclass, new Exp(2.0));
baseModel.link(Network.serialRouting(delay, queue));

Environment env = new Environment("ServerModes", 2);
Network fastModel = baseModel.copy();
((Queue) fastModel.getNodeByName("Fast/Slow Server"))
        .setService(fastModel.getClasses().get(0), new Exp(4.0));
env.addStage(0, "Fast", "operational", fastModel);
Network slowModel = baseModel.copy();
((Queue) slowModel.getNodeByName("Fast/Slow Server"))
        .setService(slowModel.getClasses().get(0), new Exp(1.0));
env.addStage(1, "Slow", "degraded", slowModel);
env.addTransition(0, 1, new Exp(0.5));
env.addTransition(1, 0, new Exp(1.0));

ENV envSolver = new ENV(env, m -> new FLD(m));
envSolver.getAvgTable().print();
#include "line/lang/qn/environment.h"
#include "line/solvers/env/env_dispatch.h"

Network baseModel("BaseModel");
const std::size_t delay = baseModel.add_delay("ThinkTime");
const std::size_t queue =
    baseModel.add_queue("Fast/Slow Server", SchedStrategy::FCFS);
const std::size_t jobclass = baseModel.add_closed_class("Jobs", 5, delay);
baseModel.set_service(delay, jobclass, Exp(1.0));
baseModel.set_service(queue, jobclass, Exp(2.0));
Routing P;
P.set(delay, queue, 1.0);
P.set(queue, delay, 1.0);
baseModel.link(P);

env::Environment<double> environment("ServerModes", 2);
Network fastModel = baseModel;
fastModel.set_service(queue, jobclass, Exp(4.0));
environment.set_stage(0, "Fast", "operational", fastModel.get_struct());
Network slowModel = baseModel;
slowModel.set_service(queue, jobclass, Exp(1.0));
environment.set_stage(1, "Slow", "degraded", slowModel.get_struct());
environment.add_transition(0, 1, Exp(0.5));
environment.add_transition(1, 0, Exp(1.0));

env::EnvOptions opt;
const env::EnvAnalyzerSolution<double> res =
    env::solver_env(environment, opt);

Expected Output

envAvgTable =
  2x6 table
     Station     JobClass     QLen      Util      RespT      Tput
    _________    ________    ______    ______    _______    ______
    ThinkTime      Jobs      2.9966    2.9966          1    2.9966
    Server         Jobs      2.0034         1    0.66779         3