iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1
AI/ ML & Data

機器學習與深度學習背後框架與過程論文與實作系列 第 5

DAY5 圖形演算法的學習攻略 5/30

  • 分享至 

  • xImage
  •  

根據CAR Theorem解決問題的重要程序步驟:(1) Criticality:探討問題的本質 (2) Abstraction:抽象化簡化問題。 (3) Restriction:將範圍縮小,首要解決的優先,次要的因子後探討。

我們利用Graph來表示物件(object)之間的關係,其中Grapg的組成需由點(Nodes)與線(Edge)來促成,利用符號表示成G=(V,E)而e={u,v}。當Graph具有方向性時{u,v} == {v,u};當Grapg不具有方向性(u,v)!=(v,u)。

生活中常見以graph來解決問題的表示方式有很多,台灣的捷運地圖就是一個很好的例子:
https://ithelp.ithome.com.tw/upload/images/20240812/20168552LRPsYXsbpt.png
而社交網絡的表示方式,則是將原本抽象概念的思維形象化:
https://ithelp.ithome.com.tw/upload/images/20240812/20168552tRaocuOJCT.jpg
儘管Nodes與Edges的組成,很大的程度上解決了我們需要知道是否為neighbor的事實,卻無法藉由Edge的長度去知道交通時間,然而若是一張航海地圖,比例尺能夠有根據地調整之下,兩地之間的遠距就能夠被計算出來。

接下來我們介紹path的概念,假設P= <v1,v2,v3,v4...,vn, vn+1...>,Path上兩個連續的點之間以Edge組成,若兩個相同的起點與終點之間有無限多個走法,當我們需要找尋最小的距離(最短路徑),則此時我們正在求最少的Edges,假使一個路徑中沒有重複相同的點,我們稱之為Simple;若兩個點有重複形成一個圓,曾稱之為Circle。

倘若我們的Grapg是一個Tree形狀,透過rooted tree可以清楚看到Nodes之間的聯繫關係,在這裡稱連結下一個點的前一個nodes為parents,也就是他們之間具有關係。
https://ithelp.ithome.com.tw/upload/images/20240812/20168552tbkgzrcQZg.png

廣度優先搜尋 Breadth-First Search(BFS)
以上圖的連通元件(Connected Component)做舉例,假如我們以1為圓心漣漪式地向外擴散為搜尋的範圍,從圖示中可發現A為搜尋時間L0之內能夠抵達的範圍,B和C為L1時間內的搜尋範圍...以此類推。這些相鄰節點(adjacent nodes)只要有和圓心1有connectivity的關係,就會被BFS搜尋到,藉由此搜尋方法能夠找到從源頭至目的點的最少Edges,也就是最短路徑,值得一提的是,兩個Nodes之間的layer只差1。ex.小畫家水桶塗色

from collections import deque
graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F'],
    'D': ['E'],
    'E': ['G'],
    'F': ['G'],
    'G': []
}

def bfs_shortest_path(graph, start, goal):
    #初始化
    queue = deque([start])
    #路徑字典
    predecessor = {start: None}
    #訪問點集合
    visited = set([start])

    while queue:
        current = queue.popleft()

        # 如果找到目標節點建構路徑
        if current == goal:
            path = []
            while current is not None:
                path.append(current)
                current = predecessor[current]
            return path[::-1]  # 反转路径

        #遍佈neighbor
        for neighbor in graph[current]:
            if neighbor not in visited:
                visited.add(neighbor)
                predecessor[neighbor] = current
                queue.append(neighbor)

    return None  #如果沒有找到路徑

#使用BFS找到A到E的最短路徑
path = bfs_shortest_path(graph, 'A', 'E')
print("The shortest path from A to E is:", path)

深度優先搜尋 Depth-First Search(DFS)
從區分點(Vertex)出發,只要有路(Edges)就會往前繼續行走,以數字較小的做優先探索,若無路可進則走回去繼續進行DFS搜尋,直到無法再繼續Explore,則會Return繼續進行搜索工作,直到全部都搜索過一遍。

def dfs_path(graph, start, goal):
    #初始化
    stack = [start]
    #路徑字典
    predecessor = {start: None}
    #訪問點集合
    visited = set([start])

    while stack:
        current = stack.pop()

        #找到目標節點建構路徑
        if current == goal:
            path = []
            while current is not None:
                path.append(current)
                current = predecessor[current]
            return path[::-1]  #反轉

        #遍歷neighbor
        for neighbor in graph[current]:
            if neighbor not in visited:
                visited.add(neighbor)
                predecessor[neighbor] = current
                stack.append(neighbor)

    return None  #如果未找到路徑

#使用DFS找到A到E路徑
path = dfs_path(graph, 'A', 'E')
print("The path from A to E found by DFS is:", path)

在BFS之中的graph,為路徑的edges稱之為Tree Edge,一般來說通常為parent-child關係;反之稱為Non-Tree Edge,一般來說為uncle-nephew或是sister-brother關係。在DFS之中的graph,為路徑的edges稱之為Tree Edge,一般來說通常為parent-child關係;反之稱為Non-Tree Edge,一般來說為ancestor-descendants。下圖清楚說明BFS Tree與DFS Tree的探索路徑差異:
https://ithelp.ithome.com.tw/upload/images/20240812/20168552DSDjVZudvb.png

接下來我們介紹Queue&Stack來建造資料結構,之後會常常看到:
Queue
需要服從FIFO(First in,First out)規則,在Q=(a1,a2,a3...an,an+1)含有元素的情形下,我們稱a1為front,an為rear,當我們新增(push)一個資料進入會從尾巴開始,當我們刪除(pop)一個資料會從頭開始處理。
https://ithelp.ithome.com.tw/upload/images/20240812/20168552ISPERO4o4M.jpg
Stack
需要服從LIFO(Last in,First out)規則,最先進去的需要出去(pop)才能將新的資料push in。
https://ithelp.ithome.com.tw/upload/images/20240812/20168552mnBBDOL6Fa.png

今天的文章就到這裡,下個章節會更精彩哦~


上一篇
DAY4 常見的runtime衡量方式補充 4/30
下一篇
DAY6 貪婪演算法的啟蒙之路 6/30
系列文
機器學習與深度學習背後框架與過程論文與實作28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言