LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
rewardModel_1.m
1%% Example: Using setReward for reward-based CTMC analysis
2% This example demonstrates the setReward feature for defining custom
3% reward functions on a queueing network model and computing steady-state
4% expected rewards using the CTMC solver.
5%
6% Copyright (c) 2012-2026, Imperial College London
7% All rights reserved.
8
9clear; clc;
10
11%% Model Definition
12% Create a simple M/M/1/K queue with finite buffer
13
14model = Network('RewardExample');
15
16% Block 1: nodes
17source = Source(model, 'Source');
18queue = Queue(model, 'Queue', SchedStrategy.FCFS);
19sink = Sink(model, 'Sink');
20
21% Set finite buffer capacity
22queue.setNumberOfServers(1);
23queue.setCapacity(3); % Maximum jobs in the system
24
25% Block 2: job classes
26oclass = OpenClass(model, 'Class1');
27source.setArrival(oclass, Exp(2)); % Arrival rate = 2
28queue.setService(oclass, Exp(3)); % Service rate = 3 (utilization ~ 0.67)
29
30% Block 3: topology
31model.link(Network.serialRouting(source,queue,sink));
32
33%% Define Reward Functions
34% setReward(name, @(state, sn) -> reward_value)
35% The function receives the aggregated state vector and network structure
36
37% Reward 1: Queue length (number of jobs in the queue)
38% State format for this model: state = [jobs_at_queue]
39model.setReward('QueueLength', @(state, sn) state(2));
40
41% Reward 2: Utilization (1 if server busy, 0 if idle)
42% Server is busy if at least 1 job is present
43model.setReward('Utilization', @(state, sn) min(state(2), 1));
44
45% Reward 3: Blocking indicator (1 if buffer full, 0 otherwise)
46% Buffer is full when jobs = capacity (10)
47model.setReward('BlockingProb', @(state, sn) (state(2) >= 10));
48
49% Reward 4: Weighted queue cost (quadratic penalty for long queues)
50model.setReward('QueueCost', @(state, sn) state(2)^2);
51
52%% Solve with CTMC Solver
53fprintf('Solving with CTMC solver...\n\n');
54
55options = Solver.defaultOptions;
56options.verbose = 1;
57
58solver = CTMC(model, options);
59
60%% Get Steady-State Expected Rewards
61[R, names] = solver.getAvgReward();
62
63fprintf('\n=== Steady-State Expected Rewards ===\n');
64for i = 1:length(names)
65 fprintf('%15s: %.6f\n', names{i}, R(i));
66end
67
68%% Get Transient Reward Analysis
69% Get full reward trajectories over time
70[t, V, names, stateSpace] = solver.getReward();
71
72fprintf('\n=== State Space ===\n');
73fprintf('Number of states: %d\n', size(stateSpace, 1));
74fprintf('State dimensions: %d\n', size(stateSpace, 2));
75
76%% Plot Reward Convergence
77figure('Name', 'Reward Convergence', 'Position', [100 100 800 600]);
78
79nRewards = length(names);
80for r = 1:nRewards
81 subplot(2, 2, r);
82
83 % Plot mean reward rate over time (averaged over all initial states)
84 meanReward = mean(V{r}, 2); % Average over states
85
86 % Compute reward rate (reward per unit time)
87 rewardRate = zeros(length(t), 1);
88 for k = 2:length(t)
89 rewardRate(k) = meanReward(k) / t(k);
90 end
91
92 plot(t(2:end), rewardRate(2:end), 'LineWidth', 1.5);
93 hold on;
94 yline(R(r), 'r--', 'LineWidth', 1.5);
95 hold off;
96
97 xlabel('Time');
98 ylabel('Expected Reward Rate');
99 title(sprintf('%s (Steady-state: %.4f)', names{r}, R(r)));
100 legend('Transient', 'Steady-state', 'Location', 'best');
101 grid on;
102end
103
104sgtitle('Convergence of Reward Functions to Steady-State');
105
106%% Compare with Analytical Results for M/M/1/K
107fprintf('\n=== Comparison with M/M/1/K Analytical Results ===\n');
108
109lambda = 2; % Arrival rate
110mu = 3; % Service rate
111rho = lambda / mu;
112K = 10; % Buffer capacity
113
114% For M/M/1/K queue, steady-state probabilities:
115% pi(n) = (1-rho) * rho^n / (1 - rho^(K+1))
116if rho ~= 1
117 pi = zeros(K+1, 1);
118 for n = 0:K
119 pi(n+1) = (1 - rho) * rho^n / (1 - rho^(K+1));
120 end
121else
122 pi = ones(K+1, 1) / (K+1);
123end
124
125% Analytical expected queue length
126L_analytical = sum((0:K)' .* pi);
127
128% Analytical utilization (P(server busy) = 1 - pi(0))
129U_analytical = 1 - pi(1);
130
131% Analytical blocking probability = pi(K)
132B_analytical = pi(end);
133
134% Analytical queue cost (E[N^2])
135Cost_analytical = sum(((0:K).^2)' .* pi);
136
137fprintf('%15s: LINE = %.6f, Analytical = %.6f, Error = %.2e\n', ...
138 'QueueLength', R(1), L_analytical, abs(R(1) - L_analytical));
139fprintf('%15s: LINE = %.6f, Analytical = %.6f, Error = %.2e\n', ...
140 'Utilization', R(2), U_analytical, abs(R(2) - U_analytical));
141fprintf('%15s: LINE = %.6f, Analytical = %.6f, Error = %.2e\n', ...
142 'BlockingProb', R(3), B_analytical, abs(R(3) - B_analytical));
143fprintf('%15s: LINE = %.6f, Analytical = %.6f, Error = %.2e\n', ...
144 'QueueCost', R(4), Cost_analytical, abs(R(4) - Cost_analytical));
145
146fprintf('\nExample completed successfully.\n');
Definition mmt.m:92