Ejemplo n.º 1
0
class KruskalsMST:
    def __init__(self, g):
        self.mst = []
        self.g = g
        self.heap = MinHeap()
        self.UF = UnionFind(g.V)
        self.populateHeap()
        self.populate_mst()

    def populateHeap(self):
        edges = set()
        for i in range(self.g.V):
            for edge in self.g.adj(i):
                edges.add(edge)
        for edge in edges:
            self.heap.add_item(edge)

    def populate_mst(self):
        while len(self.mst) < self.g.V - 1 and not self.heap.is_empty():
            edge = self.heap.del_min()
            if not self.UF.find(edge.either(), edge.other(edge.either())):
                self.mst.append(edge)
                self.UF.union(edge.either(), edge.other(edge.either()))

    def get_mst(self):
        return self.mst
Ejemplo n.º 2
0
    def shortest_path(self, v_start, v_end):
        # item structure: {'w': 11, 'path': ['va', 'vb', ...]}
        priority_queue = MinHeap(criterion='w')
        # structure: {..., 'v_name': {'w': 11, 'path': ['va', 'vb',...] }}
        best_tracks = {}

        curr_track = {'path': [v_start], 'w': 0, 'v': v_start}
        while True:
            for edge in self.vertex_edges[curr_track['v']]:
                new_track = {
                    'w': curr_track['w'] + edge['w'],
                    'path': curr_track['path'] + [edge['v2']]
                }
                priority_queue.insert(new_track)

            assert priority_queue.is_empty() == False
            min_track = priority_queue.getMin()

            while better_track_exists(min_track, best_tracks):
                min_track = priority_queue.getMin()

            if at_destination(min_track, v_end):
                return min_track

            best_tracks[min_track['path'][-1]] = min_track
            curr_track = min_track.copy()
            curr_track['v'] = min_track['path'][-1]
class KruskalsMST:
    def __init__(self, g):
        self.mst = []
        self.g = g
        self.heap = MinHeap()
        self.done = [False]*self.g.V
        self.populate_mst()

    def travel_node(self, node):
        self.done[node] = True
        for each in self.g.adj(node):
            self.heap.add_item(each)

    def populate_mst(self):
        self.travel_node(0)
        while len(self.mst) < self.g.V-1 and not self.heap.is_empty():
            edge = self.heap.del_min()
            if not self.done[edge.either()] and self.done[edge.other(edge.either())]:
                self.travel_node(edge.either())
                self.mst.append(edge)
            elif self.done[edge.either()] and not self.done[edge.other(edge.either())]:
                self.travel_node(edge.other(edge.either()))
                self.mst.append(edge)
                    
    def get_mst(self):
        return self.mst
Ejemplo n.º 4
0
def dijkstra (source_vertex, vertices, edges):

	minheap = MinHeap("dist")

	for vertex in vertices:
		vertex.parent = vertex
		vertex.dist = 999999
		minheap.push(vertex)

	minheap.update_key( minheap.find_index(vertices[0]), 0 )

	while not minheap.is_empty():
		vertex = minheap.pop()
		print(vertex.id, vertex.parent.id, vertex.dist)

		for dest_vertex, weight in edges[vertex]:
			if dest_vertex.dist > vertex.dist + weight:
				dest_vertex.parent = vertex
				minheap.update_key( minheap.find_index(dest_vertex), vertex.dist + weight )
Ejemplo n.º 5
0
    def MST_prim2(self):
        #최종적으로 만들어질 MST
        mst = Graph()
        mst.add_vertex(self.vertex_num)
        #TV={} : MST 정점의 집합, 시작 노드부터 하나씩 채워나간다
        TV = set()

        #w_list : 각 정점의 w 값을 담아두기 위한 배열
        w_list = [None for _ in range(self.vertex_num)]
        #min heap에 w와 from을 가진 정점을 담아둔다
        #heap 초기화 : w->inf, from->None
        h = MinHeap()
        for i in range(1, self.vertex_num):
            w_list[i] = math.inf
            h.push(Element(i, math.inf, None))
        #시작 노드인 0은 w->0, from->None
        w_list[0] = 0
        h.push(Element(0, 0, None))

        while not h.is_empty():
            #가중치가 가장 작은 에지 (from, v) : w
            #정보를 가진 정점 Element v
            v = h.pop()
            #TV에 정점을 추가
            TV.add(v.v)
            #TE에 에지 추가
            if v._from != None:
                mst.insert_edge(v.v, v._from, v.w)

            #TV에 정점이 추가되면 인접 정점 중
            #트리 밖에 있는 정점에 대해 업데이트 시도
            #u는 새로 추가된 정점 v에 인접한 정점 노드
            u = self.adjacency_list[v.v]
            while u:
                #u가 트리 밖의 정점이고
                #기존 w 값보다 w(u, v)이 작다면 업데이트
                if u.vertex not in TV and u.weight < w_list[u.vertex]:
                    #w_list 업데이트
                    w_list[u.vertex] = u.weight
                    h.decrease_weight(Element(u.vertex, u.weight, v.v))
                u = u.link

        return mst
Ejemplo n.º 6
0
    def dijkstra(self, start):
        seen = set()
        heap = MinHeap()

        heap.push(start, start.val)
        seen.add(start)

        while not heap.is_empty():
            top, priority = heap.pop()

            for name, edge_dist in top.neighbors.items():
                tmp_distance = edge_dist + priority
                neighbor = self.nodes[name]
                if tmp_distance < neighbor.val:
                    neighbor.parent = top
                    neighbor.val = tmp_distance
                    if neighbor in seen:
                        heap.update_priority(neighbor, neighbor.val)
                    else:
                        heap.push(neighbor, neighbor.val)
Ejemplo n.º 7
0
def algorithm(P: NPuzzleInstance, name='ASTAR'):

    begin = time.now()
    open_heap = MinHeap()
    open_heap.push(
        P.initial_state,
        P.initial_state.get_total_cost()
        if name == 'ASTAR' else P.initial_state.greedy_value)
    cost_so_far = {P.initial_state: 0}
    father_of = {P.initial_state: None}

    while not open_heap.is_empty():

        # print('heap size -> ' + str(len(open_heap.elements)), end='\r', flush=True)
        P.current_state = open_heap.pop()

        if P.is_solved():
            P.spent_time = time.now() - begin
            solution = []
            curr = P.current_state
            while curr:
                solution.append(curr)
                curr = father_of[curr]

            P.build_solution(list(reversed(solution)))

            return P

        for neighbor in P.neighbors():
            if neighbor not in cost_so_far.keys(
            ) or P.current_state.greedy_value < cost_so_far[neighbor]:
                cost_so_far[neighbor] = P.current_state.greedy_value
                open_heap.push(
                    neighbor,
                    neighbor.get_total_cost()
                    if name == 'ASTAR' else neighbor.greedy_value)
                father_of[neighbor] = State(
                    P.current_state.matrix, P.current_state.greedy_value,
                    P.current_state.heuristic_value if name == 'ASTAR' else 0)

    return None
Ejemplo n.º 8
0
def a_star_search(P: NPuzzleInstance, parents=[]):

    open_heap = MinHeap()
    open_heap.push(P.initial_state, P.initial_state.get_total_cost())
    cost_so_far = { P.initial_state: 0 }
    father_of = { P.initial_state: None }

    while not open_heap.is_empty():

        print('\theap size -> ' + str(len(open_heap.elements)), end='\r', flush=True)
        P.current_state = open_heap.pop()

        if P.is_solved():
            solution = []
            curr = P.current_state
            while father_of[curr]:
                solution.append(curr)
                curr = father_of[curr]

            solution.append(curr)

            return list(reversed(solution))

        for neighbor in P.neighbors():
            new_cost = P.current_state.greedy_value

            if neighbor not in cost_so_far.keys() or new_cost < cost_so_far[neighbor]:
                cost_so_far[neighbor] = new_cost
                open_heap.push(neighbor, neighbor.get_total_cost())
                father_of[neighbor] = State(
                    P.current_state.matrix,
                    P.current_state.greedy_value,
                    P.current_state.heuristic_value
                )

    return None
Ejemplo n.º 9
0
    def __init__(self, graph):

        self.__tree = []
        self.__weight = 0

        heap = MinHeap()
        for i in range(graph.get_node_nums()):
            adj = graph.iter_nodes(i)
            for edge in adj:
                if edge.orgin < edge.goal:
                    heap.add(edge)

        union_find = UnionFind(graph.get_node_nums())
        while not heap.is_empty() and len(
                self.__tree) < graph.get_node_nums() - 1:

            edge = heap.pop()

            if not union_find.is_connected(edge.orgin, edge.goal):
                self.__tree.append(edge)
                union_find.union(edge.orgin, edge.goal)

        for x in self.__tree:
            self.__weight += x.weight
Ejemplo n.º 10
0
def test_is_empty():
    heap = MinHeap()
    assert heap.is_empty()
    heap.add_all([randrange(0, 1000) for _ in range(0, randrange(1, 100))])