1function
P = makeErgodic(self, targetNode)
2%
P = MAKEERGODIC(TARGETNODE)
4% Generates a modified routing matrix that makes the network ergodic
5% by routing jobs from absorbing stations back to a target node.
8% TARGETNODE: (optional) Node or node name to route absorbing stations to.
9% If not specified, uses the first Delay node or first station.
12%
P: Modified routing matrix (cell array) that can be used with model.link(
P)
14% Note: This method does NOT automatically relink the network. You must call
15% model.link(
P) with the returned routing matrix to apply the changes.
18%
P = model.makeErgodic();
21% Copyright (c) 2012-2026, Imperial College London
24[isErg, info] = self.isRoutingErgodic();
27 line_warning(mfilename,
'Routing is already ergodic. No changes needed.');
28 P = self.getLinkedRoutingMatrix();
32if isempty(info.absorbingStations)
33 line_warning(mfilename, 'No absorbing stations found, but network
is not ergodic. Manual intervention required.');
34 P = self.getLinkedRoutingMatrix();
38% Determine target node
39nodeNames = self.getNodeNames();
40stationIdxs = self.getStationIndexes();
42if nargin < 2 || isempty(targetNode)
43 % Find first Delay node as default target
46 if isa(self.
nodes{idx},
'Delay')
51 % If no Delay, use first station that
's not absorbing
54 if ~ismember(nodeNames{idx}, info.absorbingStations)
60 % Last resort: use first station
61 if isempty(targetIdx) && ~isempty(stationIdxs)
62 targetIdx = stationIdxs(1);
65 line_error(mfilename, 'Cannot find a suitable target node
for routing.
');
67 targetName = nodeNames{targetIdx};
69 if isa(targetNode, 'Node
')
70 targetName = targetNode.getName();
71 targetIdx = self.getNodeIndex(targetName);
73 targetName = targetNode;
74 targetIdx = self.getNodeIndex(targetName);
76 if isempty(targetIdx) || targetIdx <= 0
77 line_error(mfilename, sprintf('Target node
"%s" not found in network.
', targetName));
81% Get current routing matrix
84 P = self.initRoutingMatrix();
87K = self.getNumberOfClasses();
89% Modify routing for each absorbing station
90for i = 1:length(info.absorbingStations)
91 absStationName = info.absorbingStations{i};
92 absIdx = self.getNodeIndex(absStationName);
94 if absIdx == targetIdx
95 line_warning(mfilename, sprintf('Cannot route %s to itself. Skipping.
', absStationName));
99 % For each class, redirect self-loops to the target
103 % Clear all routing from this absorbing station
104 P{r,s}(absIdx, :) = 0;
107 % Route to target with same class
109 P{r,r}(absIdx, targetIdx) = 1.0;
113 line_printf('Routing from %s redirected to %s
for all
classes.\n
', absStationName, targetName);
116line_printf('\nTo apply changes, call: model.link(
P)\n
');