圖算法總結(判斷有環、最短路徑)

有向圖判斷有環

拓撲排序

if __name__ == "__main__":
    v = [[0, 0, 0, 0, 1], [1, 0, 0, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0]]
    e = [[]]
    in_v = {}
    cnt = 0
    visited = set()
    circle = []
    # 計算每個點的入度
    for i in range(len(v)):
        for j in range(len(v)):
            if v[i][j] == 1:
                if j not in in_v.keys():
                    in_v[j] = 0
                in_v[j] += 1

    # 拓撲
    # 入度爲0的點,加入到visited中
    change = True
    while change:
        change = False
        for node in range(len(v)):
            if node not in visited and (node not in in_v.keys() or in_v[node] == 0):
                change = True
                visited.add(node)
                for j in range(len(v)):
                    if v[node][j] == 1:
                        in_v[j] -= 1

    # 沒有被visited的,即爲環
    for node in range(len(v)):
        if node not in visited:
            circle.append(node)

    print(circle)

應用:

給定一堆序列標號(標號用整數),形式爲[a,b],表示標號爲a,b的兩個物體的體積關係滿足:a > b,用合適的數據結構存儲數據,並判斷這堆序列是否有效。(比如[a,b], [b, d], [d, a]這個就不是有效的,因爲a > b, b > d, 那麼 a > d, 但是最後一個序列說的是 d > a,矛盾了。)

思路:

題目實際是,求圖中是否有環,用拓撲結構,把入度爲0的結點全部刪掉,直到刪不動爲止。

# 有向圖判斷有環:拓撲算法
def hasCircel(inputs):
    graph = {}
    in_v = {}
    nodes = set()
    # 用字典存每個點連接的點
    # 保存每個點入度
    for pair in inputs:
        a,b = pair
        nodes.add(a)
        nodes.add(b)
        if a not in graph.keys():
            graph[a] = [b]
        else:
            graph[a].append(b)
        if b not in in_v.keys():
            in_v[b] = 0
        in_v[b] += 1

    # 拓撲判斷是否有環:
    # 入度爲0的點刪去,它相關的出度點入度-1,不斷迭代
    nodes = list(nodes)
    visted = [False]*len(nodes)
    change = True
    while change:
        change = False
        for i in range(len(nodes)):
            if not visted[i] and (nodes[i] not in in_v.keys() or in_v[nodes[i]] == 0):
                visted[i] = True
                change = True
                if nodes[i] in graph.keys():
                    connect_nodes = graph[nodes[i]]
                    for node in connect_nodes:
                        in_v[node] -= 1

    for i in range(len(nodes)):
        if not visted[i]:
            return False
    return True

if __name__ == '__main__':
    inputs = [[1, 2], [2, 3], [3, 1]]
    res = hasCircel(inputs)
    print(res)

 

Dijkstra算法(單源最短路徑)

貪心思想實現的,首先把起點到所有點的距離存下來找個最短的,然後鬆弛一次再找出最短的,所謂的鬆弛操作就是,遍歷一遍看通過剛剛找到的距離最短的點作爲中轉站會不會更近,如果更近了就更新距離,這樣把所有的點找遍之後就存下了起點到其他所有點的最短距離。

具體實現參考:

https://blog.csdn.net/lbperfect123/article/details/84281300

 

Floyd(多源最短路徑)

https://blog.csdn.net/shezjoe/article/details/80670188

 

bfs/dfs

https://blog.csdn.net/wzy_2017/article/details/78910697

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章