1function self = setReward(self, name, rewardFn)
2% SETREWARD Define a reward function on the network
for CTMC analysis
4% SELF = SETREWARD(SELF, NAME, REWARDFN)
6% NAME - String identifier
for the reward
7% REWARDFN - Function handle with signature:
8% @(state) ->
double (recommended -
new API)
9% @(state, sn) ->
double (backward compatible)
11% state: RewardState
object providing intuitive state access:
12% - state.at(node) - Jobs at node (all
classes)
13% - state.at(node,
class) - Jobs at node
for specific
class
14% - state.forClass(
class) - Jobs of
class (all
nodes)
16% RewardState also supports aggregation via RewardStateView:
17% - state.at(node).total() - Sum jobs across
classes at node
18% - state.at(node).max() - Max jobs across
classes at node
19% - state.at(node).min() - Min jobs across
classes at node
20% - state.at(node).count() - Count non-zero entries
22% sn: NetworkStruct (optional, for advanced users to access
23% rates, capacities, etc.)
25% Multiple rewards can be defined by calling setReward multiple times
26% with different names. Use clearRewards() to remove all rewards.
28% Recommended: Use Reward templates for common metrics
29% Reward.queueLength(node, [class])
30% Reward.utilization(node, [class])
31% Reward.blocking(node)
33% Examples (New API - Recommended):
35% model.setReward(
'QLen_Q1_C1', @(state) state.at(queue1, class1));
37% % Aggregation: sum across
classes
38% model.setReward(
'TotalJobs_Q1', @(state) state.at(queue1).total());
40% % Aggregation: sum across stations
41% model.setReward(
'ClassTotal_C1', @(state) state.forClass(class1).total());
44% model.setReward(
'Util_Q1', Reward.utilization(queue1));
45% model.setReward(
'Block_Q1', Reward.blocking(queue1));
47% % Custom composite rewards
48% model.setReward(
'Cost', @(state) ...
49% 2.0 * state.at(queue1).total() + ...
50% 5.0 * state.at(queue2).total());
52% % Advanced:
using NetworkStruct parameter (
for power-users)
53% model.setReward(
'AdvancedMetric', @(state, sn) ...
54% state.at(queue1, class1) * sn.rates(sn.nodeToStation(queue1.index), 1));
56% See also: RewardState, RewardStateView, Reward, getAvgReward
58% Copyright (c) 2012-2026, Imperial College London
61if ~ischar(name) && ~isstring(name)
62 error(
'Reward name must be a string');
64if ~isa(rewardFn,
'function_handle')
65 error('Reward function must be a function handle @(state, sn) ->
double');
68% Initialize reward cell array if needed
70 self.sn = NetworkStruct();
72if ~isfield(self.sn, 'reward') || isempty(self.sn.reward)
76% Check
if reward with
this name already exists and update it
79for i = 1:length(self.sn.reward)
80 if strcmp(self.sn.reward{i}.name, name)
81 self.sn.reward{i}.fn = rewardFn;
87% Add
new reward
if not found
91 reward.type =
'state';
92 self.sn.reward{end+1} = reward;