LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
example_infer_ubo_changepoint.m
1clear node jobclass
2%% Example: UBO sliding-window change-point detection (open network)
3%
4% Service demand changes from D=0.3 to D=0.6 at t=100.
5% A sliding window of size W is used to estimate demands online.
6%
7% Copyright (c) 2012-2026, Imperial College London
8% All rights reserved.
9
10%% define model
11model = Network('model');
12
13node{1} = Delay(model, 'Delay');
14node{2} = Queue(model, 'Queue1', SchedStrategy.FCFS);
15node{3} = Source(model, 'Source');
16node{4} = Sink(model, 'Sink');
17
18jobclass{1} = OpenClass(model, 'Class1', 0);
19jobclass{2} = OpenClass(model, 'Class2', 0);
20
21node{1}.setService(jobclass{1}, Exp.fitMean(1.0));
22node{1}.setService(jobclass{2}, Exp.fitMean(1.0));
23node{2}.setService(jobclass{1}, Exp(NaN));
24node{2}.setService(jobclass{2}, Exp(NaN));
25node{3}.setArrival(jobclass{1}, Exp(1.0));
26node{3}.setArrival(jobclass{2}, Exp(0.5));
27
28P = model.initRoutingMatrix;
29P{1,1} = [0,1,0,0; 0,0,0,1; 1,0,0,0; 0,0,0,0];
30P{2,2} = [0,1,0,0; 0,0,0,1; 1,0,0,0; 0,0,0,0];
31model.link(P);
32
33%% Generate data with change point
34% Class 1 demand changes: D1=0.1 -> 0.3
35% Class 2 demand stays: D2=0.2
36n = 200;
37changeT = 100;
38D1_before = 0.1; D1_after = 0.3;
39D2 = 0.2;
40lambda1 = 1.0; lambda2 = 0.5;
41noise = 0.01;
42
43ts = (1:n)';
44arvr1_samples = lambda1*ones(n,1) + randn(n,1)*noise;
45arvr2_samples = lambda2*ones(n,1) + randn(n,1)*noise;
46
47util_samples = zeros(n,1);
48respt1_samples = zeros(n,1);
49respt2_samples = zeros(n,1);
50for t = 1:n
51 if t <= changeT
52 d1 = D1_before;
53 else
54 d1 = D1_after;
55 end
56 U = lambda1*d1 + lambda2*D2 + randn(1)*noise;
57 U = max(0.01, min(0.95, U));
58 util_samples(t) = U;
59 respt1_samples(t) = d1 / (1 - U) + randn(1)*noise*0.1;
60 respt2_samples(t) = D2 / (1 - U) + randn(1)*noise*0.1;
61end
62
63%% Sliding-window estimation
64W = 30;
65est1 = zeros(n - W + 1, 1);
66est2 = zeros(n - W + 1, 1);
67
68for t = W:n
69 idx = (t-W+1):t;
70
71 node{2}.setService(jobclass{1}, Exp(NaN));
72 node{2}.setService(jobclass{2}, Exp(NaN));
73 model.reset();
74
75 estoptions = ParamEstimator.defaultOptions;
76 estoptions.method = 'ubo';
77 se = ParamEstimator(model, estoptions);
78
79 se.addSamples(SampledMetric(MetricType.ArvR, ts(idx), arvr1_samples(idx), node{2}, jobclass{1}));
80 se.addSamples(SampledMetric(MetricType.ArvR, ts(idx), arvr2_samples(idx), node{2}, jobclass{2}));
81 se.addSamples(SampledMetric(MetricType.RespT, ts(idx), respt1_samples(idx), node{2}, jobclass{1}));
82 se.addSamples(SampledMetric(MetricType.RespT, ts(idx), respt2_samples(idx), node{2}, jobclass{2}));
83 se.addSamples(SampledMetric(MetricType.Util, ts(idx), util_samples(idx), node{2}));
84 se.interpolate();
85 estVal = se.estimateAt(node{2});
86 est1(t - W + 1) = estVal(1);
87 est2(t - W + 1) = estVal(2);
88end
89
90%% Report results
91fprintf(1, '\n=== UBO Change-Point Detection (2-class) ===\n');
92fprintf(1, 'Class 1: D=%.1f (t<=100), D=%.1f (t>100)\n', D1_before, D1_after);
93fprintf(1, 'Class 2: D=%.1f (constant)\n', D2);
94fprintf(1, 'Window size: %d\n\n', W);
95
96checkpoints = [W, 50, 80, 100, 110, 120, 130, 150, 180, 200];
97fprintf(1, '%6s %8s %8s %8s %8s\n', 't', 'Est D1', 'True D1', 'Est D2', 'True D2');
98fprintf(1, '%6s %8s %8s %8s %8s\n', '------', '--------', '--------', '--------', '--------');
99for i = 1:length(checkpoints)
100 t = checkpoints(i);
101 if t >= W && t <= n
102 e1 = est1(t - W + 1);
103 e2 = est2(t - W + 1);
104 if t <= changeT
105 trueD1 = D1_before;
106 else
107 trueD1 = D1_after;
108 end
109 fprintf(1, '%6d %8.4f %8.4f %8.4f %8.4f\n', t, e1, trueD1, e2, D2);
110 end
111end
112
113%% Plot
114figure;
115tAxis = (W:n)';
116subplot(2,1,1);
117plot(tAxis, est1, 'b-', 'LineWidth', 1.5); hold on;
118yline(D1_before, 'r--', 'LineWidth', 1);
119yline(D1_after, 'r--', 'LineWidth', 1);
120xline(changeT, 'k:', 'Change point', 'LineWidth', 1);
121ylabel('Demand'); title('Class 1 (changes D=0.1 -> D=0.3)');
122grid on;
123
124subplot(2,1,2);
125plot(tAxis, est2, 'b-', 'LineWidth', 1.5); hold on;
126yline(D2, 'r--', 'LineWidth', 1);
127xline(changeT, 'k:', 'Change point', 'LineWidth', 1);
128xlabel('Time'); ylabel('Demand'); title('Class 2 (constant D=0.2)');
129grid on;