LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_mva.m
1function [Q,U,R,T,C,X,lG] = solver_mva(sn,options)
2% [Q,U,R,T,C,X,LG] = SOLVER_MVA(SN,OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7if nargin < 2
8 options = SolverMVA.defaultOptions;
9end
10
11[Lchain,STchain,Vchain,alpha,Nchain,~,refstatchain] = sn_get_demands_chain(sn);
12
13nservers = sn.nservers;
14sched = sn.sched;
15M = sn.nstations;
16K = sn.nchains;
17
18if ~sn_has_product_form(sn)
19 line_error(mfilename, 'Unsupported exact MVA analysis, the model does not have a product form');
20end
21
22% Check for special LCFS + LCFS-PR 2-station network
23lcfsStat = find(sched == SchedStrategy.LCFS);
24lcfsprStat = find(sched == SchedStrategy.LCFSPR);
25if ~isempty(lcfsStat) && ~isempty(lcfsprStat)
26 % Validate LCFS network topology
27 if length(lcfsStat) ~= 1 || length(lcfsprStat) ~= 1
28 line_error(mfilename, 'LCFS MVA requires exactly one LCFS and one LCFS-PR station.');
29 end
30 if any(isinf(Nchain))
31 line_error(mfilename, 'LCFS MVA requires a closed queueing network.');
32 end
33 % Check for self-loops in routing matrix
34 rt = sn.rt;
35 nclasses = sn.nclasses;
36 for ist = [lcfsStat, lcfsprStat]
37 for r = 1:nclasses
38 if rt((ist-1)*nclasses+r, (ist-1)*nclasses+r) > 0
39 line_error(mfilename, 'LCFS MVA does not support self-loops at stations.');
40 end
41 end
42 end
43 % Call specialized LCFS MVA solver
44 [Q,U,R,T,C,X,lG] = solver_mva_lcfsqn(sn, options, lcfsStat, lcfsprStat);
45 return;
46elseif ~isempty(lcfsStat)
47 % LCFS without LCFS-PR is not supported
48 line_error(mfilename, 'LCFS scheduling requires a paired LCFS-PR station.');
49end
50
51infSET =[]; % set of infinite server stations
52qSET =[]; % set of other product-form stations
53for ist=1:M
54 switch sched(ist)
55 case SchedStrategy.EXT
56 % no-op
57 case SchedStrategy.INF
58 infSET(1,end+1) = ist;
59 case {SchedStrategy.PS, SchedStrategy.LCFSPR}
60 qSET(1,end+1) = ist;
61 case {SchedStrategy.FCFS, SchedStrategy.SIRO}
62 qSET(end+1) = ist;
63 otherwise
64 line_error(mfilename, sprintf('Unsupported exact MVA analysis for %s scheduling.',SchedStrategy.toText(sched(ist))));
65 end
66end
67
68Uchain = zeros(M,K); Tchain = zeros(M,K); C = zeros(1,K); Wchain = zeros(M,K); Qchain = zeros(M,K);
69
70lambda = zeros(1,K);
71ocl = find(isinf(Nchain));
72if any(isinf(Nchain))
73 for r=ocl % open classes
74 lambda(r) = 1 ./ STchain(refstatchain(r),r);
75 Qchain(refstatchain(r),r) = Inf;
76 end
77end
78rset = setdiff(1:K,find(Nchain==0));
79
80[Xchain,Qpf,Uchain,~,lG] = pfqn_mvams(lambda,STchain(qSET,:).*Vchain(qSET,:),Nchain,STchain(infSET,:).*Vchain(infSET,:),ones(length(qSET),1),nservers(qSET));
81Qchain(qSET,:) = Qpf;
82Qchain(infSET,:) = repmat(Xchain,numel(infSET),1) .* STchain(infSET,:) .* Vchain(infSET,:);
83
84ccl = find(isfinite(Nchain));
85for r=rset
86 for k=infSET(:)'
87 Wchain(k,r) = STchain(k,r);
88 end
89 for k=qSET(:)'
90 if isinf(nservers(k)) % infinite server
91 Wchain(k,r) = STchain(k,r);
92 else
93 if Vchain(k,r) == 0 || Xchain(r) == 0
94 Wchain(k,r) = 0;
95 else
96 Wchain(k,r) = Qchain(k,r) / (Xchain(r) * Vchain(k,r));
97 end
98 end
99 end
100end
101
102for r=rset
103 if sum(Wchain(:,r)) == 0
104 Xchain(r) = 0;
105 else
106 if isinf(Nchain(r))
107 C(r) = Vchain(:,r)'*Wchain(:,r);
108 % X(r) remains constant
109 elseif Nchain(r)==0
110 Xchain(r) = 0;
111 C(r) = 0;
112 else
113 C(r) = Vchain(:,r)'*Wchain(:,r);
114 Xchain(r) = Nchain(r) / C(r);
115 end
116 end
117
118 for k=1:M
119 Qchain(k,r) = Xchain(r) * Vchain(k,r) * Wchain(k,r);
120 Tchain(k,r) = Xchain(r) * Vchain(k,r);
121 end
122end
123
124for k=1:M
125 for r=rset
126 if isinf(nservers(k)) % infinite server
127 Uchain(k,r) = Vchain(k,r)*STchain(k,r)*Xchain(r);
128 else
129 Uchain(k,r) = Vchain(k,r)*STchain(k,r)*Xchain(r)/nservers(k);
130 end
131 end
132end
133
134for k=1:M
135 for r=1:K
136 if Vchain(k,r)*STchain(k,r) > options.tol
137 switch sched(k)
138 case {SchedStrategy.FCFS,SchedStrategy.PS}
139 if sum(Uchain(k,:))>1+options.tol
140 Uchain(k,r) = min(1,sum(Uchain(k,:))) * Vchain(k,r)*STchain(k,r)*Xchain(r) / ((Vchain(k,:).*STchain(k,:))*Xchain(:));
141 end
142 end
143 end
144 end
145end
146
147%Vsink = cellsum(sn.nodevisits);
148%Vsink = Vsink(find(sn.nodetype==NodeType.Sink),:);
149%for r=find(isinf(Nchain)) % open classes
150 %Xchain(r) = Vsink(r) ./ STchain(refstatchain(r),r);
151%end
152
153Rchain = Qchain./Tchain;
154Xchain(~isfinite(Xchain))=0;
155Uchain(~isfinite(Uchain))=0;
156Qchain(~isfinite(Qchain))=0;
157Rchain(~isfinite(Rchain))=0;
158
159Xchain(Nchain==0)=0;
160Uchain(:,Nchain==0)=0;
161Qchain(:,Nchain==0)=0;
162Rchain(:,Nchain==0)=0;
163Tchain(:,Nchain==0)=0;
164Wchain(:,Nchain==0)=0;
165
166[Q,U,R,T,C,X] = sn_deaggregate_chain_results(sn, Lchain, [], STchain, Vchain, alpha, [], [], Rchain, Tchain, [], Xchain);
167end