LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
writeJMVA.m
1function outputFileName = writeJMVA(sn, outputFileName, options)
2% FNAME = WRITEJMVA(SN, FNAME, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7%if ~self.model.hasProductFormSolution
8% line_error(mfilename,'JMVA requires the model to have a product-form solution.');
9%end
10
11%if self.model.hasClassSwitching
12% line_error(mfilename,'JMVA does not support class switching.');
13%end
14
15mvaDoc = com.mathworks.xml.XMLUtils.createDocument('model');
16mvaElem = mvaDoc.getDocumentElement;
17
18xmlnsXsi = 'http://www.w3.org/2001/XMLSchema-instance';
19mvaElem.setAttribute('xmlns:xsi', xmlnsXsi);
20mvaElem.setAttribute('xsi:noNamespaceSchemaLocation', 'JMTmodel.xsd');
21
22algTypeElement = mvaDoc.createElement('algType');
23switch options.method
24 case {'jmva.recal'}
25 if max(sn.nservers(isfinite(sn.nservers))) > 1
26 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
27 end
28 algTypeElement.setAttribute('name','RECAL');
29 case {'jmva.chow'}
30 if max(sn.nservers(isfinite(sn.nservers))) > 1
31 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
32 end
33 algTypeElement.setAttribute('name','Chow');
34 case {'jmva.bs','jmva.amva'}
35 if max(sn.nservers(isfinite(sn.nservers))) > 1
36 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
37 end
38 algTypeElement.setAttribute('name','Bard-Schweitzer');
39 case {'jmva.aql'}
40 if max(sn.nservers(isfinite(sn.nservers))) > 1
41 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
42 end
43 algTypeElement.setAttribute('name','AQL');
44 case {'jmva.lin'}
45 if max(sn.nservers(isfinite(sn.nservers))) > 1
46 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
47 end
48 algTypeElement.setAttribute('name','Linearizer');
49 case {'jmva.dmlin'}
50 if max(sn.nservers(isfinite(sn.nservers))) > 1
51 line_error(mfilename,sprintf('%s does not support multi-server stations.',options.method));
52 end
53 algTypeElement.setAttribute('name','De Souza-Muntz Linearizer');
54 %case {'jmva.ls'}
55 % algTypeElement.setAttribute('name','Logistic Sampling');
56 otherwise
57 algTypeElement.setAttribute('name','MVA');
58end
59algTypeElement.setAttribute('tolerance','1.0E-7');
60algTypeElement.setAttribute('maxSamples',num2str(options.samples));
61
62%%%%%%%%%%
63M = sn.nstations; %number of stations
64NK = sn.njobs'; % initial population per class
65C = sn.nchains;
66SCV = sn.scv;
67
68% determine service times
69ST = 1./sn.rates;
70ST(isnan(sn.rates))=0;
71SCV(isnan(SCV))=1;
72
73[Lchain,STchain,Vchain,alpha,Nchain,SCVchain] = sn_get_demands_chain(sn);
74
75%%%%%%%%%%
76parametersElem = mvaDoc.createElement('parameters');
77classesElem = mvaDoc.createElement('classes');
78classesElem.setAttribute('number',num2str(sn.nchains));
79stationsElem = mvaDoc.createElement('stations');
80stationsElem.setAttribute('number',num2str(sn.nstations - sum(sn.nodetype == NodeType.Source)));
81refStationsElem = mvaDoc.createElement('ReferenceStation');
82refStationsElem.setAttribute('number',num2str(sn.nchains));
83algParamsElem = mvaDoc.createElement('algParams');
84
85sourceid = sn.nodetype == NodeType.Source;
86for c=1:sn.nchains
87 if isfinite(sum(sn.njobs(sn.chains(c,:))))
88 classElem = mvaDoc.createElement('closedclass');
89 classElem.setAttribute('population',num2str(Nchain(c)));
90 classElem.setAttribute('name',sprintf('Chain%02d',c));
91 else
92 classElem = mvaDoc.createElement('openclass');
93 classElem.setAttribute('rate',num2str(sum(sn.rates(sourceid,sn.chains(c,:)))));
94 classElem.setAttribute('name',sprintf('Chain%02d',c));
95 end
96 classesElem.appendChild(classElem);
97end
98
99isLoadDep = false(1,sn.nstations);
100for i=1:sn.nstations
101 switch sn.nodetype(sn.stationToNode(i))
102 case NodeType.Delay
103 statElem = mvaDoc.createElement('delaystation');
104 statElem.setAttribute('name',sn.nodenames{sn.stationToNode(i)});
105 case NodeType.Queue
106 if sn.nservers(i) == 1
107 isLoadDep(i) = false;
108 statElem = mvaDoc.createElement('listation');
109 statElem.setAttribute('name',sn.nodenames{sn.stationToNode(i)});
110 statElem.setAttribute('servers',num2str(1));
111 else
112 isLoadDep(i) = true;
113 statElem = mvaDoc.createElement('ldstation');
114 statElem.setAttribute('name',sn.nodenames{sn.stationToNode(i)});
115 statElem.setAttribute('servers',num2str(1));
116 end
117 otherwise
118 continue
119 end
120 srvTimesElem = mvaDoc.createElement('servicetimes');
121 for c=1:sn.nchains
122 if isLoadDep(i)
123 statSrvTimeElem = mvaDoc.createElement('servicetimes');
124 statSrvTimeElem.setAttribute('customerclass',sprintf('Chain%02d',c));
125 ldSrvString = num2str(STchain(i,c));
126 % For open models (Inf population), use nservers as cutoff
127 % since service time is constant at S/c for n >= c
128 if any(isinf(NK))
129 ldLimit = sn.nservers(i);
130 else
131 ldLimit = sum(NK);
132 end
133
134 for n=2:ldLimit
135 ldSrvString = sprintf('%s;%s',ldSrvString,num2str(STchain(i,c)/min( n, sn.nservers(i) )));
136 end
137 statSrvTimeElem.appendChild(mvaDoc.createTextNode(ldSrvString));
138 srvTimesElem.appendChild(statSrvTimeElem);
139 else
140 statSrvTimeElem = mvaDoc.createElement('servicetime');
141 statSrvTimeElem.setAttribute('customerclass',sprintf('Chain%02d',c));
142 statSrvTimeElem.appendChild(mvaDoc.createTextNode(num2str(STchain(i,c))));
143 srvTimesElem.appendChild(statSrvTimeElem);
144 end
145 end
146 statElem.appendChild(srvTimesElem);
147 visitsElem = mvaDoc.createElement('visits');
148 for c=1:sn.nchains
149 statVisitElem = mvaDoc.createElement('visit');
150 statVisitElem.setAttribute('customerclass',sprintf('Chain%02d',c));
151 if STchain(i,c) > 0
152 val = Lchain(i,c) ./ STchain(i,c);
153 else
154 val = 0;
155 end
156 statVisitElem.appendChild(mvaDoc.createTextNode(num2str(val)));
157 visitsElem.appendChild(statVisitElem);
158 end
159 statElem.appendChild(visitsElem);
160
161 stationsElem.appendChild(statElem);
162end
163
164refstatchain = zeros(C,1);
165for c=1:sn.nchains
166 inchain = sn.inchain{c};
167 refstatchain(c) = sn.refstat(inchain(1));
168end
169
170for c=1:sn.nchains
171 classRefElem = mvaDoc.createElement('Class');
172 classRefElem.setAttribute('name',sprintf('Chain%02d',c));
173 % For open chains, the refstat is Source which is excluded from JMVA output.
174 % Use the first non-Source station as the reference station instead.
175 refIdx = refstatchain(c);
176 refNodeType = sn.nodetype(sn.stationToNode(refIdx));
177 if refNodeType == NodeType.Source
178 for ii=1:sn.nstations
179 nt = sn.nodetype(sn.stationToNode(ii));
180 if nt ~= NodeType.Source && nt ~= NodeType.Sink
181 refIdx = ii;
182 break;
183 end
184 end
185 end
186 classRefElem.setAttribute('refStation',sn.nodenames{sn.stationToNode(refIdx)});
187 refStationsElem.appendChild(classRefElem);
188end
189
190compareAlgsElem = mvaDoc.createElement('compareAlgs');
191compareAlgsElem.setAttribute('value','false');
192algParamsElem.appendChild(algTypeElement);
193algParamsElem.appendChild(compareAlgsElem);
194
195parametersElem.appendChild(classesElem);
196parametersElem.appendChild(stationsElem);
197parametersElem.appendChild(refStationsElem);
198mvaElem.appendChild(parametersElem);
199mvaElem.appendChild(algParamsElem);
200
201xmlwrite(outputFileName, mvaDoc);
202end