def time_interval_correspondence(self, t): """ :param t: timepoint :return: lastTime: lowerBound of flowInterval containing time """ if Utilities.is_eq_tol(t, 0): return 0 for lowerBoundTime in self.lowerBoundsToIntervalDict: if Utilities.is_geq_tol(t, lowerBoundTime): lastTime = lowerBoundTime return lastTime
def is_full(self, v, w, t): """ :param v: tail of edge :param w: head of edge :param t: time :return: True if d_(v,w)(t) ~= storage(v,w) """ try: load = self.arc_load(v, w, t) return Utilities.is_eq_tol(load, self.network[v][w]['storage']) except TypeError: return False
def assert_ntf(self): """Check if computed NTF really is an NTF""" # Works only on shortest path network p = lambda e: max( [self.NTFNodeLabelDict[e[0]], self.NTFEdgeFlowDict[e] / self.network[e[0]][e[1]]['outCapacity']]) \ if e not in self.resettingEdges \ else self.NTFEdgeFlowDict[e] / self.network[e[0]][e[1]]['outCapacity'] for w in self.shortestPathNetwork: if self.shortestPathNetwork.in_edges(w): minimalCongestion = min( map(p, self.shortestPathNetwork.in_edges(w))) assert (Utilities.is_eq_tol(minimalCongestion, self.NTFNodeLabelDict[w])) for v, w in self.shortestPathNetwork.edges(): minimalCongestion = min( map(p, self.shortestPathNetwork.in_edges(w))) assert (Utilities.is_eq_tol(self.NTFEdgeFlowDict[v, w], 0) or Utilities.is_eq_tol(p((v, w)), minimalCongestion)) # Check if actually an s-t-flow for w in self.shortestPathNetwork: m = 0 incomingEdges = self.shortestPathNetwork.in_edges(w) outgoingEdges = self.shortestPathNetwork.out_edges(w) for e in incomingEdges: m += self.NTFEdgeFlowDict[e] for e in outgoingEdges: m -= self.NTFEdgeFlowDict[e] if w == 's': assert (Utilities.is_eq_tol(m, (-1) * self.inflowRate)) elif w == 't': assert (Utilities.is_eq_tol(m, self.inflowRate)) else: assert (Utilities.is_eq_tol(m, 0))
def get_outflow(self, v, w, t): """ :param v: tail of edge :param w: head of edge :param t: time :return: f_(v,w)^-(t), i.e. outflow rate of e=(v,w) at time t (picking the newest value) """ if Utilities.is_eq_tol(t, 0): return 0 for wTimeLower, wTimeUpper in self.network[v][w]['outflow']: if Utilities.is_between_tol(wTimeLower, t, wTimeUpper): # t lies between l_w(theta_k) and l_w(theta_k+1) lastOutflow = self.network[v][w]['outflow'][(wTimeLower, wTimeUpper)] return lastOutflow
def change_edge_show_status(self, show=True): """ Change whether zero-flow edges are visible or not """ if show: self.network = self.originalNetwork.copy() # self.network = deepcopy(self.originalNetwork) else: removedEdges = [] for edge in self.network.edges(): if Utilities.is_eq_tol(self.NTFEdgeFlowDict[edge], 0): removedEdges.append(edge) self.network.remove_edges_from(removedEdges) isolated_nodes = list(nx.isolates(self.network)) self.network.remove_nodes_from(isolated_nodes) self.init_plot()
def draw_flow(self, edge, src, dst): """ Draw flow animation :param edge: edge = vw to draw :param src: position of v :param dst: position of w """ if self.edgeColoring[edge]: for fk in self.edgeColoring[edge].keys(): self.edgeColoring[edge][fk].remove() self.edgeColoring[edge].clear() if self.widthReferenceSize[edge]: self.widthReferenceSize[edge].clear() if self.visualQueueColoring[edge]: self.visualQueueColoring.remove() v, w = edge time = self.timePoints[self.currentTimeIndex] transitTime = self.network[v][w]['transitTime'] src = np.array(src) dst = np.array(dst) s = dst - src flowOnEdgeList = [self.flowOnEntireEdge[edge][fk][time] for fk in range(len(self.nashFlow.flowIntervals))] totalFlowOnEdge = sum(flowOnEdgeList) if Utilities.is_eq_tol(totalFlowOnEdge, 0): return overflowBlocks = [] for fk in range(len(self.nashFlow.flowIntervals)): if Utilities.is_eq_tol(self.flowOnEdgeNotQueue[edge][fk][time], 0): # No flow on edgeNotQueue at this time continue inflowInterval, outflowInterval = self.nashFlow.animationIntervals[edge][fk] vTimeLower, vTimeUpper = inflowInterval inflow = float(self.network[v][w]['inflow'][(vTimeLower, vTimeUpper)]) # These position factors are using that the amount on the edgeNotQueue has to be positive at this point # This implies that vTimeLower <= time <= vTimeUpper + transitTime startFac = float(time - vTimeUpper) / transitTime if time > vTimeUpper else 0 endFac = float(time - vTimeLower) / transitTime if time <= vTimeLower + transitTime else 1 start = src + startFac * s end = src + endFac * s edge_pos = np.asarray([(start, end)]) edge_color = tuple(colorConverter.to_rgba(self.NTFColors[fk % len(self.NTFColors)], alpha=1)) widthRatioScale = min(1, inflow/self.maxWidthFlowSize[edge]) self.widthReferenceSize[edge][fk] = max(self.tubeWidthMaximum*widthRatioScale, self.tubeWidthMinimum) # Drawing of flow tubes edgeCollection = LineCollection(edge_pos, colors=edge_color, linewidths=self.tubeWidthFactor*self.widthReferenceSize[edge][fk], antialiaseds=(1,), transOffset=self.axes.transData, alpha=1 ) edgeCollection.set_zorder(1) self.edgeColoring[edge][fk] = edgeCollection self.axes.add_collection(edgeCollection) # Drawing of overflow blocks ''' if not overflowBlocks: if Utilities.is_eq_tol(self.flowOnQueue[edge][fk][time], 0): continue else: # Draw first block blockSizeFactor = min(1, self.flowOnEntireEdge[edge][fk][time]/self.maxOverflowStorage[edge]) block = Rectangle(start - delta, width=d, height=14, transform=t, facecolor=self.NTFColors[fk % len(self.NTFColors)], linewidth=None, alpha=1) overflowBlocks.append(block) else: pass ''' if overflowBlocks: overflowBlockCollection = PatchCollection(boxes, match_original=True, antialiaseds=(1,), transOffset=self.axes.transData) self.visualQueueColoring[edge] = overflowBlockCollection self.axes.add_collection(overflowBlockCollection)
def update_queue_animation(self, radius=7): """Update queue animation to display different edge queue""" if not self.focusEdge: return if self.boxColoring: self.boxColoring.remove() self.boxColoring = None # Work setting edge = self.focusEdge time = self.timePoints[self.currentTimeIndex] totalFlowOnQueue = sum( self.flowOnQueue[edge][fk][time] for fk in range(len(self.nashFlow.flowIntervals))) if Utilities.is_eq_tol(totalFlowOnQueue, 0) or Utilities.is_eq_tol( self.maxQueueSize, 0): return flowRatio = [ max(0, float(self.flowOnQueue[edge][fk][time]) / totalFlowOnQueue) for fk in range(len(self.nashFlow.flowIntervals)) ] totalRatio = totalFlowOnQueue / float(self.maxQueueSize) delta = np.array([0, radius]) src = np.array(self.src) dst = np.array(self.dst) s = dst - src angle = np.rad2deg(np.arctan2(s[1], s[0])) t = matplotlib.transforms.Affine2D().rotate_deg_around( src[0], src[1], angle) boxes = [] lastProportion = 1 for fk in range(len(self.nashFlow.flowIntervals)): if Utilities.is_eq_tol(flowRatio[fk], 0): continue d = np.sqrt(np.sum(((dst - src) * lastProportion)**2)) rec = Rectangle(src - delta, width=d, height=radius * 2, transform=t, facecolor=self.NTFColors[fk % len(self.NTFColors)], linewidth=int(lastProportion), alpha=1) boxes.append(rec) lastProportion -= (totalRatio * flowRatio[fk]) d = np.sqrt(np.sum(((dst - src) * (1 - totalRatio))**2)) lastRec = Rectangle(src - delta, width=d, height=radius * 2, transform=t, facecolor='white', linewidth=0, alpha=1) boxes.append(lastRec) boxCollection = PatchCollection(boxes, match_original=True, antialiaseds=(1, ), transOffset=self.axes.transData) self.boxColoring = boxCollection self.axes.add_collection(boxCollection)