Exemple #1
0
 def __init__(self):
     #_graphLayer[n] is the nth overlay layer
     #_coveredVertices[n] is the set of vertices in _graphLayer[n]
     self._graphLayer = []
     self._coveredVertices = []
     self._metrics = cfg.metrics
     self._numberOfLayers = None
     try:
         #Check if we already have created an overlay graph before. The program can load the file and initialize instantly without
         #re-creating overlay graphs from the scratch
         overlayGraphFile = cfg.filelocation["OVERLAYGRAPH"]
         self._graphLayer = load(overlayGraphFile)
         self._coveredVertices = map(
             lambda diGraphAtlayer: set(diGraphAtlayer.vertices()),
             self._graphLayer)
         self._numberOfLayers = len(self._graphLayer)
         applogger.debug("Number of layers in loaded graph = %s",
                         self._numberOfLayers)
     except IOError:
         #This occures if a pre-existing overlay graph file doesnt exist on disk. We need to create an overlay graph and store it so that future runs
         #dont have to do this again.
         applogger.info(
             "Creating overlaygraph for the first time. This might take a while"
         )
         self._createOverLayGraph()
         self._writeOverLayGraphToFile()
Exemple #2
0
 def _createOverLayGraph(self):
     try:
         #BaseGraph is the raw graph (road network).
         baseGraphFile = cfg.filelocation["BASEGRAPH"]
         self._numberOfLayers = cfg.numberOfLayers
         #initialize graphLayer . ie start with every layer as an empty list. Later on graphLayer[n] will be the nth layer of the overlay graph
         self._graphLayer = [None for k in xrange(self._numberOfLayers)]
         self._coveredVertices = [
             None for k in xrange(self._numberOfLayers)
         ]
         #Initialize the first layer as the raw graph data
         self._graphLayer[0] = load(baseGraphFile)
         applogger.debug("Loaded baseGraph")
         #Initialize the cover in the first layer as all the vertices of the raw graph
         self._coveredVertices[0] = set(self._graphLayer[0].vertices())
         applogger.debug("Retrieved baseGraph vertices")
         for layerNum in xrange(1, self._numberOfLayers):
             applogger.debug("Generating Layer %s" % layerNum)
             self._createLayer(layerNum)
             applogger.debug(
                 "Layer %s Generated. Number of vertices = %s, Number of edges = %s"
                 % (layerNum, self._graphLayer[layerNum].order(),
                    self._graphLayer[layerNum].size()))
         applogger.debug("OverlayGraph creation complete")
     except IOError:
         print "No base file located"
         import sys
         sys.exit()
Exemple #3
0
 def _modifyEdgeLabel(self, u, v, layerNum, currentEdgeLabel, newEdgeLabel):
     modifiedEdgeLabel = currentEdgeLabel.copy()
     sameWeights = True
     for metric in newEdgeLabel:
         #If all the metrices in the new weights are equaivalent to whats already on the edge, we don't have to update the edge
         if modifiedEdgeLabel.get(metric) != newEdgeLabel.get(metric):
             sameWeights = false
         modifiedEdgeLabel[metric] = newEdgeLabel.get(metric)
     if not sameWeights:
         applogger.debug("Modifying %s, %s, %s, %s" %
                         (u, v, currentEdgeLabel, layerNum))
         self._graphLayer[layerNum].delete_edge(u, v, currentEdgeLabel)
         self._graphLayer[layerNum].add_edge(u, v, modifiedEdgeLabel)
         #Sage doesnt support editing in place the edge weight between u,v when there are multiple edges between them
         #So, I delete the old edge and then add the new edge with new weights(to emulate a modification)
     else:
         applogger.debug("Skip Modifying %s, %s, %s, %s" %
                         (u, v, currentEdgeLabel, layerNum))
Exemple #4
0
 def _createLayer(self, layerNum):
     #Find the vertex cover of the graph at the lower layer. Vertex cover works only on for undirected graph in Sage
     #So, converting the lower layer into a undirected graph and also removing the multiple edges in the lower graph
     applogger.debug("Starting vertex cover of layer %s" % (layerNum - 1))
     self._coveredVertices[layerNum] = self._getVertexCoverOflayer(
         layerNum - 1)
     applogger.debug("Retrieved vertex cover of layer %s" % (layerNum - 1))
     applogger.debug("VC Size = %s" % len(self._coveredVertices[layerNum]))
     #This is a switch in-case I decide to store only the shortest path later instead of all routes from one node to another
     if cfg.ALLPATH:
         self._graphLayer[layerNum] = self._createAllPathLayer(layerNum)
Exemple #5
0
 def findOptimumRoute(self, sourceVertex, targetVertex, userWieghts):
     """Given two nodes on the graph, returns the optimum path along them
         @sourceVertex - Starting node
         @targetVertex - Destination node
         @UserWeights - Dictionary of user preference
             eg : {'dist' : 1, 'traffic_lights:0'} will find the optimum path considering shortest distance between source and target
                  {'dist' : 0, 'traffic_lights:1'} will find the optimum path considering least amount of traffic lights between source and target
     """
     applogger.debug("Start of Query")
     args = [(sourceVertex, True), (targetVertex, False)]
     pool = ThreadPool(2)
     #Run a bi-directional dijsktra parallely : A forward Dijsktra from source and a backward dijsktra from the target
     (forwardResult, backwardWardResult) = pool.map(
         lambda arg: self._runPartialDijsktra(arg[0], userWieghts, arg[1]),
         args)
     #Sample Forward Result :
     #({1: {'cost': 0, 'parent': None}, 2: {'cost': 1, 'parent': 1}, 3: {'cost': 2, 'parent': 2}, 4: {'cost': 3, 'parent': 3}, 10: {'cost': 1, 'parent': 1}}, set([10, 4]))
     #Sample BackWard Result :
     #({8: {'cost': 0, 'parent': None}, 6: {'cost': 2, 'parent': 7}, 7: {'cost': 1, 'parent': 8}}, set([6]))
     pool.close()
     pool.join()
     verticesVisitedDuringForwardSearch, forwardAccessNodes = forwardResult
     verticesVisitedDuringBackwardSearch, backWardAccessNodes = backwardWardResult
     #TargetVertex was already settled during the forward search. We have nothing more to do here.
     if targetVertex in verticesVisitedDuringForwardSearch:
         path, _ = self._getNodesAlongShortestPath(
             targetVertex, verticesVisitedDuringForwardSearch)
         path.reverse()
         jsonDict = {
             "minCost":
             verticesVisitedDuringForwardSearch.get(targetVertex).get(
                 "cost"),
             "route":
             path
         }
         return jsonDict
     #To run, Dijsktra on the overlay graph, we initialize the priority Q with every access node obtained in the forward
     #search and its cost from source. By the end of the Dijstra in Overlay graph, we get the cost from source to every
     #access node of the target
     forwardAccessNodePathCost = [
         (accessNode,
          verticesVisitedDuringForwardSearch.get(accessNode).get("cost"))
         for accessNode in forwardAccessNodes
     ]
     verticesVisitedDuringOverlaySearch = self._runDijsktraOnOverlay(
         forwardAccessNodePathCost, backWardAccessNodes.copy(), userWieghts)
     #Sample verticesVisitedDuringOverlaySearch :
     #{10: {'cost': 1, 'intermediateVerticesToParent': [], 'parent': None}, 4: {'cost': 3, 'intermediateVerticesToParent': [], 'parent': None}, 6: {'cost': 4, 'intermediateVerticesToParent': [], 'parent': 4}}
     #Pick the target access node that minimizes the cost of (source to access node) + (access node to target)
     distToTargetViaAcessNodes = map(
         lambda accessNode: (verticesVisitedDuringOverlaySearch[
             accessNode].get("cost") + verticesVisitedDuringBackwardSearch[
                 accessNode].get("cost"), accessNode), backWardAccessNodes)
     minimumCost, minimumAccessNode = min(distToTargetViaAcessNodes)
     #Here , we create the shortest route from the source to target.
     #For , overlay search, we use the parent heirarchy and the edgeIntermediate vertices to retrieve the actual path
     pathAlongOverLayGraph, lastNode = self._getNodesAlongShortestPath(
         minimumAccessNode, verticesVisitedDuringOverlaySearch, True)
     pathAlongForwardSearch, _ = self._getNodesAlongShortestPath(
         lastNode, verticesVisitedDuringForwardSearch, False)
     pathAlongBackWardSearch, _ = self._getNodesAlongShortestPath(
         minimumAccessNode, verticesVisitedDuringBackwardSearch, False)
     path = []
     path.extend(pathAlongOverLayGraph)
     path.extend(pathAlongForwardSearch)
     #The parent heirarchy lists the route in reverse order. So we reverse it to obtain the forward order
     path.reverse()
     #Backward search operated in the backward direction. So the parent heirarchy will already list vertices in the actual forward order
     #So, no need to reverse it
     path.extend(pathAlongBackWardSearch)
     applogger.debug("End of Query")
     #print path
     jsonDict = {"minCost": minimumCost, "route": path}
     return jsonDict