Diseño Óptimo de Redes con Programación Lineal en Java: Código Net2Plan y GLPK
for (Node n1 : netPlan.getNodes()) /* ya que dice por cada par de nodos (dos bucles for) */
{
for (Node n2 : netPlan.getNodes())
{
if (n1 != n2)
{
netPlan.addLink(n1, n2, 0, netPlan.getNodePairEuclideanDistance(n1, n2), 200000, null);
}
}
}
OptimizationProblem op = new OptimizationProblem();
/* 7777777777777 */
final int D = netPlan.getNumberOfDemands();
final int E = netPlan.getNumberOfLinks();
op.addDecisionVariable("zd", false, new int[]{1, E}, 0, Double.MAX_VALUE); /* variable por cada enlace que existe, necesitaremos saber el número de estos (mirar línea de arriba) */
op.addDecisionVariable("xd", false, new int[]{D, E}, 0, Double.MAX_VALUE); /* tráfico de la demanda D que circula por el enlace E */
op.addDecisionVariable("ue", false, new int[]{1, E}, 0, maximunLinkCapacity);
/* 88888888888888 *//* parámetros de entrada, aquellos valores de la función objetivo que no son variables de decisión */
op.setInputParameter("d_e", netPlan.getVectorLinkLengthInKm(), "row");
op.setInputParameter("c_km", costPerKm);
op.setInputParameter("c_Gbps", costPerGbps);
op.setObjectiveFunction("minimize", "c_km * d_e * z_e' + c_Gbps * sum(u_e)");
op.setInputParameter("U", maximunLinkCapacity);
for (Link e : netPlan.getLinks())
{
op.setInputParameter("e", e.getIndex());
op.addConstraint("u_e(e) <= U * z_e(e)");
}
/* leemos de derecha a izquierda en el PDF la segunda restricción para guiarnos en la construcción del código */
for (Node n : netPlan.getNodes())
{
op.setInputParameter("deltaPlus", NetPlan.getIndexes(n.getOutgoingLinks()), "row");
op.setInputParameter("deltaMinus", NetPlan.getIndexes(n.getIncomingLinks()), "row");
for (Demand d : netPlan.getDemands())
{
op.setInputParameter("d", d.getIndex());
op.setInputParameter("h_d", d.getOfferedTraffic());
if (n == d.getIngressNode()) // si es el nodo origen de la demanda
op.addConstraint("sum(x_de(d,deltaPlus)) - sum(x_de(d,deltaMinus)) == h_d");
else if (n == d.getEgressNode()) // si es el nodo destino de la demanda
op.addConstraint("sum(x_de(d,deltaPlus)) - sum(x_de(d,deltaMinus)) == -h_d");
else
op.addConstraint("sum(x_de(d,deltaPlus)) - sum(x_de(d,deltaMinus)) == 0");
}
}
/* Add the link capacity constraints (all links carry less or equal traffic than its capacity) */
for (Link e : netPlan.getLinks())
{
op.setInputParameter("e", e.getIndex());
op.addConstraint("sum(x_de(all/* todos los enlaces */,e)) <= u_e(e)");
}
/* call the solver to solve the problem */
op.solve("glpk", "maxSolverTimeInSeconds", 10);
/* An optimal solution was not found */
if (!op.solutionIsFeasible())
throw new Net2PlanException("not found");
/* Set the routing according to the optimum solutions */
final DoubleMatrix2D x_de = op.getPrimalSolution("x_de").view2D();
netPlan.setRoutingFromDemandLinkCarriedTraffic(x_de, false, false);
/* Set the capacity in the links according to the a_e variables */
final double[] u_e = op.getPrimalSolution("u_e").to1DArray();
for (Link e : netPlan.getLinks())
e.setCapacity(u_e[e.getIndex()]);
/* Remove all the links that have not capacity */
netPlan.removeAllLinksUnused(0.01);
return "Ok!"; // this is the message that will be shown in the screen at the end of the algorithm
}