LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
qsys_is_retrial.m
1%{ @file qsys_is_retrial.m
2 % @brief Checks if network is a valid BMAP/PH/N/N bufferless retrial queue
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Checks if network is a valid BMAP/PH/N/N bufferless retrial queue
9 %
10 % @details
11 % Validates that the network structure matches the requirements for
12 % the BMAP/PH/N/N retrial queue solver:
13 % - Single bufferless queue (capacity == number of servers)
14 % - Retrial drop strategy configured
15 % - BMAP/MAP arrival process at source
16 % - PH/Exp service at queue
17 % - Open class model
18 %
19 % Based on: Dudin et al., "Analysis of BMAP/PH/N-Type Queueing System with
20 % Flexible Retrials Admission Control", Mathematics 2025, 13(9), 1434.
21 %
22 % @par Syntax:
23 % @code
24 % [isRetrial, retInfo] = qsys_is_retrial(sn)
25 % @endcode
26 %
27 % @par Parameters:
28 % <table>
29 % <tr><th>Name<th>Description
30 % <tr><td>sn<td>Network structure
31 % </table>
32 %
33 % @par Returns:
34 % <table>
35 % <tr><th>Name<th>Description
36 % <tr><td>isRetrial<td>True if network is valid BMAP/PH/N/N retrial topology
37 % <tr><td>retInfo<td>Struct with parameters for the retrial solver
38 % </table>
39 %
40 % Copyright (c) 2012-2026, Imperial College London
41 % All rights reserved.
42%}
43function [isRetrial, retInfo] = qsys_is_retrial(sn)
44
45% Initialize output
46isRetrial = false;
47retInfo = struct();
48retInfo.stationIdx = [];
49retInfo.nodeIdx = [];
50retInfo.sourceIdx = [];
51retInfo.classIdx = [];
52retInfo.errorMsg = '';
53retInfo.N = []; % Number of servers
54retInfo.alpha = []; % Retrial rate
55retInfo.gamma = 0; % Orbit impatience (default 0)
56retInfo.p = 0; % Batch rejection prob (default 0)
57retInfo.R = []; % Admission threshold (from FCR or default N-1)
58
59% Check if model is open
60if ~sn_is_open_model(sn)
61 retInfo.errorMsg = 'BMAP/PH/N/N retrial solver requires open queueing model.';
62 return;
63end
64
65% Check for single class (current limitation)
66if sn.nclasses > 1
67 retInfo.errorMsg = 'BMAP/PH/N/N retrial solver currently supports single class only.';
68 return;
69end
70
71retInfo.classIdx = 1;
72
73% Find bufferless queue stations (capacity == nservers, finite capacity)
74bufferlessStations = [];
75for ist = 1:sn.nstations
76 if sn.nodetype(sn.stationToNode(ist)) == NodeType.Queue
77 if isfinite(sn.cap(ist)) && sn.cap(ist) == sn.nservers(ist)
78 bufferlessStations = [bufferlessStations, ist];
79 end
80 end
81end
82
83if isempty(bufferlessStations)
84 retInfo.errorMsg = 'No bufferless queue found (capacity must equal number of servers).';
85 return;
86end
87
88% Check retrial drop strategy
89retrialStation = [];
90for ist = bufferlessStations(:)'
91 if any(sn.droprule(ist,:) == DropStrategy.RETRIAL | ...
92 sn.droprule(ist,:) == DropStrategy.RETRIAL_WITH_LIMIT)
93 retrialStation = ist;
94 break;
95 end
96end
97
98if isempty(retrialStation)
99 retInfo.errorMsg = 'No retrial drop strategy configured on bufferless queue.';
100 return;
101end
102
103retInfo.stationIdx = retrialStation;
104retInfo.nodeIdx = sn.stationToNode(retrialStation);
105retInfo.N = sn.nservers(retrialStation);
106
107% Find source station
108sourceStation = [];
109for ist = 1:sn.nstations
110 if sn.nodetype(sn.stationToNode(ist)) == NodeType.Source
111 sourceStation = ist;
112 break;
113 end
114end
115
116if isempty(sourceStation)
117 retInfo.errorMsg = 'No Source node found.';
118 return;
119end
120
121retInfo.sourceIdx = sourceStation;
122
123% Validate arrival process (must be MAP/BMAP)
124% sn.proc{station}{class} contains PH representation
125arrivalProc = sn.proc{sourceStation}{retInfo.classIdx};
126if isempty(arrivalProc) || ~iscell(arrivalProc) || length(arrivalProc) < 2
127 retInfo.errorMsg = 'Invalid arrival process at source.';
128 return;
129end
130
131% Check if arrival is MAP/BMAP (has matrix structure)
132% For BMAP: proc is {D0, D1, D2, ...} or {alpha, A} for MAP
133% For Exp/PH at source: it's {1, -lambda} format
134if ~iscell(arrivalProc{1}) && size(arrivalProc{1}, 2) > 1
135 % This looks like a PH representation {alpha, A}, convert from arrival to MAP
136 % For now, we accept it - the solver_mam_retrial will handle conversion
137elseif iscell(arrivalProc{1})
138 % This might be BMAP format already
139end
140
141% Validate service process (must be PH/Exp)
142serviceProc = sn.proc{retrialStation}{retInfo.classIdx};
143if isempty(serviceProc) || ~iscell(serviceProc) || length(serviceProc) < 2
144 retInfo.errorMsg = 'Invalid service process at queue.';
145 return;
146end
147
148% Extract retrial rate alpha from retrial delay distribution
149% In sn struct, we need to check for retrial configuration
150% For now, use default if not found - the Network/getStruct needs to export this
151retInfo.alpha = 0.1; % Default, will be extracted from sn in solver
152
153% Check for FCR containing this queue and extract admission threshold
154retInfo.R = retInfo.N - 1; % Default: no admission control
155
156% Check if region field exists and is non-empty
157if isfield(sn, 'region') && ~isempty(sn.region) && isfield(sn, 'nregions') && sn.nregions > 0
158 for f = 1:sn.nregions
159 regionMatrix = sn.region{f};
160 % Check if this station is in the region with a global capacity
161 if size(regionMatrix, 1) >= retrialStation
162 globalCapCol = size(regionMatrix, 2); % Last column is typically global cap
163 if regionMatrix(retrialStation, globalCapCol) > 0
164 % Get the global max jobs for this region
165 R_fcr = regionMatrix(retrialStation, globalCapCol);
166 if R_fcr <= retInfo.N - 1
167 retInfo.R = R_fcr; % Use FCR threshold
168 end
169 break;
170 end
171 end
172 end
173end
174
175% All validations passed
176isRetrial = true;
177
178end