Пример #1
0
    def testGetMin(self):
        pq = PriorityQueue()
        randomTuples = self.generateRandomTuples(10000)
        for randomT in randomTuples:
            pq.insertNode(randomT)

        currentMin = pq.getMin()
        while len(pq.tree) > 1:
            nextMin = pq.getMin()
            self.assertLessEqual(currentMin[1], nextMin[1])
            currentMin = nextMin
def lowerBoundImprovementReversed(source, target) :
    """
    Evolution of the normal label-setting algorithm, with a preprocessing that uses
    Dijkstra bicriteria algorithm

    @return
        number of loops
    """
    visitedNodes = __dijkstraBiCrit(target, source, 0) # safest path
    bestDanger = source.danger
    for v in visitedNodes:
        v.resetValue(True)
    __dijkstraBiCrit(target, source, 1) # shortest path
    bestDistance = source.distance

    labelQueue = PriorityQueue()
    sourceLabel = (0, 0, source, None, 0, None)
    source.labelList.append(sourceLabel)
    labelQueue.put(sourceLabel, sourceLabel[0])
    ending = False
    counter = 0
    while not labelQueue.isEmpty() :
        actualLabel = labelQueue.getMin()
        distSoFar = actualLabel[0]
        dangSoFar = actualLabel[1]
        actualNode = actualLabel[2]
        parentIndex = actualLabel[4]
        
        for nearNode, weight in actualNode.neighbors :
            distance, danger = weight
            ownIndex = len(nearNode.labelList)
            newLabel = (distSoFar + distance, dangSoFar + danger, nearNode, actualNode, ownIndex, parentIndex) # creating of a new label
            useLabel = True

            if nearNode.bestLabel[0] is not None and nearNode.bestLabel[1] is not None :    # if the best label is present, enter
                checkDistance = newLabel[0] + nearNode.bestLabel[0]
                checkDanger = newLabel[1] + nearNode.bestLabel[1]
                if checkDanger >= bestDanger and checkDistance >= bestDistance :  # if the values are negative is useless to check
                    continue #checkLabel = (newLabel[0] + checkDistance, newLabel[1] + checkDanger)
                else :
                    checkLabel = newLabel   
            else :
                checkLabel = newLabel
            
            if ending :
                if isDominated(checkLabel, target.labelList) : # if the newlabel + bestLabel is dominated is useless go on                
                    continue # restart 'for' loop with another nearNode
            
            for label in nearNode.labelList :
                if isDominated(newLabel, [label]) :
                    useLabel = False
                    break # if a value is useless (1st case) the loop - label in labelList - is interrupt, to jump some loops
            if useLabel :
                nearNode.labelList.append(newLabel)
                if nearNode != target :
                    labelQueue.put(newLabel, newLabel[0])
                else :
                    ending = True
        counter += 1
    return counter
Пример #3
0
def a_star(source, target):
    listOfCand = PriorityQueue()
    listOfCand.put(source, 0)

    counter = 0

    while not listOfCand.isEmpty():
        actualNode = listOfCand.getMin()
        counter = counter + 1
        actualNode.visited = True

        if target.visited:
            break

        for nextNode, distance in actualNode.neighbors:
            if not nextNode.visited:

                newDistance = actualNode.minWeight + distance[0]

                if newDistance < nextNode.minWeight:
                    #this path is the best until now, let's record
                    if nextNode.euclidean is None:  # this check is to minimazie the calculation of the "euclidean distance"
                        nextNode.euclidean = euclideanDistance(
                            nextNode, target)

                    nextNode.minWeight = newDistance
                    nextNode.predecessor = actualNode
                    priority = newDistance + nextNode.euclidean
                    listOfCand.put(nextNode, priority)
    print("loops:", counter)
def __dijkstraBiCrit(source, target, alpha) :
    """
    With the bicriteria algorithm I decided to use the attribute "distance"
    of the node, because "minWeight" is used has comparator.
    Also in normal dijkstra is calcolated the weight, in this specific case we know
    that the "weights" are distance and danger 

    alpha : to varying of this variable the algorithm can find different results
                more α is near to 0, will be found the safest path
                more α is near to 1, will be found the shortest path
    """
    visitedNodes = []

    listOfCandidate = PriorityQueue()
    listOfCandidate.put(source, 0)
    while not listOfCandidate.isEmpty() :
        actualNode = listOfCandidate.getMin()
        actualNode.visited = True
        visitedNodes.append(actualNode)

        if target.visited :
            break

        for nextNode, weight in actualNode.neighbors : 
            distance, danger = weight
            weightResult = alpha*distance + (1-alpha)*danger
            newWeight = actualNode.minWeight + weightResult
            if newWeight < nextNode.minWeight :
                nextNode.minWeight = newWeight
                nextNode.distance = actualNode.distance + distance
                nextNode.danger = actualNode.danger + danger
                nextNode.predecessor = actualNode
                listOfCandidate.put(nextNode, newWeight)
                if not isDominated((nextNode.distance, nextNode.danger), nextNode.bests) :
                    for label in nextNode.bests :
                        if label[0] > nextNode.distance and label[1] >= nextNode.danger :
                            nextNode.bests.remove(label)
                    nextNode.bests.append((nextNode.distance, nextNode.danger))
                if alpha == 0 :         # Those ifs are useful only with the lowerBound Algorithm ()
                    # if nextNode.bestLabel[1] is None or nextNode.bestLabel[1] > nextNode.danger :
                    #     nextNode.bestLabel[1] = nextNode.danger
                    if nextNode.bestDangerLabel is None or nextNode.bestDangerLabel[1] > nextNode.danger :
                        nextNode.bestDangerLabel = (nextNode.distance, nextNode.danger)
                elif alpha == 1 :
                    # if nextNode.bestLabel[0] is None or nextNode.bestLabel[0] > nextNode.distance :
                    #     nextNode.bestLabel[0] = nextNode.distance
                    if nextNode.bestDistanceLabel is None or nextNode.bestDangerLabel[0] > nextNode.distance :
                        nextNode.bestDistanceLabel = (nextNode.distance, nextNode.danger)
    return visitedNodes
Пример #5
0
 def dijkstra(self, start_label, end_label):
     start_vertex = self.find_vertex_by_label(start_label)
     start_vertex.weight = 0
     pq = PriorityQueue()
     pq.build_heap(self.vertices)
     while not pq.isEmpty():
         min_vertex = pq.getMin()  # return Vertex object
         for neighbour_vertex in self.adjacencyList[min_vertex.label]:
             tmp_vertex = self.find_vertex_by_label(
                 neighbour_vertex.label)  # vertex object from self.vertices
             if min_vertex.weight + neighbour_vertex.weight < tmp_vertex.weight:
                 tmp_vertex.parent = min_vertex.label
                 tmp_vertex.weight = min_vertex.weight + neighbour_vertex.weight
         pq.deleteMin()
     print(self.print_path(end_label))
Пример #6
0
def dijkstraOneToAll(source):
    nodeSet = PriorityQueue()
    nodeSet.put(source, 0)
    # counter = 0
    while not nodeSet.isEmpty():
        actualNode = nodeSet.getMin()
        # counter = counter + 1
        for nextNode, distance in actualNode.neighbors:
            newDistance = actualNode.minWeight + distance[0]
            if newDistance < nextNode.minWeight:
                #this is the better path, until now
                nextNode.minWeight = newDistance
                nextNode.predecessor = actualNode
                nodeSet.put(nextNode, newDistance)
                source.addShortestPath(
                    nextNode, newDistance
                )  # all the path from the starting node are here
Пример #7
0
def dijkstraListOfCandidate(source, target):
    listOfCand = PriorityQueue()
    listOfCand.put(source, 0)
    while not listOfCand.isEmpty():
        actualNode = listOfCand.getMin()
        actualNode.visited = True

        if target.visited:
            break

        for nextNode, distance in actualNode.neighbors:
            newDistance = actualNode.minWeight + distance[0]
            if newDistance < nextNode.minWeight:
                nextNode.minWeight = newDistance
                nextNode.predecessor = actualNode
                listOfCand.put(nextNode, newDistance)

    if not target.visited:  # if the target is not been visited, it means that it wasn't in the set
        print("ERROR! impossible to reach the target")
 def prim(self, start_label):
     start_vertex = self.find_vertex_by_label(start_label)
     start_vertex.weight = 0
     pq = PriorityQueue()
     #for vertex in self.vertices:
     #    pq.insert(vertex)
     pq.build_heap(self.vertices)
     while not pq.isEmpty():
         min_vertex = pq.getMin()  # return Vertex object
         if min_vertex.parent is not None:
             self.path += (min_vertex.parent + " -> " + min_vertex.label +
                           ", ")
         for neighbour_vertex in self.adjacencyList[min_vertex.label]:
             tmp_vertex = self.find_vertex_by_label(
                 neighbour_vertex.label)  # vertex object from self.vertices
             if neighbour_vertex.weight < tmp_vertex.weight:
                 tmp_vertex.parent = min_vertex.label
                 tmp_vertex.weight = neighbour_vertex.weight
         pq.deleteMin()
     print(self.path)
Пример #9
0
def dijskstra(source):
    global dist
    global adjList

    pq = PriorityQueue()
    dist[source] = 0
    pq.insertNode((source, 0))

    while pq.getSize() > 1:
        currPair = pq.getMin()
        currNodeIndex = currPair[0]
        currWeight = currPair[1]
        if( currWeight > dist[currNodeIndex]):
            continue
        
        for neighbor in adjList[currNodeIndex]:
            nextNodeIndex = neighbor[0]
            nextWeight = neighbor[1]
            if dist[currNodeIndex] + nextWeight < dist[nextNodeIndex]:
                dist[nextNodeIndex] = dist[currNodeIndex] + nextWeight
                pq.insertNode(neighbor)
Пример #10
0
def labelSettingAlgorithm(source, target):
    """
    label = (dist, danger, owner, predecessor, ownerListPos, predListPos)
              [0]    [1]    [2]       [3]           [4]          [5]

              [ownerListPos] : is the position on the own label list
              [predListPos] : is the postion in the labelList of the predecessor label
    
    Step 0 :
        create first label (0, 0, source, null, 0, null)
        and put it in the labelSet (a priorityQueue)
    Step 1 :
        if labelSet.isEmpty() -> step 4
        else select the label w/ the less distance and calc the label of the neighbors
    Step 2 :
        foreach neighbor of the current label calc
            What to do when i found a new label for a node : - 3 possibility
                1st - new label IS DOMINATED by one already existence (in the node.labelList) -> delete new label
                2nd - new label DOMINATE one or more already existence ( " " ) -> delete old label, add new label
                3rd - new label ISN'T DOMINATED AND CAN'T DOMINATE any other node -> add new label
    Step 3 :
        return to Step 1
    Step 4:
        End

    @return
        number of loops
    """
    labelQueue = PriorityQueue()
    sourceLabel = (0, 0, source, None, 0, None)
    source.labelList.append(sourceLabel)
    labelQueue.put(sourceLabel, sourceLabel[0])
    ending = False  # become True when a "nearNode" is equal to the target
    counter = 0
    while not labelQueue.isEmpty():
        counter += 1
        actualLabel = labelQueue.getMin()
        distSoFar = actualLabel[0]
        dangSoFar = actualLabel[1]
        actualNode = actualLabel[2]
        parentIndex = actualLabel[4]

        for nearNode, weight in actualNode.neighbors:
            distance, danger = weight
            ownIndex = len(nearNode.labelList)
            newLabel = (distSoFar + distance, dangSoFar + danger, nearNode,
                        actualNode, ownIndex, parentIndex
                        )  # creating of a new label
            useLabel = True

            if ending:  # stop condition
                if isDominated(newLabel, target.labelList):
                    continue  # restart for loop if the new label is dominated

            for label in nearNode.labelList:
                if not __usableLabel(newLabel, label, nearNode.labelList):
                    useLabel = False
                    break  # if a value is useless (1st case) the loop - label in labelList - is interrupt, to jump some loops
            if useLabel:
                nearNode.labelList.append(newLabel)
                if nearNode != target:
                    labelQueue.put(newLabel, newLabel[0])
                else:
                    ending = True
    return counter