/** Indicates if this lighptath request has lightpaths assigned * @return see above */ public boolean hasLightpathsAssigned () { return !d.getRoutes().isEmpty(); } /** Indicates if the request is blocked, meaning (i) has no lightpaths assigned, or (ii) assigned lightpaths are all down
/** * <p>Returns the routes associated to this demand, but only those that have no backup route themselves.</p> * <p><b>Important</b>: If network layer routing type is not {@link com.net2plan.utils.Constants.RoutingType#SOURCE_ROUTING SOURCE_ROUTING}, an exception is thrown.</p> * @return The set of routes * */ public SortedSet<Route> getRoutesHaveNoBackup () { return getRoutes ().stream().filter(e -> !e.hasBackupRoutes()).collect(Collectors.toCollection(TreeSet::new)); }
/** * <p>Returns the routes associated to this demand, but only those that are a backup route.</p> * <p><b>Important</b>: If network layer routing type is not {@link com.net2plan.utils.Constants.RoutingType#SOURCE_ROUTING SOURCE_ROUTING}, an exception is thrown.</p> * @return The set of routes * */ public SortedSet<Route> getRoutesAreBackup () { return getRoutes ().stream().filter(e -> e.isBackupRoute()).collect(Collectors.toCollection(TreeSet::new)); }
/** * <p>Returns the routes associated to this demand, but only those that are have themselves a backup route.</p> * <p><b>Important</b>: If network layer routing type is not {@link com.net2plan.utils.Constants.RoutingType#SOURCE_ROUTING SOURCE_ROUTING}, an exception is thrown.</p> * @return The set of routes * */ public SortedSet<Route> getRoutesHaveBackup () { return getRoutes ().stream().filter(e -> e.hasBackupRoutes()).collect(Collectors.toCollection(TreeSet::new)); }
/** * <p>Returns the routes associated to this demand, but only those that are not a backup route.</p> * <p><b>Important</b>: If network layer routing type is not {@link com.net2plan.utils.Constants.RoutingType#SOURCE_ROUTING SOURCE_ROUTING}, an exception is thrown.</p> * @return The set of routes * */ public SortedSet<Route> getRoutesAreNotBackup () { return getRoutes ().stream().filter(e -> !e.isBackupRoute()).collect(Collectors.toCollection(TreeSet::new)); }
/** Returns the set of lightpaths realizing this request. Typically one in unprotected ligtpaths, two in 1+1 settings * @return see above */ public List<WLightpathUnregenerated> getLightpaths () { return getNe().getRoutes().stream().map(r->new WLightpathUnregenerated(r)).collect(Collectors.toList()); } /** Returns the line rate of the lighptath request in Gbps
/** * <p>Gets the set of routes at the given layer from the given nodes (if {@code returnRoutesInBothDirections} is {@code true}, also the reversed routes are included). * If no layer is provided, the default layer is assumed.</p> * * @param originNode Origin node * @param destinationNode Destination node * @param returnRoutesInBothDirections Include routes in both directions * @param optionalLayerParameter Network layer (optional) * @return The {@code SortedSet} of routes between a pair of nodes */ public SortedSet<Route> getNodePairRoutes(Node originNode, Node destinationNode, boolean returnRoutesInBothDirections, NetworkLayer... optionalLayerParameter) { final SortedSet<Demand> demands = getNodePairDemands(originNode, destinationNode, returnRoutesInBothDirections, optionalLayerParameter); return demands.stream().map(d->d.getRoutes()).flatMap(e->e.stream()).collect(Collectors.toCollection(TreeSet::new)); }
/** 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(); } }
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; }
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); }
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>Sets the given demand as the bidirectional pair of this demand. If any of the demands was previously set as bidirectional * link of other demand, such relation is removed. The demands must be in the same layer, and have opposite end nodes * @param d the other demand */ public void setBidirectionalPair(Demand d) { checkAttachedToNetPlanObject(); d.checkAttachedToNetPlanObject(this.netPlan); if (this.bidirectionalPair == d) return; if (this.bidirectionalPair != null) for (Route r : getRoutes()) r.bidirectionalPair = null; if (d.layer != this.layer) throw new Net2PlanException ("Wrong layer"); if (d.ingressNode != this.egressNode || this.ingressNode != d.egressNode) throw new Net2PlanException ("Wrong end nodes"); if (this.bidirectionalPair != null) this.bidirectionalPair.bidirectionalPair = null; if (d.bidirectionalPair != null) d.bidirectionalPair.bidirectionalPair = null; this.bidirectionalPair = d; d.bidirectionalPair = this; }
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 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; }
@Override public List<AjtColumnInfo<Demand>> getNonBasicUserDefinedColumnsVisibleOrNot() { final List<AjtColumnInfo<Demand>> res = new LinkedList<> (); res.add(new AjtColumnInfo<Demand>(this , Node.class, null , "A", "Ingress node", null , d->d.getIngressNode() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Node.class, null , "B", "Egress node", null , d->d.getEgressNode() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Demand.class, null , "Bidirectional pair", "If the demand is bidirectional, provides its bidirectional pair", null , d->d.getBidirectionalPair() , AGTYPE.NOAGGREGATION, null)); res.add(new AjtColumnInfo<Demand>(this , Link.class, null , "Link coupled", "The link that this demand is coupled to (in this or other layer)", null , d->d.getCoupledLink() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "Offered traffic (" + getTableNetworkLayer().getLinkCapacityUnits() + ")", "Offered traffic by the demand", (d,val)->d.setOfferedTraffic((Double) val), d->d.getOfferedTraffic() , AGTYPE.SUMDOUBLE , null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "Carried traffic (" + getTableNetworkLayer().getLinkCapacityUnits() + ")", "Carried traffic by the demand", null , d->d.getCarriedTraffic() , AGTYPE.SUMDOUBLE , null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "% Lost traffic", "Percentage of the lost traffic by the demand", null, d->d.getOfferedTraffic() == 0? 0 : d.getBlockedTraffic() / d.getOfferedTraffic() , AGTYPE.NOAGGREGATION , d->d.getBlockedTraffic() > 0? Color.RED : Color.GREEN)); res.add(new AjtColumnInfo<Demand>(this , String.class, null , "QoS type", "A used-defined string identifying the type of traffic of the demand", (d,val)-> d.setQoSType((String)val) , d->d.getQosType(), AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Boolean.class, null , "Source routing?", "", (d,val)->d.setRoutingType((Boolean) val? RoutingType.SOURCE_ROUTING : RoutingType.HOP_BY_HOP_ROUTING), d->d.isSourceRouting() , AGTYPE.COUNTTRUE , null)); res.add(new AjtColumnInfo<Demand>(this , Boolean.class, null , "Is service chain?", "", null, d->d.isServiceChainRequest() , AGTYPE.COUNTTRUE , null)); res.add(new AjtColumnInfo<Demand>(this , String.class, null , "Resource types", "The sequence of resource types that has to be traversed by the routes of the demand, if it is a service chain", null, d->d.isSourceRouting()? d.getServiceChainSequenceOfTraversedResourceTypes().stream().collect(Collectors.joining(",")) : "" , AGTYPE.COUNTTRUE , null)); res.add(new AjtColumnInfo<Demand>(this , String.class, null , "Routing cycles", "Indicates whether there are routing cycles: loopless (no cycle in some route), open cycles (traffic reaches egress node after some cycles in some route), closed cycles (traffic does not reach the egress node in some route)", null, d->d.getRoutingCycleType().name() , AGTYPE.NOAGGREGATION , d->d.getRoutingCycleType() == RoutingCycleType.LOOPLESS? null : Color.ORANGE)); res.add(new AjtColumnInfo<Demand>(this , String.class, null , "Bifurcated?", "Indicates whether the demand is satisfied by more than one path from origin to destination", null, d->!d.isSourceRouting() ? "-" : (d.isBifurcated()) ? String.format("Yes (%d)", d.getRoutes().size()) : "No" , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Integer.class, null , "# routes", "Number of associated routes", null, d->!d.isSourceRouting() ? 0 : d.getRoutes().size() , AGTYPE.SUMINT, null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "Worst e2e lat (ms)", "Current worst case end-to-end propagation time in miliseconds (accumulating any lower layer propagation times if any)", null, d->d.getWorstCasePropagationTimeInMs() , AGTYPE.NOAGGREGATION , d->{ final double maxMs = d.getMaximumAcceptableE2EWorstCaseLatencyInMs(); return maxMs <= 0? null : (d.getWorstCasePropagationTimeInMs() > maxMs? Color.RED : null); })); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "Worst e2e length (km)", "Current worst case end-to-end propagation length in km (accumulating any lower layer propagation lengths if any)", null, d->d.getWorstCaseLengthInKm() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "Limit e2e lat (ms)", "Maximum end-to-end propagation time in miliseconds (accumulating any lower layer propagation times if any)", (d,val)-> d.setMaximumAcceptableE2EWorstCaseLatencyInMs((Double)val) , d->d.getMaximumAcceptableE2EWorstCaseLatencyInMs() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Double.class, null , "CAGR(%)" , "Compound annual growth factor for this demand", (d,val)->d.setOfferedTrafficPerPeriodGrowthFactor((Double) val), d->d.getOfferedTrafficPerPeriodGrowthFactor() , AGTYPE.NOAGGREGATION , null)); res.add(new AjtColumnInfo<Demand>(this , Integer.class, null , "#Monit points" , "Number of samples of the offered traffic stored, coming from a monitoring or forecasting traffic process", null , d->d.getMonitoredOrForecastedOfferedTraffic().getSize() , AGTYPE.NOAGGREGATION , null)); return res; }
private Pair<Map<Demand,Demand>,Map<Route,Route>> initializeNetPlanLinksBidirDemandsAndRoutes (NetPlan np) { /* Remove lower half demands from np */ np.removeAllRoutes(); for (Node n1 : np.getNodes()) for (Node n2 : np.getNodes()) if (n1.getIndex () > n2.getIndex ()) for (Demand d : np.getNodePairDemands(n1, n2,false)) d.remove (); np.addRoutesFromCandidatePathList(netPlan.computeUnicastCandidatePathList(null , tcfa_maxNumberPathsPerDemand.getInt(), tcfa_maxPathLengthInKm.getDouble(), tcfa_maxPathNumberOfHops.getInt(), -1, -1, -1, -1 , null)); /* Add symmetric demands and routes */ Map<Demand,Demand> opposite_d = new HashMap<Demand,Demand> (); Map<Route,Route> opposite_r = new HashMap<Route,Route> (); for (Demand d : new HashSet<Demand> (np.getDemands())) { final Demand opDemand = np.addDemand(d.getEgressNode(), d.getIngressNode(), d.getOfferedTraffic(), RoutingType.SOURCE_ROUTING , null); opposite_d.put(d,opDemand); opposite_d.put(opDemand,d); for (Route r : new HashSet<Route> (d.getRoutes ())) { final Route oppRoute = np.addRoute(opDemand, r.getCarriedTraffic(), r.getOccupiedCapacity() , oppositeSeqLinks (r.getSeqLinks()), null); opposite_r.put(r,oppRoute); opposite_r.put(oppRoute,r); } } return Pair.of(opposite_d,opposite_r); }
private void createCandidateRoutes (NetPlan netPlan , double [] c0) { if (useExistingRoutes.getBoolean()) { for (Demand d : netPlan.getDemands()) if (d.getRoutes().isEmpty()) throw new Net2PlanException ("There are no paths available for the demand " + d + ", from: " + d.getIngressNode() + " to " + d.getEgressNode()); } else { netPlan.removeAllRoutes(); Map<Link,Double> linkCostMap = new HashMap<Link,Double> (); for (Link e : netPlan.getLinks()) linkCostMap.put(e , c0 [e.getIndex()]); for (Demand d : netPlan.getDemands()) { List<List<Link>> shortestPaths = GraphUtils.getKLooplessShortestPaths(netPlan.getNodes (), netPlan.getLinks(), d.getIngressNode(), d.getEgressNode(), linkCostMap, numberOfRoutesPerDemand.getInt(), -1, -1, -1, -1, -1, -1); if (shortestPaths.isEmpty()) throw new Net2PlanException ("There are no paths available for the demand " + d + ", from: " + d.getIngressNode() + " to " + d.getEgressNode()); for (List<Link> path : shortestPaths) netPlan.addRoute(d, 0, 0, path, null); } } } }
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 ())); }