1function [runtime, analyzer] = runAnalyzer(self, options)
7 options = self.getOptions;
15% The shared gate subsumes the coarse supports(self.model) test (through
16% supportsModelMethod) and additionally reports which features are unsupported;
17% a separate coarse check here would fire first and name nothing. It also
18% validates options.method, as in the other solvers.
19self.runAnalyzerChecks(options);
21Solver.resetRandomGeneratorSeed(options.seed);
23sn = getStruct(self); % doesn't need initial state
24line_ack('QNS', options.verbose);
26line_debug(options, 'QNS: starting (method=%s, multiserver=%s)', options.method, options.config.multiserver);
28if (strcmp(options.method,'exact')||strcmp(options.method,'mva')) && ~self.model.hasProductFormSolution
29 line_error(mfilename,'The exact method requires the model to have a product-
form solution. This model does not have one. You can use Network.hasProductFormSolution() to check before running the solver.');
32method = options.method;
36 options.config.multiserver = 'conway';
38 options.config.multiserver = 'rolia';
40 options.config.multiserver = 'zhou';
42 options.config.multiserver = 'suri';
44 options.config.multiserver = 'reiser';
46 options.config.multiserver = 'schmidt';
48 options.config.multiserver = 'rolia';
51if self.model.hasProductFormSolution() || self.model.hasOpenClasses()
52 % Use qnsolver directly for product-
form networks or open networks
53 % (QN2LQN does not support Source/Sink
nodes for open networks)
54 line_debug(options, 'QNS: product-
form or open model, routing to qns_analyzer');
55 [QN,UN,RN,TN,CN,XN,runtime,actualMethod] = solver_qns_analyzer(sn, options);
57 line_debug(options, 'QNS: non-product-
form closed model, converting to LQN and using SolverLQNS');
58 lqnmodel=QN2LQN(self.model);
59 lqn = lqnmodel.getStruct;
61 lqnsoptions = SolverLQNS.defaultOptions;
62 lqnsoptions.verbose = false;
63 actualMethod = options.method; % Track the actual method for LQNS path
66 lqnsoptions.config.multiserver = 'conway';
67 actualMethod = 'conway';
69 lqnsoptions.config.multiserver = 'rolia';
70 actualMethod = 'rolia';
72 lqnsoptions.config.multiserver = 'zhou';
73 actualMethod = 'zhou';
75 lqnsoptions.config.multiserver = 'suri';
76 actualMethod = 'suri';
78 lqnsoptions.config.multiserver = 'reiser';
79 actualMethod = 'reiser';
81 lqnsoptions.config.multiserver = 'schmidt';
82 actualMethod = 'schmidt';
84 actualMethod = 'rolia'; % Default
is rolia for LQNS
86 AvgTable = SolverLQNS(lqnmodel,lqnsoptions).getAvgTable;
90 t = lqn.ashift + r + (i-1)*sn.nclasses;
91 QN(i,r) = AvgTable.QLen(t);
92 % lqns already reports the activity utilization per server, which
93 %
is the convention LINE uses at a finite-capacity station, so it
94 %
is carried over unscaled. Dividing by nservers here would report
95 % a utilization nservers times too low.
96 UN(i,r) = AvgTable.Util(t);
97 RN(i,r) = AvgTable.RespT(t);
98 WN(i,r) = AvgTable.ResidT(t);
99 TN(i,r) = AvgTable.Tput(t);
107 analyzer = @(sn) solver_qns_analyzer(sn, options);
111T = getAvgTputHandles(self);
112AN = sn_get_arvr_from_tput(sn, TN, T);
114% Apply default(...) convention based on actual method used
115if strcmp(method, 'default')
116 method = ['default/' actualMethod];
118 method = actualMethod;
121self.setAvgResults(QN,UN,RN,TN,AN,[],CN,XN,runtime,method);