def __init__(self, graph, inflowRate, numberOfIntervals, outputDirectory, templateFile, scipFile, cleanUpBool, timeout): """ :param graph: Networkx Digraph instance :param inflowRate: u_0 :param numberOfIntervals: number of intervals that will be computed. -1 if all :param outputDirectory: path where output should be saved :param templateFile: Selected method, i.e. 0,1,2 :param scipFile: path to scip binary :param cleanUpBool: If true, then cleanup :param timeout: seconds until timeout. Deactivated if equal to 0 """ self.network = graph.copy() self.inflowRate = inflowRate # For the moment: constant self.numberOfIntervals = numberOfIntervals # No. of intervals to compute self.outputDirectory = outputDirectory # Template File from /source/templates self.templateFile = os.path.join( os.getcwd(), 'source', 'templates', 'algorithm_' + str(templateFile + 1) + '.zpl') self.allInOne = (templateFile == 1) self.advancedAlgo = ( templateFile == 2 ) # If true, then advanced backtracking with preprocessing is performed self.scipFile = scipFile self.cleanUpBool = cleanUpBool self.numberOfSolvedIPs = 0 self.computationalTime = 0 self.infinityReached = False # True if last interval has alpha = +inf self.timeout = timeout self.minCapacity = Utilities.compute_min_attr_of_network(self.network) self.counter = 0 self.preprocessedNodes = 0 self.preprocessedEdges = 0 # Create directory for Nash-Flow self.rootPath = os.path.join(self.outputDirectory, 'NashFlow-' + Utilities.get_time()) Utilities.create_dir(self.rootPath) self.flowIntervals = [ ] # List containing triplets of form (lowerBound, upperBound, FlowInterval-instance) self.lowerBoundsToIntervalDict = OrderedDict() self.animationIntervals = {edge: [] for edge in self.network.edges()}
def compute_NTF(self): """Computes NTF in current tab""" originalNetwork = self.gttr('network') network = deepcopy(originalNetwork) # Remove inactive edges from network inactiveEdges = [ edge for edge in originalNetwork.edges() if not originalNetwork[edge[0]][edge[1]]['TFC']['active'] ] network.remove_edges_from(inactiveEdges) # Remove nodes that are now no longer reachable L = [] for (v, d) in network.in_degree(): if d == 0 and v != 's': # Non-reachable node found L.append(v) network.remove_nodes_from(L) # Validate input returnCode = self.validate_thinflow_input(network) if returnCode != 0: # Invalid input has been given # Spawn warning QtWidgets.QMessageBox.question(QtWidgets.QWidget(), 'Abort: Input error', self.get_error_message(returnCode), QtWidgets.QMessageBox.Ok) return # Drop current NTF plot self.re_init_NTF_frame() # Get necessary data resettingEdges = [ edge for edge in network.edges() if network[edge[0]][edge[1]]['TFC']['resettingEnabled'] ] lowerBoundTime = 0 # No needed for different times as only one flowInterval is being computed inflowRate = float(self.inflowLineEdit.text()) minCapacity = Utilities.compute_min_attr_of_network(network) counter = "Standalone" rootPath = self.outputDirectory self.templateFile = self.templateComboBox.currentIndex() if self.currentTF == 'general': templateFile = os.path.join( os.getcwd(), 'templates', 'algorithm_' + str(self.templateFile + 1) + '.zpl') elif self.currentTF == 'spillback': print( "Note: For spillback only the basic algorithm [1] is available and hence run now." ) templateFile = os.path.join(os.getcwd(), 'templates', 'algorithm_spillback_1.zpl') scipFile = self.scipFile timeout = float(self.timeoutLineEdit.text()) self.save_config() if self.currentTF == 'general': self.interval_general = FlowInterval(network, resettingEdges=resettingEdges, lowerBoundTime=lowerBoundTime, inflowRate=inflowRate, minCapacity=minCapacity, counter=counter, outputDirectory=rootPath, templateFile=templateFile, scipFile=scipFile, timeout=timeout) elif self.currentTF == 'spillback': fullEdges = [] minInflowBound = float('inf') for e in network.edges(): (v, w) = e minInflowBound = min(minInflowBound, network[v][w]['TFC']['inflowBound']) self.interval_spillback = FlowInterval_spillback( network, resettingEdges=resettingEdges, fullEdges=fullEdges, lowerBoundTime=lowerBoundTime, inflowRate=inflowRate, minCapacity=minCapacity, counter=counter, outputDirectory=rootPath, templateFile=templateFile, scipFile=scipFile, timeout=timeout, minInflowBound=minInflowBound) # Set shortest path network manually to entire graph (is the deepcopy really needed?) interval = self.gttr('interval') interval.shortestPathNetwork = deepcopy(network) if self.currentTF == 'spillback': interval.transfer_inflowBound(interval.shortestPathNetwork) self.advancedAlgo = ( self.templateFile == 2 ) # If true, then advanced backtracking with preprocessing is performed if self.currentTF == 'general': if self.advancedAlgo: interval.get_ntf_advanced() else: interval.get_ntf() elif self.currentTF == 'spillback': interval.get_ntf() self.sttr( 'plotNTFCanvas', self.currentTF, PlotNTFCanvas( interval.shortestPathNetwork, self, intervalID=None, stretchFactor=self.plotNTFCanvasStretchFactor, showNoFlowEdges=self.showEdgesWithoutFlowCheckBox.isChecked(), onlyNTF=True)) self.gttr('plotNTFFrameLayout').addWidget(self.gttr('plotNTFCanvas')) self.cleanup()
def compute_flowInterval(self): """Method to compute a single flowInterval""" # Get lowerBoundTime lowerBoundTime = 0 if not self.flowIntervals else self.flowIntervals[ -1][1] # Compute resettingEdges cmp_queue = lambda v, w, t: \ Utilities.is_greater_tol(self.node_label(w, t), self.node_label(v, t) + self.network[v][w]['transitTime']) resettingEdges = [(v, w) for v, w in self.network.edges() if cmp_queue(v, w, lowerBoundTime)] \ if lowerBoundTime > 0 else [] edges_to_choose_from = self.network.edges( ) # Fulledges can be non resetting! fullEdges = [(v, w) for v, w in edges_to_choose_from if self.is_full(v, w, self.node_label(v, lowerBoundTime)) ] if lowerBoundTime > 0 else [] minInflowBound = None interval = FlowInterval_spillback(self.network, resettingEdges=resettingEdges, fullEdges=fullEdges, lowerBoundTime=lowerBoundTime, inflowRate=self.inflowRate, minCapacity=self.minOutCapacity, counter=self.counter, outputDirectory=self.rootPath, templateFile=self.templateFile, scipFile=self.scipFile, timeout=self.timeout, minInflowBound=minInflowBound) if lowerBoundTime == 0: interval.shortestPathNetwork = Utilities.get_shortest_path_network( self.network) # Compute shortest path network for v, w in interval.shortestPathNetwork.edges(): interval.shortestPathNetwork[v][w][ 'inflowBound'] = self.network[v][w]['inCapacity'] else: interval.shortestPathNetwork = Utilities.get_shortest_path_network( self.network, labels={ v: self.node_label(v, lowerBoundTime) for v in self.network }) # Compute shortest path network for v, w in interval.shortestPathNetwork.edges(): vTimeLower = self.node_label(v, lowerBoundTime) minimizer = self.get_outflow( v, w, vTimeLower) if (v, w) in fullEdges else float('inf') interval.shortestPathNetwork[v][w]['inflowBound'] = min( minimizer, self.network[v][w]['inCapacity']) minInflowBound = Utilities.compute_min_attr_of_network( interval.shortestPathNetwork, 'inflowBound') interval.set_minInflowBound(minInflowBound) start = time.time() interval.get_ntf() ''' if self.advancedAlgo: interval.get_ntf_advanced() else: interval.get_ntf() ''' end = time.time() self.computationalTime += (end - start) interval.computationalTime = end - start self.preprocessedNodes += interval.preprocessedNodes self.preprocessedEdges += interval.preprocessedEdges self.lowerBoundsToIntervalDict[lowerBoundTime] = interval if lowerBoundTime == 0: self.init_edge_properties() interval.compute_alpha({ node: self.node_label(node, lowerBoundTime) for node in self.network }) self.flowIntervals.append( (interval.lowerBoundTime, interval.upperBoundTime, interval)) # Update in/out-flow rates self.update_edge_properties(lowerBoundTime, interval) self.counter += 1 self.numberOfSolvedIPs += interval.numberOfSolvedIPs self.infinityReached = (interval.alpha == float('inf'))