Tutorial 9: Optimizing Performance Metrics
This example shows how to optimize a performance metric using LINE. We find the optimal routing probabilities that minimize average response times for two parallel processor sharing queues in a closed network.
model = Network('LoadBalCQN');
% Block 1: nodes
delay = Delay(model,'Think');
queue1 = Queue(model, 'Queue1', SchedStrategy.PS);
queue2 = Queue(model, 'Queue2', SchedStrategy.PS);
% Block 2: classes
cclass = ClosedClass(model, 'Job1', 16, delay);
delay.setService(cclass, Exp(1));
queue1.setService(cclass, Exp(0.75));
queue2.setService(cclass, Exp(0.50));
% Block 3: topology
P = model.initRoutingMatrix;
P{cclass}(queue1, delay) = 1.0;
P{cclass}(queue2, delay) = 1.0;
model.link(P);
% Block 4: solution - optimization
objFun = @(p) evalOptimization(p, model, P, cclass, delay, queue1, queue2);
p_opt = fminbnd(objFun, 0, 1);
function R = evalOptimization(p, model, P, cclass, delay, queue1, queue2)
P{cclass}(delay, queue1) = p;
P{cclass}(delay, queue2) = 1-p;
model.relink(P);
R = MVA(model,'exact','verbose',false).getAvgSysRespT;
end
from line_solver import *
from scipy import optimize
model = Network('LoadBalCQN')
# Block 1: nodes
delay = Delay(model, 'Think')
queue1 = Queue(model, 'Queue1', SchedStrategy.PS)
queue2 = Queue(model, 'Queue2', SchedStrategy.PS)
# Block 2: classes
cclass = ClosedClass(model, 'Job1', 16, delay)
delay.set_service(cclass, Exp(1))
queue1.set_service(cclass, Exp(0.75))
queue2.set_service(cclass, Exp(0.50))
# Block 3: topology
P = model.init_routing_matrix()
P.set(cclass, cclass, queue1, delay, 1.0)
P.set(cclass, cclass, queue2, delay, 1.0)
model.link(P)
def objFun(p):
P.set(cclass, cclass, delay, queue1, p)
P.set(cclass, cclass, delay, queue2, 1.0 - p)
model.relink(P)
R = MVA(model, method='exact', verbose=False).avg_sys_resp_t()
return R[0]
p_opt = optimize.fminbound(objFun, 0, 1)
print(f"Optimal routing probability: {p_opt}")
import de.xypron.jcobyla.Calcfc;
import de.xypron.jcobyla.Cobyla;
import java.util.function.Function;
import jline.lang.ClosedClass;
import jline.lang.RoutingMatrix;
import jline.lang.nodes.Delay;
import jline.solvers.mva.MVA;
Network model = new Network("LoadBalCQN");
Delay delay = new Delay(model, "Think");
Queue queue1 = new Queue(model, "Queue1", SchedStrategy.PS);
Queue queue2 = new Queue(model, "Queue2", SchedStrategy.PS);
ClosedClass cclass = new ClosedClass(model, "Job1", 16, delay);
delay.setService(cclass, new Exp(1));
queue1.setService(cclass, new Exp(0.75));
queue2.setService(cclass, new Exp(0.50));
RoutingMatrix P = model.initRoutingMatrix();
P.set(cclass, queue1, delay, 1.0);
P.set(cclass, queue2, delay, 1.0);
model.link(P);
Function<Double, Double> routingModel = p -> {
P.set(cclass, delay, queue1, p);
P.set(cclass, delay, queue2, 1 - p);
model.reset();
model.relink(P);
return (Double) new MVA(model, "exact").getAvgSysRespT().get(0);
};
Calcfc objFun = (n, m, x, con) -> routingModel.apply(x[0]);
double[] p = {0.5};
Cobyla.findMinimum(objFun, 1, 0, p, 0.5, 1.0e-8, 0, 10000);
System.out.println("Optimal p: " + p[0]);
#include "line/solvers/mva/solver_mva_runner.h"
Network model("LoadBalCQN");
Delay delay(model, "Think");
Queue queue1(model, "Queue1", SchedStrategy::PS);
Queue queue2(model, "Queue2", SchedStrategy::PS);
ClosedClass cclass(model, "Job1", 16, delay);
delay.set_service(cclass, Exp(1.0));
queue1.set_service(cclass, Exp(0.75));
queue2.set_service(cclass, Exp(0.50));
Routing P;
P.set(queue1, delay, 1.0);
P.set(queue2, delay, 1.0);
const auto objFun = [&](double p) {
Routing Pp = P;
Pp.set(delay, queue1, p);
Pp.set(delay, queue2, 1.0 - p);
model.link(Pp);
mva::MvaOptions opt;
opt.method = "exact";
const mva::AvgResult<double> r =
mva::solver_mva_run_analyzer(model.get_struct(), opt, Matrix<double>());
return r.CN[cclass - 1];
};
// Golden-section search on [0, 1].
double a = 0.0, b = 1.0;
const double phi = 0.5 * (std::sqrt(5.0) - 1.0);
double c = b - phi * (b - a), d = a + phi * (b - a);
double fc = objFun(c), fd = objFun(d);
while (b - a > 1e-8) {
if (fc < fd) { b = d; d = c; fd = fc; c = b - phi * (b - a); fc = objFun(c); }
else { a = c; c = d; fc = fd; d = a + phi * (b - a); fd = objFun(d); }
}
const double pOpt = 0.5 * (a + b);
Expected Output
Optimal routing probability: 0.6105