Exemplo n.º 1
0
def prim(G, start):
    """Function recives a graph and a starting node, and returns a MST"""
    stopN = G.number_of_nodes() - 1
    current = start
    closedSet = set()
    pq = PQDict()
    mst = []

    while len(mst) < stopN:
        # print " "
        # print "Current node :", current
        for node in G.neighbors(current):
            if node not in closedSet and current not in closedSet:
                # print "    neigbors: ", node
                if (current, node) not in pq and (node, current) not in pq:
                    w = G.edge[current][node]['weight']
                    pq.additem((current, node), w)

        closedSet.add(current)

        tup, wght = pq.popitem()
        while (tup[1] in closedSet):
            tup, wght = pq.popitem()
        mst.append(tup)
        current = tup[1]

    return mst
Exemplo n.º 2
0
def main():

	# Main output dict
	output = {'results': []}

	# Read JSON from file
	with open('input.json', 'r') as f:
		inputjson = json.load(f)

	profiles = inputjson['profiles']
	for profile in profiles:
		pq = PQDict()
		no_of_profiles = 0
		matches=[]
        
		# The output for this profile in JSON format 
		profile_output = {'profileId': profile['id'],
				'matches': []}

		for other_profile in profiles:
			if other_profile['id'] == profile['id']:
			# dont calculate against our own profile
				continue
			# Calculate match percentage with OKCupid's formula
			match_score = math.sqrt(satisfaction(profile, other_profile) * satisfaction(other_profile, profile))

			# Add the first ten matches to a min-heap (PQDict) 
			if len(pq) < 11:
				pq.additem(other_profile['id'],match_score)
			else:
				if match_score > pq.popitem()[1]:
					pq.additem(other_profile['id'],match_score)
				else:
					continue
	
		for i in range(len(pq)):
			key,value = pq.popitem()
			temp = {'profileId': key,
				'score': value}
			matches.append(temp)

        	# Reverse the heap and store it in the output for that profile
        	profile_output['matches'] = matches[::-1]
        	output['results'].append(profile_output)

	# Write out the output JSON to file
	with open('output_optimized.json', 'w') as outf:
		json.dump(output, outf, indent=1)

	return 0
Exemplo n.º 3
0
def main():

    # Main output dict
    output = {'results': []}

    # Read JSON from file
    with open('input.json', 'r') as f:
        inputjson = json.load(f)

    profiles = inputjson['profiles']
    for profile in profiles:
        pq = PQDict()
        no_of_profiles = 0
        matches = []

        # The output for this profile in JSON format
        profile_output = {'profileId': profile['id'], 'matches': []}

        for other_profile in profiles:
            if other_profile['id'] == profile['id']:
                # dont calculate against our own profile
                continue
            # Calculate match percentage with OKCupid's formula
            match_score = math.sqrt(
                satisfaction(profile, other_profile) *
                satisfaction(other_profile, profile))

            # Add the first ten matches to a min-heap (PQDict)
            if len(pq) < 11:
                pq.additem(other_profile['id'], match_score)
            else:
                if match_score > pq.popitem()[1]:
                    pq.additem(other_profile['id'], match_score)
                else:
                    continue

        for i in range(len(pq)):
            key, value = pq.popitem()
            temp = {'profileId': key, 'score': value}
            matches.append(temp)

# Reverse the heap and store it in the output for that profile
        profile_output['matches'] = matches[::-1]
        output['results'].append(profile_output)

    # Write out the output JSON to file
    with open('output_optimized.json', 'w') as outf:
        json.dump(output, outf, indent=1)

    return 0
Exemplo n.º 4
0
def djikstra(G, start):
    '''
    Djikstra's algorithm determines the length from `start` to every other 
    vertex in the graph.

    The graph argument `G` should be a dict indexed by nodes.  The value 
    of each item `G[v]` should also a dict indexed by predecessor nodes.
    In other words, for any node `v`, `G[v]` is itself a dict, indexed 
    by the predecessors of `v`.  For any directed edge `w -> v`, `G[v][w]` 
    is the length of the edge from `w` to `v`.

    '''
    inf = float('inf')
    dist = {start: 0}  # track shortest path distances from `start`
    E = set([start])  # explored
    U = set(G.keys()) - E  # unexplored

    while U:  # unexplored nodes
        D = PQDict()  # frontier candidates
        for u in U:  # unexplored nodes
            for v in G[u]:  # neighbors of u
                if v in E:  # then u is a frontier node
                    l = dist[v] + G[u][v]  # start -> v -> u
                    D[u] = min(l, D.get(u, inf))  # choose minimum for u

        (x, d) = D.popitem()  # node w/ min dist on frontier
        dist[x] = d  # assign djikstra greedy score
        U.remove(x)  # remove from unexplored
        E.add(x)  # add to explored

    return dist  # shortest path distances
Exemplo n.º 5
0
def dijkstra(graph, start, end):
    inf = float('inf')
    shortest_distances = {start: 0}                 # mapping of nodes to their dist from start
    queue_sd = PQDict(shortest_distances)           # priority queue for tracking min shortest path
    predecessors = {}                               # mapping of nodes to their direct predecessors
    unexplored = set(graph.keys())                  # unexplored nodes
    path = []

    while unexplored:                                           # nodes yet to explore
        (minNode, minDistance) = queue_sd.popitem()             # node w/ min dist d on frontier
        shortest_distances[minNode] = minDistance               # est dijkstra greedy score
        unexplored.remove(minNode)                              # remove from unexplored
        if minNode == end: break                                # end if goal already reached

        # now consider the edges from minNode with an unexplored head -
        # we may need to update the dist of unexplored successors
        for neighbor in graph[minNode]:                               # successors to v
            if neighbor in unexplored:                          # then neighbor is a frontier node
                minDistance = shortest_distances[minNode] + graph[minNode][neighbor]
                if minDistance < queue_sd.get(neighbor, inf):
                    queue_sd[neighbor] = minDistance
                    predecessors[neighbor] = minNode                   # set/update predecessor

    currentNode = end
    while currentNode != start:
        try:
            path.insert(0,currentNode)
            currentNode = predecessors[currentNode]
        except KeyError:
            print('Path not reachable')
            break
    path.insert(0,start)
    if shortest_distances[end] != inf:
        return shortest_distances[end], path
Exemplo n.º 6
0
def dijkstra(g, s):
    vis = [False for i in range(len(g))]
    dist = [float('inf') for i in range(len(g))]
    prev = [None for i in range(len(g))]
    dist[s] = 0

    ipq = PQDict()
    ipq.additem(s, 0)
    while len(ipq) != 0:
        index, minValue = ipq.popitem()
        vis[index] = True
        # mica optimizare, daca deja avem distanda mai buna pe alt drum fata de drumul direct dintre 2 noduri, pass
        if dist[index] < minValue:
            continue
        for edge in g[index]:
            # ia toate nodurile vecine nevizitate
            if vis[edge[0]]:
                continue
            # le calculaeza distanta
            newDist = dist[index] + edge[1]
            # si o modifica doar daca este mai mica decat cea care era deja
            if newDist < dist[edge[0]]:
                dist[edge[0]] = newDist
                # apoi modifica si in indexed priority queue, daca nu e, il adauga, daca e, ii updateaza valoarea
                if ipq.get(edge[0]) is None:
                    ipq.additem(edge[0], newDist)
                else:
                    ipq[edge[0]] = newDist
                # si seteaza si tatal de fiecare data pentru a ramane ultimul adica cel cu costul cel mai mic
                prev[edge[0]] = index
    return dist, prev
Exemplo n.º 7
0
def dijkstra(graph, start):
    p_queue = PQDict()
    dist_to_start = {}
    prev_vert = {}

    # Fill the dictionaries with initial values
    for vert in graph:
        dist_to_start[vert] = 1000
        prev_vert[vert] = None

    # Initialize the priority queue dictionary
    dist_to_start[start] = 0
    for vert in graph:
        p_queue[vert] = dist_to_start[vert] # starts at 1000

    # BFS the priority queue dictionary
    while len(p_queue) > 0:
        current = p_queue.popitem()[0] # the first item in the tuple is the key
        neighbors = graph[current].keys()

        for vert in neighbors:
            neighbor_dist = graph[current][vert] 
            new_distance = dist_to_start[current] + neighbor_dist
            
            if new_distance < dist_to_start[vert]: # if smaller than the last dist_to_start replace
                p_queue[vert] = new_distance
                dist_to_start[vert] = new_distance
                prev_vert[vert] = current

    return prev_vert
Exemplo n.º 8
0
def djikstra(G, start):
    '''
    Djikstra's algorithm determines the length from `start` to every other 
    vertex in the graph.

    The graph argument `G` should be a dict indexed by nodes.  The value 
    of each item `G[v]` should also a dict indexed by predecessor nodes.
    In other words, for any node `v`, `G[v]` is itself a dict, indexed 
    by the predecessors of `v`.  For any directed edge `w -> v`, `G[v][w]` 
    is the length of the edge from `w` to `v`.

    '''
    inf = float('inf')
    dist = {start: 0}       # track shortest path distances from `start`
    E = set([start])        # explored
    U = set(G.keys()) - E   # unexplored

    while U:                                        # unexplored nodes
        D = PQDict()                                # frontier candidates
        for u in U:                                 # unexplored nodes
            for v in G[u]:                          # neighbors of u
                if v in E:                          # then u is a frontier node
                    l = dist[v] + G[u][v]           # start -> v -> u
                    D[u] = min(l, D.get(u, inf))    # choose minimum for u

        (x, d) = D.popitem()                        # node w/ min dist on frontier
        dist[x] = d                                 # assign djikstra greedy score
        U.remove(x)                                 # remove from unexplored
        E.add(x)                                    # add to explored

    return dist                                     # shortest path distances
Exemplo n.º 9
0
def AStar(problem):
	#Give path of data file
	path = problem.datapath
	#Data
	data = list()
	data = readFunc(path)

	#Initialization of a node.
	node = Node()
	node.state = problem.initState
	node.pathcost = 0

	#Frontier is a priority queue dict of tuples:(node.pathcost, node), with key:node.state
	#Frontier is ordered by path cost.
	frontier = PQDict()
	frontier.additem(node.state, (node.pathcost,node))

	#Explored begins as the empty set.
	explored = Set()

	while True:
		if len(frontier) == 0:
			return 'No route exists'
		node = frontier.popitem()[1][1] #Chooses the lowest-cost node in frontier
		if problem.goalState == node.state:
			return solution(node,problem)
		explored.add(node.state)

		possibleActions = findPossibleActions(node.state,data)
		for action in range(len(possibleActions)):
			child = childNode(problem,node,possibleActions[action],data)
			if (child.state not in explored) and (child.state not in frontier):
				frontier.additem(child.state, (child.pathcost, child))
			elif (child.state in frontier) and (frontier[child.state][1].pathcost > child.pathcost):
				frontier[child.state] = (child.pathcost, child)
    def test_heapsort(self):
        # sequences of operations
        pq = PQDict()
        self.check_heap_invariant(pq)
        self.check_index(pq)

        items = generateData('int')

        # push in a sequence of items
        added_items = []
        for dkey, pkey in items:
            pq.additem(dkey, pkey)
            self.check_heap_invariant(pq)
            self.check_index(pq)
            added_items.append( (dkey,pkey) )

        # pop out all the items
        popped_items = []
        while pq:
            dkey_pkey = pq.popitem()
            self.check_heap_invariant(pq)
            self.check_index(pq)
            popped_items.append(dkey_pkey)

        self.assertTrue(len(pq._heap)==0)
        self.check_index(pq)
Exemplo n.º 11
0
    def get_dijkstra3(self, G, target):
        Gk = G.reverse()
        inf = float('inf')
        D = {target: 0}
        Que = PQDict(D)
        P = {}
        nodes = Gk.nodes
        U = set(nodes)
        while U:
            #print('len U %d'%len(U))
            #print('len Q %d'%len(Que))
            if len(Que) == 0: break
            (v, d) = Que.popitem()
            D[v] = d
            U.remove(v)
            #if v == target: break
            neigh = list(Gk.successors(v))
            for u in neigh:
                if u in U:
                    d = D[v] + Gk[v][u]['weight']
                    if d < Que.get(u, inf):
                        Que[u] = d
                        P[u] = v

        return P
def branchAndBound(G, cutoff, ftrace):
    queue = PQDict()
    bestSolution = INFINITY
    bestTour = []
    totalNodes = len(G.nodes())
    startNode = G.nodes()[0]
    nodeList = G.nodes()
    nodeList.remove(startNode)
    queue.additem(tuple([startNode]), lowerBound(G, [startNode]))

    start_time = time.time()
    while len(queue) != 0:
        coveredNodes, lowerBoundCurrent = queue.popitem()

        elapsed_time = time.time() - start_time
        if elapsed_time > cutoff:
            if bestSolution == INFINITY:
                return [], -1
            return bestTour, bestSolution

        for neighbor in G.neighbors(coveredNodes[-1]):
            if not neighbor in coveredNodes:
                tempNodes = list(coveredNodes)
                tempNodes.append(neighbor)
                if len(tempNodes) == totalNodes:
                    cost = findCost(G, tempNodes) + G.get_edge_data(neighbor, startNode)["weight"]
                    if cost < bestSolution:
                        bestSolution = cost
                        bestTour = tempNodes
                        ftrace.write("{0:.2f}".format(elapsed_time * 1.0) + "," + str(bestSolution) + "\n")
                else:
                    tempLowerBound = lowerBound(G, tempNodes)
                    if tempLowerBound < bestSolution:
                        queue.additem(tuple(tempNodes), tempLowerBound)
    return bestTour, bestSolution
Exemplo n.º 13
0
    def a_star(self, heuristic):
        node = self.tree.create_node(state=State(self.wrigglers), pathCost=0)
        node.heuristic = heuristic(node)

        frontier = PQDict()
        stateFrontier = {}
        explored = {}

        # Sacrifice memory to have a huge speed up being able to instantly check for state in frontier
        stateFrontier[str(node.state)] = node.heuristic
        frontier.additem(node._identifier, node.heuristic)

        while(True):
            if(len(frontier) == 0):
                return None

            nodeID = frontier.popitem()[0]
            node = self.tree.get_node(nodeID)
            nodeStateStr = str(node.state)

            del stateFrontier[nodeStateStr]

            if self.testGoal(node.state):
                return node

            explored[nodeStateStr] = -1  # we don't care what the hash matches
            actions = self.getActions(node.state)
            for action in actions:
                child = self.childNode(node, action)
                child.heuristic = heuristic(child)
                childStr = str(child.state)

                inExplored = False
                inFrontier = False

                if childStr in explored:
                    inExplored = True

                bGreater = False
                if childStr in stateFrontier:
                    if(stateFrontier[childStr] < child.heuristic + child.pathCost):
                        bGreater = True
                    inFrontier = True

                if(not inExplored and not inFrontier):
                    stateFrontier[childStr] = child.heuristic
                    frontier.additem(child._identifier, child.heuristic + child.pathCost)
                elif(bGreater):
                    bHappened = False
                    for key in frontier:
                        if(str(self.tree.get_node(key).state) == childStr):
                            bHappened = True
                            frontier.pop(key)
                            frontier.additem(child._identifier, child.heuristic + child.pathCost)
                            break
                    assert bHappened
Exemplo n.º 14
0
def dijkstra(G, start, end=None):
    '''
    dijkstra's algorithm determines the length from `start` to every other 
    vertex in the graph.

    The graph argument `G` should be a dict indexed by nodes.  The value 
    of each item `G[v]` should also a dict indexed by successor nodes.
    In other words, for any node `v`, `G[v]` is itself a dict, indexed 
    by the successors of `v`.  For any directed edge `v -> w`, `G[v][w]` 
    is the length of the edge from `v` to `w`.

        graph = {'a': {'b': 1}, 
                 'b': {'c': 2, 'b': 5}, 
                 'c': {'d': 1},
                 'd': {}}

    Returns two dicts, `dist` and `pred`:

        dist, pred = dijkstra(graph, start='a') 
    
    `dist` is a dict mapping each node to its shortest distance from the
    specified starting node:

        assert dist == {'a': 0, 'c': 3, 'b': 1, 'd': 4}

    `pred` is a dict mapping each node to its predecessor node on the
    shortest path from the specified starting node:

        assert pred == {'b': 'a', 'c': 'b', 'd': 'c'}
    
    '''
    inf = float('inf')
    D = {start: 0}  # mapping of nodes to their dist from start           p*
    Q = PQDict(
        D)  # priority queue for tracking min shortest path      Cin ????
    P = {}  # mapping of nodes to their direct predecessors      存边
    U = set(G.keys())  # unexplored nodes

    while U:  # nodes yet to explore
        (v,
         d) = Q.popitem()  # node w/ min dist d on frontier           找到Cln最小的l
        D[v] = d  # est dijkstra greedy score                pl*
        U.remove(v)  # remove from unexplored                  从U中删除l
        if v == end: break  #如果集合为空,则算法终止

        # now consider the edges from v with an unexplored head -
        # we may need to update the dist of unexplored successors
        for w in G[v]:  # successors to v
            if w in U:  # then w is a frontier node
                d = D[v] + G[v][w]  # dgs: dist of start -> v -> w
                if d < Q.get(w, inf):
                    Q[w] = d  # set/update dgs
                    P[w] = v  # set/update predecessor

    return D, P
Exemplo n.º 15
0
def prim(G: "networx Graph object", start: "1X2 Tuple(Node)") -> (list, list):
    """
    Function recives a graph and a starting node, 
    and returns the MST and the history of the algorithm
    """
    MST_len = G.number_of_nodes() - 1
    current = start
    visited = set()
    # Priority Queue
    #(keeps the item with the lowest value on the top -
    #in this case the weight of an edge)
    pq = PQDict()
    # Minimal spamming tree
    mst = []
    steps = []
    history = []
    # While the MST has N - 1 edges (N is the total nodes)
    while len(mst) < MST_len:
        # Get the neighbors
        # history.append((current, G.neighbors(current)))
        for node in G.neighbors(current):
            if node not in visited and current not in visited:
                # Append the history
                steps.append((current, node))
                if (current, node) not in pq and (node, current) not in pq:
                    w = G.edge[current][node]['weight']
                    pq.additem((current, node), w)
        # We have visited the node
        visited.add(current)
        # Tup is the edge "(X, Y)", wght is the cost
        tup, wght = pq.popitem()
        # Get the lowest edge if we haven't visited the node
        while (tup[1] in visited):
            tup, wght = pq.popitem()
        # Append the edge to the minimum spanning tree
        mst.append(tup)
        history.append([tup, steps])
        steps = list()
        # Update the current node to the one we visit based on the minimal weight
        current = tup[1]

    return mst, history
Exemplo n.º 16
0
def dijkstra(G, start, end=None):
    '''
    dijkstra's algorithm determines the length from `start` to every other 
    vertex in the graph.

    The graph argument `G` should be a dict indexed by nodes.  The value 
    of each item `G[v]` should also a dict indexed by successor nodes.
    In other words, for any node `v`, `G[v]` is itself a dict, indexed 
    by the successors of `v`.  For any directed edge `v -> w`, `G[v][w]` 
    is the length of the edge from `v` to `w`.

        graph = {'a': {'b': 1}, 
                 'b': {'c': 2, 'b': 5}, 
                 'c': {'d': 1},
                 'd': {}}

    Returns two dicts, `dist` and `pred`:

        dist, pred = dijkstra(graph, start='a') 
    
    `dist` is a dict mapping each node to its shortest distance from the
    specified starting node:

        assert dist == {'a': 0, 'c': 3, 'b': 1, 'd': 4}

    `pred` is a dict mapping each node to its predecessor node on the
    shortest path from the specified starting node:

        assert pred == {'b': 'a', 'c': 'b', 'd': 'c'}
    
    '''
    inf = float('inf')
    D = {start: 0}          # mapping of nodes to their dist from start
    Q = PQDict(D)           # priority queue for tracking min shortest path
    P = {}                  # mapping of nodes to their direct predecessors
    U = set(G.keys())       # unexplored nodes

    while U:                                    # nodes yet to explore
        (v, d) = Q.popitem()                    # node w/ min dist d on frontier
        D[v] = d                                # est dijkstra greedy score
        U.remove(v)                             # remove from unexplored
        if v == end: break

        # now consider the edges from v with an unexplored head -
        # we may need to update the dist of unexplored successors 
        for w in G[v]:                          # successors to v
            if w in U:                          # then w is a frontier node
                d = D[v] + G[v][w]              # dgs: dist of start -> v -> w
                if d < Q.get(w, inf):
                    Q[w] = d                    # set/update dgs
                    P[w] = v                    # set/update predecessor

    return D, P
Exemplo n.º 17
0
    def plan(self, start_state, goal_state):
        #PQ = pqdict()
        V = {}

        self.goal_state = goal_state
        h0 = self.heuristic(start_state, goal_state)
        n0 = node(start_state, None, None, 0, h0)

        key0 = np.around(n0.state, decimals=1).tostring()
        PQ = PQDict(key0=n0)

        i = 0
        while PQ and i < 100000:
            current = PQ.popitem()[1]
            #print '\n'
            #print current.state[2]
            if (self.state_is_equal(current.path, goal_state)):
                path = self.reconstruct_path(current)
                return (path, current.f)

            V[np.around(current.state,
                        decimals=1).tostring()] = copy.deepcopy(current)

            #get children
            children = self.getChildren(
                current)  #do set parent, should return an array of nodes

            for child in children:
                i += 1
                if i % 100 == 0:
                    print 'A* iteration ' + str(i)

                child_key = np.around(child.state, decimals=1).tostring()
                if child_key in V:
                    if child.f >= V[child_key].f:
                        continue

                if (child_key in PQ):
                    existing_child = PQ[child_key]
                    if (child.g >= existing_child.g):
                        continue
                    else:
                        PQ.updateitem(child_key, child)
                else:
                    #print child.state, current.state
                    #pdb.set_trace()
                    #if(child.state[2] < 0):
                    #    pdb.set_trace()
                    PQ.additem(child_key, child)

        print 'A* Failed'
        return (None, None)
Exemplo n.º 18
0
    def plan(self, start_state, goal_state):
        #PQ = pqdict()
        V = {}

        self.goal_state = goal_state
        h0 = self.heuristic(start_state, goal_state)
        n0 = node(start_state, None, None, 0, h0)

        key0 = np.around(n0.state, decimals = 1).tostring()
        PQ = PQDict(key0=n0)

        i = 0 
        while PQ and i < 100000:
            current = PQ.popitem()[1]
            #print '\n'
            #print current.state[2]
            if(self.state_is_equal(current.path, goal_state)):
                path = self.reconstruct_path(current)
                return (path, current.f)

            V[np.around(current.state, decimals = 1).tostring()] = copy.deepcopy(current)

            #get children
            children = self.getChildren(current)#do set parent, should return an array of nodes
            
            for child in children:
                i += 1
                if i%100 == 0:
                    print 'A* iteration '+str(i)
                
                child_key = np.around(child.state, decimals = 1).tostring()
                if child_key in V:
                    if child.f >= V[child_key].f:
                        continue
                
                if (child_key in PQ):
                    existing_child = PQ[child_key]
                    if(child.g >= existing_child.g):
                        continue
                    else:
                        PQ.updateitem(child_key, child)
                else:
                    #print child.state, current.state
                    #pdb.set_trace()
                    #if(child.state[2] < 0):
                    #    pdb.set_trace()
                    PQ.additem(child_key,child)
        
        print 'A* Failed'
        return (None, None)
def executa_prim(G, primeiro_no):

    no_de_parada = G.number_of_nodes() - 1
    atual = primeiro_no
    visitados = set()  # Tira os repetidos e é uma Hash
    min_heap = PQDict()  # É um min_heap
    mst = []
    peso_total = 0
    pesos = []

    while len(mst) < no_de_parada:
        # print("Esse é o visitados", visitados)
        # print("Esse é o min_heap: ", min_heap)
        for noVizinho in G.neighbors(atual):
            # print("Esse é o no: ", noVizinho)
            # print("Esse é o atual: ", atual)
            if noVizinho not in visitados and atual not in visitados:
                if (atual,
                        noVizinho) not in min_heap and (noVizinho,
                                                        atual) not in min_heap:
                    peso_aresta = G[atual][noVizinho]['weight']
                    min_heap.additem((atual, noVizinho), peso_aresta)

        visitados.add(atual)

        aresta, peso = min_heap.popitem()  # Tira a raiz
        while (aresta[1] in visitados):  # Aresta[1] é o vizinho
            aresta, peso = min_heap.popitem(
            )  # Vai tirando a raiz até encontrar um vizinho não visitado
            # print("Essa é a aresta: ", aresta)
            # print("Esse é o peso: ", peso)
        peso_total += peso
        pesos.append(peso)
        mst.append(aresta)
        atual = aresta[1]

    return mst, peso_total, pesos
Exemplo n.º 20
0
def dijkstra(source):
    distResults = [INF] * (N + 1)
    distResults[source] = 0
    dist = PQDict()
    for i in range(1, N + 1):
        dist[i] = distResults[i]

    while dist:
        v1, d1 = dist.popitem()
        distResults[v1] = d1
        if d1 == INF:
            break
        for v2 in range(1, N + 1):
            if v2 in dist:
                dist[v2] = min(dist[v2], graph[v1, v2] + d1)
    return distResults
Exemplo n.º 21
0
def branchAndBound(G, cutoff, ftrace):
    queue = PQDict()
    bestSolution = INFINITY
    bestTour = []
    totalNodes = len(G.nodes())
    startNode = G.nodes()[0]
    nodeList = G.nodes()
    nodeList.remove(startNode)
    queue.additem(tuple([startNode]), lowerBound(G, [startNode]))

    start_time = time.time()
    while (len(queue) != 0):
        #         print count
        #         count+=1
        coveredNodes, lowerBoundCurrent = queue.popitem()
        #         coveredNodes=list(coveredNodes)

        elapsed_time = time.time() - start_time
        if elapsed_time > cutoff:
            if bestSolution == INFINITY:
                return -1, []
            return bestTour, bestSolution

        for neighbor in G.neighbors(coveredNodes[-1]):
            if not neighbor in coveredNodes:
                tempNodes = list(coveredNodes)
                tempNodes.append(neighbor)
                if (len(tempNodes) == totalNodes):
                    cost = findCost(G, tempNodes) + G.get_edge_data(
                        neighbor, startNode)['weight']
                    if (cost < bestSolution):
                        bestSolution = cost
                        bestTour = tempNodes
                        ftrace.write("{0:.2f}".format(elapsed_time * 1.0) +
                                     ',' + str(bestSolution) + '\n')
                else:
                    tempLowerBound = lowerBound(G, tempNodes)
                    if tempLowerBound < bestSolution:
                        queue.additem(tuple(tempNodes), tempLowerBound)
#                     else:
#                         print 'prune'
    return bestTour, bestSolution
Exemplo n.º 22
0
def prim(G):
    """ Return MST of the given undirected graph"""
    sumWeight = 0

    heap = PQDict()
    for u in G:
        heap[u] = float("inf")
    flag = [False] * len(G)
    heap[0] = 0
    #parents is the MST
    # parents = {}
    # parents[0] = 0
    while len(heap) != 0:
        [u, value] = heap.popitem()
        flag[u] = True
        sumWeight += value
        for v in G[u]:
            if flag[v] is False:
                # parents[v] = u
                heap[v] = min(heap[v], G[u][v])
    return sumWeight
Exemplo n.º 23
0
def dijkstra(G, src, dst=None):
    inf = float('inf')
    D = {src: 0}  # distance
    Q = PQDict(D)  # priority queue
    P = {}  # predecessor
    U = set(G.keys())  # unexplored nodes

    while U:  # still have unexplored
        (v, d) = Q.popitem()  # get node with least d
        D[v] = d  # add to D dict
        U.remove(v)  # node now explored
        if v == dst:  # reached destination
            break

        # now edges FROM v
        for w in G[v]:
            if w in U:  # unvisited neighbour
                tmpd = D[v] + G[v][w]
                if tmpd < Q.get(w, inf):  # return inf if not found
                    Q[w] = tmpd  # update distance
                    P[w] = v  # set predecessor as current
    return D, P
Exemplo n.º 24
0
def dijkstra(G, start, end=None):
    inf = float('inf')
    D = {start: 0}  # mapping of nodes to their dist from start
    Q = PQDict(D)  # priority queue for tracking min shortest path
    P = {}  # mapping of nodes to their direct predecessors
    U = set(G.keys())  # unexplored nodes

    while U:  # nodes yet to explore
        (v, d) = Q.popitem()  # node w/ min dist d on frontier
        D[v] = d  # est dijkstra greedy score
        U.remove(v)  # remove from unexplored
        if v == end: break

        # now consider the edges from v with an unexplored head -
        # we may need to update the dist of unexplored successors
        for w in G[v]:  # successors to v
            if w in U:  # then w is a frontier node
                d = int(D[v]) + int(G[v][w])  # dgs: dist of start -> v -> w
                if d < Q.get(w, inf):
                    Q[w] = d  # set/update dgs
                    P[w] = v  # set/update predecessor

    return D, P
Exemplo n.º 25
0
    def prim(self, start):
        p_queue = PQDict()
        prev_vert = {}
        key = {}

        for vert in self.graph:
            prev_vert[vert] = None
            key[vert] = 1000
        key[start] = 0

        for vert in self.graph:
            p_queue[vert] = key[vert]

        while p_queue:
            current = p_queue.popitem()[0]

            for vert in self.graph[current]:
                if vert in p_queue and self.graph[current][vert] < key[vert]:
                    prev_vert[vert] = current
                    key[vert] = graph[current][vert]
                    p_queue[vert] = graph[current][vert]

        return prev_vert
Exemplo n.º 26
0
    def dijkstra(self, src, dst):
        """dijkstras algorithm used to calculate the shortest path between two nodes a Priority queue is used in this implementation"""
        inf = float('inf')
        D = {src: 0}
        Q = PQDict(D)
        P = {}
        U = set(self.router_list)

        while U:
            (v, d) = Q.popitem()
            D[v] = d
            U.remove(v)
            if str(v) == dst:
                break

            for w in self.router_list[v]:
                if w in U:

                    d = D[v] + self.router_list[v][w]
                    if d < Q.get(w, inf):
                        Q[w] = d
                        P[w] = v

        return D, P
 def test_popitem(self):
     pq = PQDict(A=5, B=8, C=1)
     # pop top item
     dkey, pkey = pq.popitem()
     self.assertEqual(dkey,'C') and self.assertEqual(pkey,1)
Exemplo n.º 28
0
class Battle(object):
    """
    Fight a battle between two teams of oeo
    """
    _turn_stage_map = {
        8: '02',
        7: '03',
        6: '04',
        5: '05',
        4: '06',
        3: '07',
        2: '08',
        1: '09',
        0: '10',
        -1: '11',
        -2: '12',
        -3: '13',
        -4: '14',
        -5: '15',
        -6: '16',
        -7: '17'
    }

    _turn_spi_map = {
        0: '01',
        1: '02',
        2: '03',
        3: '04',
        4: '05',
        5: '06',
        6: '07',
        7: '08',
        8: '09',
        9: '10',
        10: '11',
        11: '12'
    }

    def __init__(self, oeos, a_id, a, a_max_fielded, b_id, b, b_max_fielded):
        assert all(isinstance(oeo, Oeo) for oeo in oeos.values()), \
            "oeos is not a dict of oeo_id:oeo"
        assert isinstance(a_id, str), "'a_id' is not a string"
        assert isinstance(a, set), "'a' is not a set of oeo_id"
        assert isinstance(a_max_fielded, int), "'a_max_fielded' is not an int"
        assert isinstance(b_id, str), "'b_id' is not a string"
        assert isinstance(b, set), "'b' is not a set of oeo_id"
        assert isinstance(b_max_fielded, int), "'b_max_fielded' is not an int"
        # Throw error if each oeo_id is not unique between teams
        if a & b:
            raise ValueError(f"{a & b} oeo_id(s) not unique between teams")

        self._oeo = oeos
        self._a_id = a_id
        self._a = a
        self._b_id = b_id
        self._b = b

        self._turn_number = 0
        self._field = Field(a_id, a_max_fielded, b_id, b_max_fielded)
        self._pending_sim_events = PQDict()
        self._processed_sim_events = []

        move_set = set()
        for o in itertools.chain(self._oeo.values()):
            for move in o.moves:
                move_set.add(move)
        moves = Move.load_moves(move_set)
        self._moves = moves

        # self._speed_priority_list = None
        self._setup_axel_events()

    @property
    def teams(self):
        return {self._a_id: self._a, self._b_id: self._b}

    @property
    def field(self):
        return self._field

    def _setup_axel_events(self):
        """
        Initialise axel events
        """
        # sim_output_message(msg)
        self.sim_output_message = Event()

        # event_choose_deployments(team_id, non_fielded_team, empty_positions)
        # non_fielded_team: oeo from the team who are not on the field
        #                   but are conscious
        # empty_positions: empty positions on the field into which an oeo
        #                  could be deployed
        self.event_choose_deployments = Event()

        # event_choose_actions(team_id, oeo_requiring_actions)
        # oeo_requiring_actions: oeo that are on the field and need to select
        #                        an action for the current turn
        self.event_choose_actions = Event()

    def run(self):
        """
        Run the battle

        :return: id of the victor
        :rtype: str
        """
        logger.info(f"{self._a_id} vs {self._b_id}...")
        ta = {oeo_id: self._oeo[oeo_id] for oeo_id in self._a}
        tb = {oeo_id: self._oeo[oeo_id] for oeo_id in self._b}
        logger.debug(f"{self._a_id}'s team:\n{ta}")
        logger.debug(f"{self._b_id}'s team:\n{tb}")

        # Add the BEGIN_TURN SimEvent for turn 1
        self._pending_sim_events.additem(SimEvent(SimEventType.BeginTurn), 1)

        victor = None

        # While there are pending sim events, loop until we break when a
        # battle end condition is met
        while self._pending_sim_events:
            # Remove any oeo with 0 HP from the field
            self._remove_unconscious_oeo()

            # Check teams: if all oeo in the battle are unconscious,
            #               then end battle as a draw
            #              if all oeo in team A are unconscious,
            #               then end battle as win for team B
            #              if all oeo in team B are unconscious,
            #               then end battle as win for team A
            if not any(oeo.conscious for oeo in self._oeo.values()):
                logger.info("All oeo on both sides of the battle are "
                            "unconscious, the battle is a draw")
                victor = "DRAW"
                break
            elif not any(self._oeo[oeo_id].conscious for oeo_id in self._a):
                logger.info(f"{self._a_id}'s team are unconscious, "
                            f"{self._b_id} wins the battle")
                victor = self._b_id
                break
            elif not any(self._oeo[oeo_id].conscious for oeo_id in self._b):
                logger.info(f"{self._b_id}'s team are unconscious, "
                            f"{self._a_id} wins the battle")
                victor = self._a_id
                break

            # Let both sides choose oeo to deploy
            self._choose_deployments()
            logger.debug(f"{self._a_id}'s side: {self._field[self._a_id]}")
            logger.debug(f"{self._b_id}'s side: {self._field[self._b_id]}")

            # Check both sides of the field:
            # if team A side is empty, then end as win for team B
            # if team B side is empty, then end as win for team A
            if self._field[self._a_id].is_empty():
                logger.info(f"{self._a_id} yields, "
                            f"{self._b_id} wins the battle")
                victor = self._b_id
                break
            elif self._field[self._b_id].is_empty():
                logger.info(f"{self._b_id} yields, "
                            f"{self._a_id} wins the battle")
                victor = self._a_id
                break

            # Pop the next event to be processed, add it to the
            # processed events list, and process it
            event, event_priority = self._pending_sim_events.popitem()
            event_complete = 0
            event_type = event.event_type
            if event_type is SimEventType.BeginTurn:
                event_complete = self._process_begin_turn()
            elif event_type is SimEventType.UseMove:
                event_complete = self._process_use_move(**event.data)
            elif event_type is SimEventType.UseItem:
                # event_complete = self._process_use_item
                pass
            elif event_type is SimEventType.Switch:
                # event_complete = self._process_switch_oeo
                pass
            elif event_type is SimEventType.Run:
                # event_complete = self._process_run
                pass
            else:
                raise ValueError(f"Invalid event_type: {event}")

            self._processed_sim_events.append(
                (event_priority, event, event_complete))

        logger.debug(f"Pending events: {self._pending_sim_events}")
        logger.info(f"Processed events: {self._processed_sim_events}")
        return victor

    def _process_begin_turn(self):
        # Increment the turn number and add the BeginTurn SimEvent
        # for the next turn
        self._turn_number += 1
        logger.debug(f"Processing BeginTurn({self._turn_number}) SimEvent")
        self._pending_sim_events.additem(SimEvent(SimEventType.BeginTurn),
                                         self._turn_number + 1)

        # TODO: Update status conditions - burn, poison, landing from flight,
        # then remove unconscious oeo from field

        # Choose the actions for the oeo on the field this turn, calculate the
        # order in which the actions should occur, and add them to the pending
        # sim events priority queue
        self._choose_actions()
        return 1

    def _process_use_move(self, user_id, move_id, target_id):
        logger.debug("Processing UseMove SimEvent")
        user, move, target = self._oeo[user_id], self._moves[move_id], \
            self._oeo[target_id]
        user_is_fielded = self._is_fielded(user_id)
        target_is_fielded = self._is_fielded(target_id)
        if user_is_fielded and target_is_fielded:
            logger.info(f"{user_id} attacks {target_id} using {move_id}")
            df_id = getattr(move, "df_id", "Standard")
            damage_function = get_damage_function(df_id)
            damage = damage_function(user, move, target)
            hp = target.current_hp
            target.current_hp -= damage
            logger.info(f"{target_id}'s HP = {hp}-{damage} "
                        f"= {target.current_hp}")
            return 1
        else:
            logger.debug(f"User on field = {user_is_fielded}, "
                         f"Target on field = {target_is_fielded}")
            return -1

    def _process_use_item(self, item, target):
        logger.debug("Processing UseItem SimEvent")
        return 0

    def _process_switch(self, user, target):
        logger.debug("Processing Switch SimEvent")
        return 0

    def _process_run(self, user, run_type):
        logger.debug("Processing Run SimEvent")
        return 0

    def _calculate_event_priority(self, turn, priority, speed_priority):
        """
        :param turn: the turn in which the event is to be actioned
        :param priority: the stage of the turn in which the event is \
                         to be actioned
        :param speed_priority: the speed_priority of the oeo undertaking \
                               the event
        :return: the priority of the event to be actioned
        """
        return float(f"{turn}.{self._turn_stage_map[priority]}"
                     f"{self._turn_spi_map[speed_priority]}")

    def _remove_unconscious_oeo(self):
        """
        Withdraw unconscious oeo from the field
        """
        for team_id in [self._a_id, self._b_id]:
            oeo_to_remove = [
                oeo_id for oeo_id in self._field[team_id].fielded
                if self._oeo[oeo_id].conscious is False
            ]
            for oeo_id in oeo_to_remove:
                self._field.withdraw(team_id, oeo_id)

    def _is_fielded(self, oeo_id):
        """
        :param oeo_id:
        :return: True if oeo_id is on the field else False
        """
        if (oeo_id in self._field[self._a_id]) or \
                (oeo_id in self._field[self._b_id]):
            return True
        else:
            return False

    def _choose_deployments(self):
        """
        Choose and make deployments to the field
        """
        for team_id in [self._a_id, self._b_id]:
            empty_positions = self._field[team_id].empty_positions
            logger.debug(f"Empty positions on {team_id}'s side: "
                         f"{empty_positions}")
            if empty_positions:
                fielded = self._field[team_id].fielded
                benched = [
                    oeo_id for oeo_id in self.teams[team_id]
                    if oeo_id not in fielded and self._oeo[oeo_id].conscious
                ]
                logger.debug(f"Benched on {team_id}'s side: {benched}")
                if benched:
                    deployments = self._poll_deployments(
                        team_id, benched, empty_positions)
                    logger.debug(f"{team_id}'s oeo to deploy: {deployments}")
                    for position, oeo_id in deployments.items():
                        self._field.deploy(team_id, oeo_id, position)

    def _poll_deployments(self, team_id, non_fielded_team, empty_positions):
        """
        Polls for deployments for team_id
        :return: dict of position:oeo_id
        """
        logger.debug(f"Polling for deployments from {team_id}")
        results = self.event_choose_deployments(team_id,
                                                list(non_fielded_team),
                                                empty_positions)
        flag, result, handler = results[0]
        if flag:
            for position, oeo_id in result.items():
                # Ensure that each oeo is only deployed to one
                # field position at most
                if list(result.values()).count(oeo_id) > 1:
                    raise Exception(f"{oeo_id} can not be deployed to more "
                                    "than one field position")
                # Ensure 0 >= position < len(self._field[team_id])
                if position < 0 or position >= len(self._field[team_id]):
                    raise Exception(f"Position {position} is out of bounds"
                                    f"(0-{len(self._field[team_id]) - 1})")
                # Ensure oeo_id is in self.team[team_id]
                if oeo_id not in self.teams[team_id]:
                    raise Exception(f"{oeo_id} is not in {team_id}'s team")
            return result
        else:
            raise Exception("Exception in choose_deployments handler") \
                from result

    def _choose_actions(self):
        """
        Choose and schedule actions for oeo on the field
        """
        # Create the speed_priority_list for this turn
        oeo_against_speed = [(oeo_id, oeo.speed)
                             for oeo_id, oeo in self._oeo.items()]
        oeo_against_speed.sort(key=itemgetter(1), reverse=True)
        logger.debug(f"Speed Priority List: {oeo_against_speed}")
        speed_priority_list = [t[0] for t in oeo_against_speed]

        a_fielded = self._field[self._a_id].fielded
        b_fielded = self._field[self._b_id].fielded

        # Create action_map dictionary of oeo_id to action:None for
        # fielded oeo and update it from future_action dictionary
        action_map = {
            oeo_id: None
            for oeo_id in itertools.chain(a_fielded, b_fielded)
        }
        # todo: Update action_map from future_actions dictionary
        logger.debug(f"Initial action map for turn {self._turn_number}: "
                     f"{action_map}")

        # Call event_choose_actions for each team for oeo that do not have
        # an action to perform (action is None)
        a_oeo_requiring_actions = [
            oeo_id for oeo_id, action in action_map.items()
            if (oeo_id in a_fielded) and (action is None)
        ]
        a_oeo_requiring_actions.sort(key=lambda x: self._oeo[x].speed,
                                     reverse=True)
        b_oeo_requiring_actions = [
            oeo_id for oeo_id, action in action_map.items()
            if (oeo_id in b_fielded) and (action is None)
        ]
        b_oeo_requiring_actions.sort(key=lambda x: self._oeo[x].speed,
                                     reverse=True)
        logger.debug(f"{self._a_id}'s oeo requiring actions: "
                     f"{a_oeo_requiring_actions}")
        logger.debug(f"{self._b_id}'s oeo requiring actions: "
                     f"{b_oeo_requiring_actions}")
        a_actions = self._poll_actions(self._a_id, a_oeo_requiring_actions)
        b_actions = self._poll_actions(self._b_id, b_oeo_requiring_actions)
        logger.info(f"{self._a_id}'s actions chosen: {a_actions}")
        logger.info(f"{self._b_id}'s actions chosen: {b_actions}")

        # For each {oeo_id: action} in dictionary returned by the event
        # handlers, add it to the action map if the oeo does not already have
        # an action for this turn in the action map
        for oeo_id, action in itertools.chain(a_actions.items(),
                                              b_actions.items()):
            if action_map[oeo_id] is not None:
                raise Exception(f"{oeo_id} already had an action "
                                "for this turn")
            action_map[oeo_id] = action
        logger.debug(f"Final action map for turn {self._turn_number}: "
                     f"{action_map}")

        # For each {oeo_id: action} in the action map add the SimEvent for
        # the action to the pending sim events queue
        for oeo_id, action in action_map.items():
            if action:
                if action.event_type == SimEventType.UseMove:
                    target = action.data["target_id"]
                    move_id = action.data["move_id"]
                    move_priority = self._moves[move_id].priority
                    oeo_priority = speed_priority_list.index(oeo_id)
                    s = SimEvent(SimEventType.UseMove,
                                 user_id=oeo_id,
                                 target_id=target,
                                 move_id=move_id)
                    ep = self._calculate_event_priority(
                        self._turn_number, move_priority, oeo_priority)
                    self._pending_sim_events.additem(s, ep)

                if action.event_type == SimEventType.UseItem:
                    pass

    def _poll_actions(self, team_id, oeo_requiring_actions):
        """
        Polls for actions from team_id
        :return: dict of oeo_id:action
        """
        logger.debug(f"Polling for actions from {team_id}")
        results = self.event_choose_actions(team_id, oeo_requiring_actions)
        flag, result, handler = results[0]
        if flag:
            for oeo_id, action in result.items():
                # Ensure oeo is on the field
                if not self._is_fielded(oeo_id):
                    raise Exception(f"{oeo_id} is not on the field")
                # Ensure oeo is in team_id
                if oeo_id not in self.teams[team_id]:
                    raise Exception(f"{oeo_id} is not on {team_id}'s side")
                # Ensure action is SimEvent
                if not isinstance(action, SimEvent):
                    raise Exception("Action is not a SimEvent")
                # Ensure action.event_type is UseMove, UseItem, Switch or Run
                if action.event_type not in [
                        SimEventType.UseMove, SimEventType.UseItem,
                        SimEventType.Switch, SimEventType.Run
                ]:
                    raise Exception("Action event type not UseMove, UseItem, "
                                    "Switch or Run")
            return result
        else:
            raise Exception("Exception in choose_actions handler") from result
Exemplo n.º 29
0
          costs[node2] = cost
  elif node2 == mst[0]:
      if costs[node1] > cost:
          costs[node1] = cost
if test:
    print "initial costs is", costs
    
# insert node to heap
heap = PQDict()
for node in range(2,n+1):
    heap.additem(node, costs[node])
if test:
    print "heap is", heap
cost_sum = 0
while len(heap) != 0:
    next_node = heap.popitem(); # (node, cost)
    if test:
        print "next_node is %d" % next_node[0]
    cost_sum = cost_sum + next_node[1]
    if test:
        print "current cost_sum is %d" % cost_sum
    mst.append(next_node[0])
    if test:
        print "current mst is", mst
    for edge in edges:
        node1 = edge[0]
        node2 = edge[1]
        cost = edge[2]
        if (node1 == next_node[0]) and (node2 not in mst):
            if costs[node2] > cost:
                if test: