예제 #1
0
 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
예제 #3
0
    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))
예제 #4
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()
예제 #6
0
    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)