/** Returns the sequence of fibers traversed by this lp * @return see above */ public List<WFiber> getSeqFibers () { return r.getSeqLinks().stream().map(e->new WFiber(e)).collect(Collectors.toList()); } /** Changes the sequence of fibers traversed by this lightpath
/** Returns the sequence of traversed IP links, filtering out any VNF instance traversed * @return see above */ public List<WIpLink> getSequenceOfTraversedIpLinks () { return r.getSeqLinks().stream().map(ee->new WIpLink (ee)).filter(e->!e.isVirtualLink()).collect(Collectors.toCollection(ArrayList::new)); } /** Returns the sequence of traversed VNF instances, filtering out any IP link traversed
private static void checkSolution(NetPlan netPlan, String type11) { if (!netPlan.getLinksOversubscribed().isEmpty()) throw new Net2PlanException("Bad - Some link is oversubscribed (constraint violated)"); if (!netPlan.getDemandsBlocked().isEmpty()) throw new Net2PlanException("Bad - Some demand is blocked (constraint violated)"); for (Route route : netPlan.getRoutesAreNotBackup()) { if (route.getBackupRoutes().size () != 1) throw new RuntimeException("Bad"); final Route backupRoute = route.getBackupRoutes().get(0); if (type11.equalsIgnoreCase("srgDisjoint")) if (!Collections.disjoint(route.getSRGs(), backupRoute.getSRGs())) throw new RuntimeException("Bad"); else if (type11.equalsIgnoreCase("linkDisjoint")) if (!Collections.disjoint(route.getSeqLinks(), backupRoute.getSeqLinks())) throw new RuntimeException("Bad"); else throw new RuntimeException ("Bad"); } } }
private TBFToFromCarriedTraffic(Route route, boolean onlyThisLayer) { super(route.getNetPlan()); this.initialElement = route; this.onlyThisLayer = onlyThisLayer; this.initialFR = null; this.auxLayerInNodes = null; final Set<Link> linksAllLayers = new HashSet<>(); final Set<Demand> demandsAllLayers = new HashSet<>(); final Set<MulticastDemand> mDemandsAllLayers = new HashSet<>(); demandsAllLayers.add(route.getDemand()); linksAllLayers.addAll(route.getSeqLinks()); if (!onlyThisLayer) updatePropagationDownWards(linksAllLayers, linksAllLayers, demandsAllLayers, mDemandsAllLayers); if (!onlyThisLayer) updatePropagationUpWards(demandsAllLayers, mDemandsAllLayers, linksAllLayers, demandsAllLayers, mDemandsAllLayers); final Set<NetworkLayer> layersToKeepAllElements = onlyThisLayer ? Sets.difference(new HashSet<>(netPlan.getNetworkLayers()), Sets.newHashSet(route.getLayer())) : new HashSet<>(); updateAllButLinksDemandsMDemandsUsingExistingInfo(linksAllLayers, demandsAllLayers, mDemandsAllLayers, layersToKeepAllElements); }
/** Returns the amount of occupied capacity of the demand in a particular link * @param e see above * @return see above */ public double getOccupiedCapacity (Link e) { if (isSourceRouting()) { double accum = 0; for (Route r : getRoutes ()) if (r.getSeqLinks().contains(e)) accum += r.getOccupiedCapacity(e); return accum; } else { final Pair<Double,Double> info = this.cacheHbH_normCarriedOccupiedPerLinkCurrentState.get(e); return info == null? 0 : info.getSecond(); } }
/** * <p>Returns a vector with one element per route, containing the length in km of the first defined backup path for such route. * If a route has no backup path defined, an exception is thrown. If no layer is provided, the defaulf layer is assumed.</p> * * @param optionalLayerParameter network layer (optional) * @return The vector */ public DoubleMatrix1D getVectorRouteFirstBackupRouteLengthInKm(NetworkLayer... optionalLayerParameter) { NetworkLayer layer = checkInThisNetPlanOptionalLayerParameter(optionalLayerParameter); DoubleMatrix1D res = DoubleFactory1D.dense.make(layer.routes.size()); for (Route r : layer.routes) { if (!r.hasBackupRoutes()) throw new Net2PlanException("A route has no backup path"); final List<Link> path = r.getBackupRoutes().get(0).getSeqLinks(); final double length = path.stream().mapToDouble(e -> e.getLengthInKm()).sum(); res.set(r.index, length); } return res; }
/** * <p>Returns a vector with one element per route, containing the number of links of the first defined backup path for such route. * If a route has no backup path defined, an exception is thrown. If no layer is provided, the defaulf layer is assumed.</p> * * @param optionalLayerParameter network layer (optional) * @return The vector */ public DoubleMatrix1D getVectorRouteFirstBackupRouteNumberOfLinks(NetworkLayer... optionalLayerParameter) { NetworkLayer layer = checkInThisNetPlanOptionalLayerParameter(optionalLayerParameter); DoubleMatrix1D res = DoubleFactory1D.dense.make(layer.routes.size()); for (Route r : layer.routes) { if (!r.hasBackupRoutes()) throw new Net2PlanException("A route has no backup path"); final List<Link> path = r.getBackupRoutes().get(0).getSeqLinks(); res.set(r.index, path.size()); } return res; }
/** * Creates a route in the opposite direction as this, and associate both as bidirectional pairs. * If this route is already bidirectional, makes nothing and returns null. The traversed links must be bidirectional, * the demand cannot be a service chain. The opposite route carried traffic and occupied capacity is set to zero * @return the newly created route */ public Route createBidirectionalOppositePair () { checkAttachedToNetPlanObject(); if (this.isBidirectional()) return null; if (!this.demand.isSourceRouting()) throw new Net2PlanException ("The demand routing type must be source routing"); if (!this.demand.isBidirectional()) throw new Net2PlanException ("The demand must be bidirectional"); if (this.demand.isServiceChainRequest()) throw new Net2PlanException ("The demand cannot be of service chain type"); if (this.getSeqLinks().stream().anyMatch(e->!e.isBidirectional())) throw new Net2PlanException ("All the traversed links must be bidirectional"); final Demand bidiPairDemand = demand.getBidirectionalPair(); final Route r = netPlan.addRoute(bidiPairDemand, 0, 0, Lists.reverse(this.getSeqLinks()).stream().map(e->e.getBidirectionalPair()).collect(Collectors.toList()), null); this.bidirectionalPair = r; r.bidirectionalPair = this; return r; }
private static Pair<Route, Integer> addLightpath(NetPlan netPlan, Node ingressNode, Node egressNode, DoubleMatrix1D w_f, NetPlan cpl, DoubleMatrix2D wavelengthFiberOccupancy) { /* Try to find a feasible physical path, with a free wavelength along it, among the set of candidate paths */ final Demand cplDemand = cpl.getNodePairDemands(cpl.getNodeFromId(ingressNode.getId()), cpl.getNodeFromId(egressNode.getId()), false).iterator().next(); for (Route cplRoute : cplDemand.getRoutes()) { List<Link> seqLinks = new LinkedList<Link>(); for (Link cplLink : cplRoute.getSeqLinks()) seqLinks.add(netPlan.getLinkFromId(cplLink.getId())); final int wavelength = WDMUtils.spectrumAssignment_firstFit(seqLinks, wavelengthFiberOccupancy,1); if (wavelength != -1) return Pair.of(cplRoute, wavelength); } /* Otherwise, return null*/ return null; }
/** * <p>Returns {@code true} if the traffic of the demand is traversing an oversubscribed link, {@code false} otherwise.</p> * @return {@code true} if the traffic is traversing an oversubscribed link, {@code false} otherwise */ public boolean isTraversingOversubscribedLinks () { if (isSourceRouting()) { for (Route r : cache_routes) if (r.getCarriedTraffic() > Configuration.precisionFactor) for (Link e : r.getSeqLinks()) if (e.isOversubscribed()) return true; } else { for (Link e : cacheHbH_normCarriedOccupiedPerLinkCurrentState.keySet()) if (cacheHbH_normCarriedOccupiedPerLinkCurrentState.get(e).getSecond() > Configuration.precisionFactor) if (e.isOversubscribed()) return true; } return false; }
/** * Returns a matrix with as many rows as links and as many columns as routes in the given layer, * the position (e,r) contains the number of times that the first backup path of route r traveres link e * * @param optionalLayerParameter Network layer (optional) * @return The matrix */ public DoubleMatrix2D getMatrixLink2RouteFirstBackupRouteAssignment(NetworkLayer... optionalLayerParameter) { NetworkLayer layer = checkInThisNetPlanOptionalLayerParameter(optionalLayerParameter); DoubleMatrix2D delta_er = DoubleFactory2D.sparse.make(layer.links.size(), layer.routes.size()); for (Route r : layer.routes) { if (!r.hasBackupRoutes()) throw new Net2PlanException("A route has no backup path"); final List<Link> path = r.getBackupRoutes().get(0).getSeqLinks(); for (Link e : path) delta_er.set(e.index, r.index, delta_er.get(e.index, r.index) + 1); } return delta_er; }
/** Returns the carried traffic per link. * * @param links List of links * @param routes List of routes * @return Carried traffic per link */ public static DoubleMatrix1D convert_xp2ye(List<Link> links, List<Route> routes) { final int E = links.size(); DoubleMatrix1D y_e = DoubleFactory1D.dense.make(E); for (Route r : routes) for (Link e : r.getSeqLinks()) y_e.set(e.getIndex(), y_e.get(e.getIndex()) + r.getCarriedTraffic()); return y_e; }
private double getAverageAllStatesExtraCarriedTrafficAfterPotentialAllocation (Demand ipDemand , double lineRateGbps , List<Link> seqLinksIfSingleSRGToleranceIsNeeded) { double extraCarriedTraffic = Math.min(ipDemand.getBlockedTraffic() , lineRateGbps); if (singleSRGToleranceNot11Type) { for (SharedRiskGroup srg : netPlan.getSRGs()) { if (srg.affectsAnyOf(seqLinksIfSingleSRGToleranceIsNeeded)) continue; // no extra carried traffic Set<Route> affectedRoutes = srg.getAffectedRoutes(wdmLayer); double carriedTrafficThisFailure = 0; for (Route ipRoute : ipDemand.getRoutes()) { Set<Route> wdmRoutes = ipRoute.getSeqLinks().get(0).getCoupledDemand().getRoutes(); for (Route r : wdmRoutes) if (!affectedRoutes.contains(r)) carriedTrafficThisFailure += r.getCarriedTraffic(); } extraCarriedTraffic += Math.min(lineRateGbps , Math.max(0 , ipDemand.getOfferedTraffic() - carriedTrafficThisFailure)); } } return extraCarriedTraffic / (singleSRGToleranceNot11Type? (netPlan.getNumberOfSRGs() + 1) : 1); }
/** * Obtains the average route length among the current routes according to * certain link cost metric. Route lengths are weighted by their carried traffic. * * @param routes List of routes * @param linkCostMap Cost metric per link * @return Average route length */ public static double getRouteAverageLength(List<Route> routes , DoubleMatrix1D linkCostMap) { double R_d = 0; double average = 0; for (Route r : routes) { R_d += r.getCarriedTraffic(); for (Link e : r.getSeqLinks()) average += r.getCarriedTraffic() * ((linkCostMap == null)? 1 : linkCostMap.get(e.getIndex())); } return R_d == 0? 0 : average / R_d; }
private double computeHdFromPrices (Demand d) { DoubleMatrix1D infoIKnow_price_e = this.control_mostUpdatedLinkPriceKnownByDemand_de.viewRow (d.getIndex ()); /* compute the demand price as weighted sum in the routes of route prices */ double demandWeightedSumLinkPrices = 0; double demandCarriedTraffic = 0; for (Route r : d.getRoutes ()) { final double h_r = r.getCarriedTraffic(); demandCarriedTraffic += h_r; for (Link e : r.getSeqLinks()) demandWeightedSumLinkPrices += h_r * infoIKnow_price_e.get(e.getIndex ()); } demandWeightedSumLinkPrices /= demandCarriedTraffic; /* compute the new h_d */ final double new_hd = Math.max(this.control_minHd.getDouble() , Math.min(this.control_maxHd.getDouble(), Math.pow(demandWeightedSumLinkPrices, -1/this.control_fairnessFactor.getDouble()))); return new_hd; }
private double computeHdFromPrices (Demand d) { DoubleMatrix1D infoIKnow_price_e = this.cc_mostUpdatedLinkPriceKnownByDemand_de.viewRow(d.getIndex()); /* compute the demand price as weighted sum in the routes of route prices */ double demandWeightedSumLinkPrices = 0; double demandCarriedTraffic = 0; for (Route r : d.getRoutes ()) { final double h_r = r.getCarriedTraffic(); demandCarriedTraffic += h_r; for (Link e : r.getSeqLinks()) demandWeightedSumLinkPrices += h_r * infoIKnow_price_e.get(e.getIndex()); } //if (Math.abs(demandCarriedTraffic - this.currentNetPlan.getDemandCarriedTraffic(dIdMe)) > 1E-3) throw new RuntimeException ("Not all the traffic is carried"); demandWeightedSumLinkPrices /= demandCarriedTraffic; /* compute the new h_d */ final double new_hd = Math.max(this.cc_minHd.getDouble() , Math.min(this.cc_maxHd.getDouble(), Math.pow(demandWeightedSumLinkPrices, -1/this.cc_fairnessFactor.getDouble()))); return new_hd; }
private boolean isIpDemandFullySatisfied (Demand d) { if (d.getBlockedTraffic() > 1e-3) return false; if (singleSRGToleranceNot11Type) { for (SharedRiskGroup srg : netPlan.getSRGs()) { Set<Route> affectedRoutes = srg.getAffectedRoutes(wdmLayer); double carriedTrafficThisFailure = 0; for (Route ipRoute : d.getRoutes()) { final Set<Route> lps = ipRoute.getSeqLinks().get(0).getCoupledDemand().getRoutes(); for (Route wdmRoute : lps) if (!affectedRoutes.contains(wdmRoute)) carriedTrafficThisFailure += wdmRoute.getCarriedTraffic(); } if (carriedTrafficThisFailure + 1e-3 < d.getOfferedTraffic()) return false; } } return true; }
@Override public List<AjtColumnInfo<Route>> getNonBasicUserDefinedColumnsVisibleOrNot() { final NetPlan np = callback.getDesign(); final NetworkLayer layer = this.getTableNetworkLayer(); final List<AjtColumnInfo<Route>> res = new LinkedList<> (); res.add(new AjtColumnInfo<Route>(this , Demand.class, null , "Demand", "Associated demand", null , d->d.getDemand() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Node.class, null , "A", "Ingress node", null , d->d.getIngressNode() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Node.class, null , "B", "Egress node", null , d->d.getEgressNode() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Boolean.class, null , "Is up?", "The route is considered up if it is not traversing failed links or nodes", null , d->!d.isDown() , AGTYPE.COUNTTRUE, r->r.getCarriedTrafficInNoFailureState() > 0 && r.isDown()? Color.RED : null)); res.add(new AjtColumnInfo<Route>(this , Boolean.class, null , "Trav. 0-cap links?", "Indicates if the route is traversing links with zero capacity", null , d->!d.isTraversingZeroCapLinks() , AGTYPE.COUNTTRUE, r->r.getCarriedTrafficInNoFailureState() > 0 && r.isTraversingZeroCapLinks()? Color.RED : null)); res.add(new AjtColumnInfo<Route>(this , Demand.class, null , "Bidirectional pair", "If the route is bidirectional, provides its bidirectional pair", null , d->d.getBidirectionalPair() , AGTYPE.NOAGGREGATION, null)); res.add(new AjtColumnInfo<Route>(this , Collection.class, null , "Main routes", "If this is a backup route, shows the routes I am backing up", null , d->d.getRoutesIAmBackup(), AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Collection.class, null , "Backup routes", "If this is a main route, shows the its back up routes", null , d->d.getBackupRoutes(), AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Double.class, null , "Carried traffic (" + layer.getDemandTrafficUnits() + ")", "Carried traffic by the route", (d,val)->d.setCarriedTraffic((Double) val , null), d->d.getCarriedTraffic() , AGTYPE.SUMDOUBLE , null)); res.add(new AjtColumnInfo<Route>(this , Double.class, null , "Occupied capacity (" + layer.getLinkCapacityUnits() + ")", "Occupied capacity in the traversed links. If the occupied capacity is different in different links, no information is shown", null , d->d.isOccupyingDifferentCapacitiesInDifferentLinksInNoFailureState()? "--" : d.getSeqOccupiedCapacitiesIfNotFailing().get(0) , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Collection.class, null , "# links", "Number of traversed links", null , d->d.getSeqLinks() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Collection.class, null , "# resources", "Number of traversed resources", null , d->d.getSeqResourcesTraversed() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Route>(this , Double.class, null , "Length (km)", "Length of the route, considering also the length of the lower layer links traversed if any", null , d->d.getLengthInKm() , AGTYPE.MAXDOUBLE , null)); res.add(new AjtColumnInfo<Route>(this , Double.class, null , "E2e latency (ms)", "End-to-end latency considering links and resources traversed, and propagation time in lower layer links if any", null , d->d.getPropagationDelayInMiliseconds() , AGTYPE.MAXDOUBLE , d->{ final double m = d.getDemand().getMaximumAcceptableE2EWorstCaseLatencyInMs(); if (m >= 0) return null; return d.getPropagationDelayInMiliseconds () > m? Color.RED : null; })); return res; }
private double computeHdFromPrices (Demand d) { DoubleMatrix1D infoIKnow_price_e = this.control_mostUpdatedLinkPriceKnownDemand_de.viewRow(d.getIndex ()); /* compute the demand price as weighted sum in the routes of route prices */ double demandWeightedSumLinkPrices = 0; double demandCarriedTraffic = 0; for (Route r : d.getRoutes ()) { final double h_r = r.getCarriedTraffic(); demandCarriedTraffic += h_r; for (Link e : r.getSeqLinks()) demandWeightedSumLinkPrices += h_r * infoIKnow_price_e.get(e.getIndex ()); } //if (Math.abs(demandCarriedTraffic - this.currentNetPlan.getDemandCarriedTraffic(dIdMe)) > 1E-3) throw new RuntimeException ("Not all the traffic is carried"); demandWeightedSumLinkPrices /= demandCarriedTraffic; /* compute the new h_d */ final double alpha = (demandType.get(d.getIndex ()) == 1)? this.cc_control_fairnessFactor_1.getDouble() : this.cc_control_fairnessFactor_2.getDouble(); final double weight = (demandType.get(d.getIndex ()) == 1)? this.cc_control_weightFairness_1.getDouble() : this.cc_control_weightFairness_2.getDouble(); final double new_hd = Math.max(this.cc_control_minHd.getDouble() , Math.min(this.cc_control_maxHd.getDouble(), Math.pow(demandWeightedSumLinkPrices/weight, -1/alpha))); return new_hd; }
private void updateDemandRoutingFromWeightsKnown (Demand d) { final Node a_d = d.getIngressNode(); final double h_d = d.getOfferedTraffic(); final DoubleMatrix1D weightsKnown_e = this.routing_mostUpdatedLinkPriceKnownByNode_ne.viewRow(a_d.getIndex ()); DoubleMatrix1D a_k = DoubleFactory1D.dense.make (R); for (Route r : d.getRoutes()) { double val = 0; for (Link e : r.getSeqLinks()) val += weightsKnown_e.get(e.getIndex()) + 1; a_k.set(r.getIndex (), val); } DoubleMatrix1D x_r = GradientProjectionUtils.regularizedProjection_sumEquality (a_k , control_routeIndexes_d [d.getIndex ()] , null , h_d , this.gradient_regularizationEpsilon.getDouble()); for (Route r : d.getRoutes ()) r.setCarriedTraffic(x_r.get(r.getIndex ()) , x_r.get(r.getIndex ())); }