LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
makeErgodic.m
1function P = makeErgodic(self, targetNode)
2% P = MAKEERGODIC(TARGETNODE)
3%
4% Generates a modified routing matrix that makes the network ergodic
5% by routing jobs from absorbing stations back to a target node.
6%
7% Input:
8% TARGETNODE: (optional) Node or node name to route absorbing stations to.
9% If not specified, uses the first Delay node or first station.
10%
11% Output:
12% P: Modified routing matrix (cell array) that can be used with model.link(P)
13%
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.
16%
17% Example:
18% P = model.makeErgodic();
19% model.link(P);
20%
21% Copyright (c) 2012-2026, Imperial College London
22% All rights reserved.
23
24[isErg, info] = self.isRoutingErgodic();
25
26if isErg
27 line_warning(mfilename, 'Routing is already ergodic. No changes needed.');
28 P = self.getLinkedRoutingMatrix();
29 return;
30end
31
32if isempty(info.absorbingStations)
33 line_warning(mfilename, 'No absorbing stations found, but network is not ergodic. Manual intervention required.');
34 P = self.getLinkedRoutingMatrix();
35 return;
36end
37
38% Determine target node
39nodeNames = self.getNodeNames();
40stationIdxs = self.getStationIndexes();
41
42if nargin < 2 || isempty(targetNode)
43 % Find first Delay node as default target
44 targetIdx = [];
45 for idx = stationIdxs
46 if isa(self.nodes{idx}, 'Delay')
47 targetIdx = idx;
48 break;
49 end
50 end
51 % If no Delay, use first station that's not absorbing
52 if isempty(targetIdx)
53 for idx = stationIdxs
54 if ~ismember(nodeNames{idx}, info.absorbingStations)
55 targetIdx = idx;
56 break;
57 end
58 end
59 end
60 % Last resort: use first station
61 if isempty(targetIdx) && ~isempty(stationIdxs)
62 targetIdx = stationIdxs(1);
63 end
64 if isempty(targetIdx)
65 line_error(mfilename, 'Cannot find a suitable target node for routing.');
66 end
67 targetName = nodeNames{targetIdx};
68else
69 if isa(targetNode, 'Node')
70 targetName = targetNode.getName();
71 targetIdx = self.getNodeIndex(targetName);
72 else
73 targetName = targetNode;
74 targetIdx = self.getNodeIndex(targetName);
75 end
76 if isempty(targetIdx) || targetIdx <= 0
77 line_error(mfilename, sprintf('Target node "%s" not found in network.', targetName));
78 end
79end
80
81% Get current routing matrix
82P = self.sn.rtorig;
83if isempty(P)
84 P = self.initRoutingMatrix();
85end
86
87K = self.getNumberOfClasses();
88
89% Modify routing for each absorbing station
90for i = 1:length(info.absorbingStations)
91 absStationName = info.absorbingStations{i};
92 absIdx = self.getNodeIndex(absStationName);
93
94 if absIdx == targetIdx
95 line_warning(mfilename, sprintf('Cannot route %s to itself. Skipping.', absStationName));
96 continue;
97 end
98
99 % For each class, redirect self-loops to the target
100 for r = 1:K
101 for s = 1:K
102 if ~isempty(P{r,s})
103 % Clear all routing from this absorbing station
104 P{r,s}(absIdx, :) = 0;
105 end
106 end
107 % Route to target with same class
108 if ~isempty(P{r,r})
109 P{r,r}(absIdx, targetIdx) = 1.0;
110 end
111 end
112
113 line_printf('Routing from %s redirected to %s for all classes.\n', absStationName, targetName);
114end
115
116line_printf('\nTo apply changes, call: model.link(P)\n');
117
118end
Definition mmt.m:92