LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
iterate.m
1function [runtime, sruntime, results] = iterate(self, options)
2% ITERATE Perform LN solver iteration with optional MOL hierarchical approach
3%
4% [RUNTIME, SRUNTIME, RESULTS] = ITERATE(OPTIONS)
5%
6% For 'mol' method: Uses LQNS-style Method of Layers with nested iteration:
7% - Outer loop: Iterate on host (processor) layers until convergence
8% - Inner loop: Iterate on task layers until convergence (host demands fixed)
9%
10% For other methods ('default', 'moment3'): Uses flat iteration over all layers
11
12if nargin < 2
13 options = self.options;
14end
15
16line_debug('LN solver iterate starting: method=%s, nlayers=%d', self.options.method, self.nlayers);
17
18if ~strcmp(self.options.method, 'mol')
19 % Use parent implementation for default/moment3
20 line_debug('Using parent EnsembleSolver iterate method');
21 [runtime, sruntime, results] = iterate@EnsembleSolver(self, options);
22 return;
23end
24
25line_debug('Using MOL (Method of Layers) iteration');
26
27%% MOL (Method of Layers) implementation
28T0 = tic;
29E = getNumberOfModels(self);
30results = cell(1, E);
31sruntime = zeros(1, E);
32
33init(self);
34
35% Get MOL configuration parameters
36mol_task_inner_max = self.options.config.mol_task_inner_max;
37mol_task_inner_tol = self.options.config.mol_task_inner_tol;
38mol_host_outer_tol = self.options.config.mol_host_outer_tol;
39mol_min_steps = self.options.config.mol_min_steps;
40
41% Initialize MOL iteration state
42self.mol_it_host_outer = 0;
43delta_host = Inf;
44it = 0; % Total iteration counter for results indexing
45
46%% First iteration: analyze ALL layers to initialize results
47it = it + 1;
48if self.options.verbose
49 line_printf('\nMOL Initialization: Analyzing all layers');
50end
51self.pre(it);
52sruntime(it, 1:E) = 0;
53
54% Analyze all layers (host + task) in first iteration
55for e = 1:E
56 [results{it, e}, solverTime] = self.analyze(it, e);
57 sruntime(it, e) = solverTime;
58end
59self.results = results;
60
61% Full post-update after initial pass
62self.post(it);
63
64if self.options.verbose
65 line_printf(' Done.\n');
66end
67
68%% OUTER LOOP: Host (processor) layer iteration
69while (self.mol_it_host_outer < mol_min_steps || delta_host > mol_host_outer_tol) ...
70 && self.mol_it_host_outer < self.options.iter_max
71
72 self.mol_it_task_inner = 0;
73 delta_task = Inf;
74
75 % INNER LOOP: Task layer iteration (host layer demands kept FIXED)
76 while delta_task > mol_task_inner_tol && self.mol_it_task_inner < mol_task_inner_max
77 self.mol_it_task_inner = self.mol_it_task_inner + 1;
78 it = it + 1;
79
80 if self.options.verbose
81 line_printf('\nMOL Outer %d, Inner %d: ', self.mol_it_host_outer + 1, self.mol_it_task_inner);
82 end
83
84 self.pre(it);
85 sruntime(it, 1:E) = 0;
86
87 % Analyze TASK layers only (host demands remain fixed)
88 for e = self.taskLayerIndices
89 [results{it, e}, solverTime] = self.analyze(it, e);
90 sruntime(it, e) = solverTime;
91 end
92
93 % Copy host layer results from previous iteration (keeping them fixed)
94 for e = self.hostLayerIndices
95 results{it, e} = results{it-1, e};
96 end
97
98 self.results = results;
99
100 % Compute task delta
101 delta_task = self.computeTaskDelta();
102
103 % Update metrics and TASK layer demands only (not host layer demands)
104 self.updateMetrics(it);
105 self.updateThinkTimes(it);
106 if self.options.config.interlocking
107 self.updatePopulations(it);
108 end
109 % updateLayers updates service times - only refresh task layer solvers
110 self.updateLayers(it);
111 self.updateRoutingProbabilities(it);
112
113 % Reset only TASK layer solvers (keep host layers unchanged)
114 for e = self.taskLayerIndices
115 self.ensemble{e}.refreshChains();
116 switch self.solvers{e}.name
117 case {'SolverMVA', 'SolverNC'}
118 self.ensemble{e}.refreshRates();
119 otherwise
120 self.ensemble{e}.refreshProcesses();
121 end
122 self.solvers{e}.reset();
123 end
124
125 if self.options.verbose
126 line_printf('Task delta=%.6f', delta_task);
127 end
128 end
129
130 self.mol_it_host_outer = self.mol_it_host_outer + 1;
131 it = it + 1;
132
133 if self.options.verbose
134 line_printf('\nMOL Outer %d: Analyzing host layers... ', self.mol_it_host_outer);
135 end
136
137 self.pre(it);
138 sruntime(it, 1:E) = 0;
139
140 % Analyze HOST layers
141 for e = self.hostLayerIndices
142 [results{it, e}, solverTime] = self.analyze(it, e);
143 sruntime(it, e) = solverTime;
144 end
145
146 % Copy task layer results from previous iteration
147 for e = self.taskLayerIndices
148 results{it, e} = results{it-1, e};
149 end
150
151 self.results = results;
152
153 % Compute host delta
154 delta_host = self.computeHostDelta();
155
156 % Update metrics and HOST layer demands
157 self.updateMetrics(it);
158 self.updateThinkTimes(it);
159 if self.options.config.interlocking
160 self.updatePopulations(it);
161 end
162 self.updateLayers(it);
163 self.updateRoutingProbabilities(it);
164
165 % Reset HOST layer solvers (update their demands for next outer iteration)
166 for e = self.hostLayerIndices
167 self.ensemble{e}.refreshChains();
168 switch self.solvers{e}.name
169 case {'SolverMVA', 'SolverNC'}
170 self.ensemble{e}.refreshRates();
171 otherwise
172 self.ensemble{e}.refreshProcesses();
173 end
174 self.solvers{e}.reset();
175 end
176
177 if self.options.verbose
178 line_printf('Host delta=%.6f (%d inner iters)\n', ...
179 delta_host, self.mol_it_task_inner);
180 end
181end
182
183finish(self);
184runtime = toc(T0);
185
186if self.options.verbose
187 line_printf('\nMOL Summary: %d outer iterations, total runtime: %.3fs\n', ...
188 self.mol_it_host_outer, runtime);
189end
190end