示例#1
0
    def __init__(self, graph):
        self.graph = graph
        self.pred = {}  # 搜索结束后从尾顶点开始获取完整路径
        self.dist = {}  # 存储每个顶点到源点的最短距离
        self.priority_queue = PriorityQueue()

        for node in self.graph.nodes.values():
            self.pred[node.key] = -1
            self.dist[node.key] = sys.maxsize
            self.priority_queue.insert(PriorityQueueNode(node.key, self.dist[node.key]))
示例#2
0
class MSTPrim(object):
    def __init__(self, graph: Graph):
        self.graph = graph
        self.pred = {}
        self.keys = {}
        self.in_queue = {}  # tag for node set V, True for V-S, False for S
        self.priority_queue = PriorityQueue()
        self.result = []

        for node in self.graph.nodes.values():
            self.pred[node.key] = -1
            self.keys[node.key] = sys.maxsize
            self.in_queue[node.key] = True
            self.priority_queue.insert(
                PriorityQueueNode(node.key, self.keys[node.key]))

    # 随机选择一个顶点开始
    def mst_prim(self, start_node_key):
        """
        :param start_node_key:random choose a node to start
        """
        if start_node_key is None:
            raise TypeError('Input node keys cannot be None')
        if start_node_key not in self.graph.nodes:
            raise ValueError('Invalid start or end node key')

        self.keys[start_node_key] = 0  # 优先级,按照目标,越小优先级越高
        self.priority_queue.decrease_key(start_node_key,
                                         self.keys[start_node_key])
        while self.priority_queue:
            mini_node_key = self.priority_queue.extract_min(
            ).obj  # 选出边<u,v>,这一轮出现的是上一个进入S的节点权重最小的邻接节点,即v
            self.in_queue[mini_node_key] = False
            curren_node = self.graph.nodes[mini_node_key]
            # 清除u剩余的邻接节点权重
            self.clear_pre_node_weight(curren_node)

            for node in curren_node.adj_nodes.values():
                if self.in_queue[node.key]:
                    weight = curren_node.adj_weights[
                        node.
                        key]  # A->B的权重存储在A的邻接权重中 A.adj_weights: {B.key:weight}
                    if weight < self.keys[node.key]:
                        self.keys[node.key] = weight
                        self.pred[node.key] = mini_node_key
                        self.priority_queue.decrease_key(node.key, weight)
            self.result.append(curren_node.key)
        print(self.result)

    def clear_pre_node_weight(self, curren_node):
        pre_key = self.pred[curren_node.key]
        if pre_key > -1:
            pre_node = self.graph.nodes[pre_key]
            for node in pre_node.adj_nodes.values():
                key = node.key
                if self.in_queue[key]:
                    self.keys[key] = sys.maxsize
                    self.pred[key] = -1
                    self.priority_queue.decrease_key(key, self.keys[key])
示例#3
0
    def __init__(self, graph: Graph):
        self.graph = graph
        self.pred = {}
        self.keys = {}
        self.in_queue = {}  # tag for node set V, True for V-S, False for S
        self.priority_queue = PriorityQueue()

        for node in self.graph.nodes.values():
            self.pred[node.key] = -1
            self.keys[node.key] = sys.maxsize
            self.in_queue[node.key] = True
            self.priority_queue.insert(
                PriorityQueueNode(node.key, self.keys[node.key]))
示例#4
0
class Dijkstra(object):
    
    def __init__(self, graph):
        self.graph = graph
        self.pred = {}  # 搜索结束后从尾顶点开始获取完整路径
        self.dist = {}  # 存储每个顶点到源点的最短距离
        self.priority_queue = PriorityQueue()

        for node in self.graph.nodes.values():
            self.pred[node.key] = -1
            self.dist[node.key] = sys.maxsize
            self.priority_queue.insert(PriorityQueueNode(node.key, self.dist[node.key]))

    def dijkstra(self, start_node_key, end_node_key=None):
        if start_node_key is None:
            raise TypeError('Input node keys cannot be None')
        if start_node_key not in self.graph.nodes:
            raise ValueError('Invalid start or end node key')

        self.dist[start_node_key] = 0  # 一旦顶点与起始顶点距离更新,则相应更新优先队列
        self.priority_queue.decrease_key(start_node_key, self.dist[start_node_key])

        while self.priority_queue:
            current_min = self.priority_queue.extract_min().obj
            current_node = self.graph.nodes[current_min]

            for node in current_node.adj_nodes.values():
                weight = current_node.adj_weights[node.key]
                new_weight = self.dist[current_node.key] + weight
                if new_weight < self.dist[node.key]:
                    self.dist[node.key] = new_weight
                    self.priority_queue.decrease_key(node.key, new_weight)
                    self.pred[node.key] = current_min

        # Walk backwards to determine the shortest path:
        # Start at the end node, walk the previous dict to get to the start node
        if end_node_key:
            return self.full_path(end_node_key)


    def full_path(self, end_node_key):
        reslut = []
        current_node_key = end_node_key
        while current_node_key != -1:
            reslut.append(current_node_key)
            current_node_key = self.pred[current_node_key]
        return reslut[::-1]
示例#5
0
class MSTPrim(object):
    def __init__(self, graph: Graph):
        self.graph = graph
        self.pred = {}
        self.keys = {}
        self.in_queue = {}  # tag for node set V, True for V-S, False for S
        self.priority_queue = PriorityQueue()

        for node in self.graph.nodes.values():
            self.pred[node.key] = -1
            self.keys[node.key] = sys.maxsize
            self.in_queue[node.key] = True
            self.priority_queue.insert(
                PriorityQueueNode(node.key, self.keys[node.key]))

    # 随机选择一个顶点开始
    def mst_prim(self, start_node_key):
        """
        :param start_node_key:random choose a node to start
        """
        if start_node_key is None:
            raise TypeError('Input node keys cannot be None')
        if start_node_key not in self.graph.nodes:
            raise ValueError('Invalid start or end node key')

        self.keys[start_node_key] = 0  # 优先级,按照目标,越小优先级越高
        self.priority_queue.decrease_key(start_node_key,
                                         self.keys[start_node_key])
        while self.priority_queue:
            mini_node_key = self.priority_queue.extract_min().obj
            self.in_queue[mini_node_key] = False
            curren_node = self.graph.nodes[mini_node_key]

            for node in curren_node.adj_nodes.values():
                if self.in_queue[node.key]:
                    weight = curren_node.adj_weights[node.key]
                    if weight < self.keys[node.key]:
                        self.keys[node.key] = weight
                        self.pred[node.key] = mini_node_key
                        self.priority_queue.decrease_key(node.key, weight)
 def setUp(self):
     self.priority_queue = PriorityQueue()
class TestPriorityQueue(unittest.TestCase):
    def tearDown(self):
        self.priority_queue = None

    def setUp(self):
        self.priority_queue = PriorityQueue()

    def test_priority_queue(self):
        self.assertEqual(self.priority_queue.extract_min(), None)
        self.priority_queue.insert(PriorityQueueNode('a', 20))
        self.priority_queue.insert(PriorityQueueNode('b', 5))
        self.priority_queue.insert(PriorityQueueNode('c', 15))
        self.priority_queue.insert(PriorityQueueNode('d', 22))
        self.priority_queue.insert(PriorityQueueNode('e', 40))
        self.priority_queue.insert(PriorityQueueNode('f', 3))
        self.priority_queue.decrease_key('f', 2)
        self.priority_queue.decrease_key('a', 19)
        mins = []
        while self.priority_queue.array:
            mins.append(self.priority_queue.extract_min().key)
        self.assertEqual(mins, [2, 5, 15, 19, 22, 40])