1classdef ClassServiceMapping < opt.DecisionVariable
2 % ClassServiceMapping Optimize
the class-to-station mapping by rerouting a
3 % job
class through a selected candidate station and bypassing
the others,
4 % preserving
default routing of every other
class. Mirrors native-Python
13 function obj = ClassServiceMapping(
jobclass, stations, name)
14 if nargin < 3 || isempty(name)
15 name = [
jobclass.getName()
'_mapping'];
17 obj@opt.DecisionVariable(name);
19 obj.stations = stations;
22 function c = getJobClass(obj), c = obj.jobclass; end
23 function s = getStations(obj), s = obj.stations; end
24 function b = getBounds(obj), b = opt.DecisionVariable.unitBounds(1); end
26 function v = decode(obj, x)
27 n = numel(obj.stations);
28 idx = floor(x(1) * n);
29 v = min(idx, n - 1); % 0-based index
32 function apply(obj, model, value)
33 if isempty(obj.stations),
return; end
34 v = min(max(value, 0), numel(obj.stations) - 1);
36 nodes = model.getNodes();
38 conn = opt.DecisionVariable.connectionMatrix(model);
40 selectedName = obj.stations{v + 1}.getName();
42 for k = 1:numel(obj.stations)
43 if ~strcmp(obj.stations{k}.getName(), selectedName)
44 idx = opt.DecisionVariable.indexOfNode(
nodes, obj.stations{k}.getName());
45 if idx > 0, blocked(end+1) = idx; end %#ok<AGROW>
49 mapped = opt.DecisionVariable.resolveClass(model, obj.jobclass);
50 if isempty(mapped),
return; end
52 rt = model.initRoutingMatrix();
53 classes = model.getClasses();
54 for ci = 1:numel(classes)
57 if strcmp(c.getName(), mapped.getName())
58 adj(:, blocked) = 0.0;
61 outDegree = sum(adj(i, :));
62 if outDegree <= 0, continue; end
65 rt.set(c, c,
nodes{i},
nodes{j}, adj(i, j) / outDegree);
73 function t = getVariableType(obj), t =
'class_mapping'; end