2%% Example of a closed queueing network with 3 chains, 5
classes, and
class switching
3% Product-form (BCMP) network with
class switching.
4% Chain 1: High-priority users (2
classes that can
switch)
5% Chain 2: Regular users (2
classes that can
switch)
6% Chain 3: Background tasks (1
class)
8% The network maintains product-form property:
9% - All service times are exponential
10% - Mix of FCFS and PS scheduling
11% - All
nodes are conventional queueing stations or infinite servers
13model = Network(
'cqn_multichain');
16node{1} = Delay(model,
'ThinkingTime');
17node{2} = Queue(model,
'WebServer', SchedStrategy.FCFS);
18node{3} = Queue(model,
'AppServer', SchedStrategy.PS);
19node{4} = Queue(model,
'DataServer', SchedStrategy.FCFS);
22% Chain 1: High-priority users (can
switch between HighPriorityA and HighPriorityB)
23jobclass{1} = ClosedClass(model,
'HighPriorityA', 2, node{1});
24jobclass{2} = ClosedClass(model,
'HighPriorityB', 1, node{1});
25% Chain 2: Regular users (can
switch between RegularA and RegularB)
26jobclass{3} = ClosedClass(model,
'RegularA', 3, node{1});
27jobclass{4} = ClosedClass(model,
'RegularB', 2, node{1});
28% Chain 3: Background tasks
29jobclass{5} = ClosedClass(model,
'Background', 2, node{1});
31%% Block 3: service times (all exponential
for product-form)
32% ThinkingTime (infinite server node)
33node{1}.setService(
jobclass{1}, Exp.fitMean(1.5));
34node{1}.setService(
jobclass{2}, Exp.fitMean(1.6));
35node{1}.setService(
jobclass{3}, Exp.fitMean(2.0));
36node{1}.setService(
jobclass{4}, Exp.fitMean(2.1));
37node{1}.setService(
jobclass{5}, Exp.fitMean(3.0));
39% WebServer (FCFS, exponential)
40node{2}.setService(
jobclass{1}, Exp.fitMean(0.4));
41node{2}.setService(
jobclass{2}, Exp.fitMean(0.42));
42node{2}.setService(
jobclass{3}, Exp.fitMean(0.5));
43node{2}.setService(
jobclass{4}, Exp.fitMean(0.52));
44node{2}.setService(
jobclass{5}, Exp.fitMean(0.8));
46% AppServer (PS, exponential)
47node{3}.setService(
jobclass{1}, Exp.fitMean(0.7));
48node{3}.setService(
jobclass{2}, Exp.fitMean(0.75));
49node{3}.setService(
jobclass{3}, Exp.fitMean(0.9));
50node{3}.setService(
jobclass{4}, Exp.fitMean(0.95));
51node{3}.setService(
jobclass{5}, Exp.fitMean(1.2));
53% DataServer (FCFS, exponential)
54node{4}.setService(
jobclass{1}, Exp.fitMean(0.5));
55node{4}.setService(
jobclass{2}, Exp.fitMean(0.52));
56node{4}.setService(
jobclass{3}, Exp.fitMean(0.6));
57node{4}.setService(
jobclass{4}, Exp.fitMean(0.62));
58node{4}.setService(
jobclass{5}, Exp.fitMean(1.0));
60%% Block 4: routing with
class switching
61M = model.getNumberOfNodes();
62K = model.getNumberOfClasses();
64P = model.initRoutingMatrix();
66% ===== Chain 1: High-priority users with switching =====
67% HighPriorityA routing:
68P{1,1}(1,2) = 1; % ThinkingTime -> WebServer
69P{1,1}(2,3) = 0.7; % WebServer -> AppServer (stay in HighPriorityA)
70P{1,2}(2,3) = 0.3; % Class
switch to HighPriorityB at WebServer
71P{1,1}(3,4) = 1; % AppServer -> DataServer
72P{1,1}(4,1) = 1; % DataServer -> ThinkingTime
74% HighPriorityB routing:
75P{2,2}(1,2) = 1; % ThinkingTime -> WebServer
76P{2,2}(2,3) = 0.75; % WebServer -> AppServer (stay in HighPriorityB)
77P{2,1}(2,3) = 0.25; % Class
switch to HighPriorityA at WebServer
78P{2,2}(3,4) = 1; % AppServer -> DataServer
79P{2,2}(4,1) = 1; % DataServer -> ThinkingTime
81% ===== Chain 2: Regular users with switching =====
83P{3,3}(1,2) = 1; % ThinkingTime -> WebServer
84P{3,3}(2,3) = 0.65; % WebServer -> AppServer (stay in RegularA)
85P{3,4}(2,3) = 0.35; % Class
switch to RegularB at WebServer
86P{3,3}(3,4) = 1; % AppServer -> DataServer
87P{3,3}(4,1) = 1; % DataServer -> ThinkingTime
90P{4,4}(1,2) = 1; % ThinkingTime -> WebServer
91P{4,4}(2,3) = 0.7; % WebServer -> AppServer (stay in RegularB)
92P{4,3}(2,3) = 0.3; % Class
switch to RegularA at WebServer
93P{4,4}(3,4) = 1; % AppServer -> DataServer
94P{4,4}(4,1) = 1; % DataServer -> ThinkingTime
96% ===== Chain 3: Background tasks =====
98P{5,5}(1,2) = 1; % ThinkingTime -> WebServer
99P{5,5}(2,3) = 1; % WebServer -> AppServer
100P{5,5}(3,4) = 1; % AppServer -> DataServer
101P{5,5}(4,1) = 1; % DataServer -> ThinkingTime
105%% Block 5: solve with multiple solvers
106options = Solver.defaultOptions;
110disp(
'Closed QN with 3 chains, 5 classes, and class switching (product-form):');
111disp(
'- Chain 1 (N=3): HighPriorityA and HighPriorityB (switch at WebServer)');
112disp(
'- Chain 2 (N=5): RegularA and RegularB (switch at WebServer)');
113disp(
'- Chain 3 (N=2): Background');
114disp(
'Network maintains BCMP product-form property (exponential, FCFS/PS)');
118solver{end+1} = MVA(model, options);
119solver{end+1} = CTMC(model, options);
120solver{end+1} = SSA(model, options);
122for s = 1:length(solver)
123 fprintf(
'SOLVER: %s\n', solver{s}.getName());
124 AvgTable{s} = solver{s}.getAvgChainTable();