3.5 Graph - 3.5.5 A* Algorithm

2024. 1. 31. 21:22ใ†CS - Roadmap.sh/3. Common Algorithms

CS - 3. Common Algorithms - 3.5 Graph - 3.5.5 A* Algorithm

A* Algorithm

๐Ÿ’ก A* is a graph traversal algorithm that is used to find the shortest path between two nodes in a graph. It is a modified version of Dijkstra’s algorithm that uses heuristics to find the shortest path. It is used in pathfinding and graph traversal.

A*๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ๋‘ ๋…ธ๋“œ ์‚ฌ์ด์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํœด๋ฆฌ์Šคํ‹ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” Dijkstra ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ˆ˜์ • ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ๊ฒฝ๋กœ ์ฐพ๊ธฐ ๋ฐ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

A* (A Star) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€, ๊ทธ๋ž˜ํ”„์—์„œ ์‹œ์ž‘ - ๋ชฉํ‘œ ๋…ธ๋“œ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

A*๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ์‚ฌ์šฉํ•ด ํƒ์ƒ‰์„ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •์—์„œ ๋” ๋‚˜์€ ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์ถ”์ • ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ฃผ๋กœ ํ˜„์žฌ ์ƒํƒœ์—์„œ ๋ชฉํ‘œ ์ƒํƒœ๊นŒ์ง€์˜ ๋น„์šฉ์„ ์ถ”์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜ h(n)์€ ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ๋ชฉํ‘œ๋…ธ๋“œ๊นŒ์ง€์˜ ์ถ”์ • ๊ฑฐ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋Š” ์ด์œ ๋Š”, ๋” ๋น ๋ฅด๊ฒŒ ๋ชฉํ‘œ ๋…ธ๋“œ์— ๋„๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ํƒ์ƒ‰ ๊ฒฝ๋กœ๋ฅผ ์•ˆ๋‚ดํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.

 

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

2์ฐจ์› array์—์„œ ๊ฒฝ๋กœ ์ฐพ๊ธฐ ๋ฌธ์ œ๋ฅผ ์ƒ๊ฐํ•ด ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋กœ ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ( ๋‘ ์  ์‚ฌ์ด์˜ ์ง์„  ๊ฑฐ๋ฆฌ)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ, ๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ, ํ•ด๋ฐ ๊ฑฐ๋ฆฌ ๋“ฑ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.)

ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ (1,2)์ด๊ณ  ๋ชฉํ‘œ๋…ธ๋“œ๊ฐ€ (4,3)์ด๋ผ๋ฉด ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜ h(n)์€

h(n) = sqrt((4-1)^2 + (3-2)^2) ์ด๋ผ ํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ๊ณ„์‚ฐํ•œ h(n)์€ ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ๋ชฉํ‘œ ๋…ธ๋“œ ๊นŒ์ง€์˜ ์ถ”์ • ๊ฑฐ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์ด ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ, A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ€์žฅ ํšจ์œจ์ ์ธ ํƒ์ƒ‰ ๊ฒฝ๋กœ๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ฌผ๋ก  ์ด๋Š” ์•„์ฃผ ๊ฐ„๋‹จํ•œ ๋ฌธ์ œ๊ณ , ๋ฌธ์ œ์˜ ํŠน์„ฑ, ๋ฐ์ดํ„ฐ์˜ ํŠน์„ฑ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์„ค์ • ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

In Python
import heapq

# ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. - ๋ฌธ์ œ์— ๋งž์ถฐ์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ ์‚ฌ์šฉ
def heuristic(a, b):
    return abs(b[0] - a[0]) + abs(b[1] - a[1])

# A* ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„, 2์ฐจ์›๋ฐฐ์—ด(array), ์‹œ์ž‘๋…ธ๋“œ(start), ๋ชฉํ‘œ๋…ธ๋“œ(goal) ์„ ์ž…๋ ฅ๋ฐ›์Œ
def astar(array, start, goal):

    # 8 ๋ฐฉํ–ฅ ์ด๋™์„ ์œ„ํ•œ ์ด์›ƒ ๋…ธ๋“œ(neighbors)์˜ ์ขŒํ‘œ ์ •์˜
    neighbors = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)]

    # ๊ฐ์ข… ๋ณ€์ˆ˜ 
    # close_set : ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์˜ ์ง‘ํ•ฉ, 
    # came_from : ๊ฐ ๋…ธ๋“œ์˜ ์ด์ „ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•œ dict, 
    # gscroe : ์‹œ์ž‘๋…ธ๋“œ ์—์„œ ๊ฐ ๋…ธ๋“œ๊นŒ์ง€์˜ ์‹ค์ œ ๋น„์šฉ, 
    # fscore : gscore์™€ ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๊ฒŒ์‚ฐํ•œ ์ถ”์ • ๋น„์šฉ์˜ํ•ฉ, 
    # oheap : ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๋“ค์„ ์ €์žฅํ•˜๋Š” ์šฐ์„ ์ˆœ์œ„ ํ
    close_set = set()
    came_from = {}
    gscore = {start:0}
    fscore = {start:heuristic(start, goal)}
    oheap = []

    # ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ์šฐ์„ ์ˆœ์œ„ ํ์— ์ถ”๊ฐ€
    heapq.heappush(oheap, (fscore[start], start))
    
    #์šฐ์„ ์ˆœ์œ„ ํ๊ฐ€ ๋นŒ๋–„๊นŒ์ง€(๋ชจ๋“  ๋…ธ๋“œ ๋ฐฉ๋ฌธ) ๋ฐ˜๋ณต
    while oheap:

        #์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๊ฐ€์žฅ ๋‚ฎ์€ ๋น„์šฉ์˜ ๋…ธ๋“œ ์ถ”์ถœ
        current = heapq.heappop(oheap)[1]

        #์ถ”์ถœ ๋…ธ๋“œ๊ฐ€ ๋ชฉํ‘œ ๋…ธ๋“œ๋ผ๋ฉด, ๊ฒฝ๋กœ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜
        if current == goal:
            data = []
            while current in came_from:
                data.append(current)
                current = came_from[current]
            return data


        #์ถ”์ถœํ•œ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์˜ ์ง‘ํ•ฉ์— ์ถ”๊ฐ€
        close_set.add(current)
        
        #์ถ”์ถœํ•œ ๋…ธ๋“œ์˜ ์ด์›ƒ๋…ธ๋“œ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋“ค
        for i, j in neighbors:
            
            #์ด์›ƒ ๋…ธ๋“œ์˜ ์ขŒํ‘œ๋ฅผ ๊ณ„์‚ฐ
            neighbor = current[0] + i, current[1] + j
            
            #ํ˜„์žฌ๋…ธ๋“œ์—์„œ ์ด์›ƒ๋…ธ๋“œ๊นŒ์ง€ ๋น„์šฉ ๊ณ„์‚ฐ
            tentative_g_score = gscore[current] + heuristic(current, neighbor)
            
            # ์ด์›ƒ ๋…ธ๋“œ๊ฐ€ ๊ทธ๋ž˜ํ”„ ๋‚ด์— ์žˆ๋Š”์ง€, ์žฅ์• ๋ฌผ์ด ์žˆ๋Š”์ง€, ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์ธ์ง€ ํ™•์ธ, ์ด์— ํ•ด๋‹นํ•˜๋ฉด ์ด์›ƒ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š๊ณ  ๊ฑด๋„ˆ๋œ€
            if 0 <= neighbor[0] < array.shape[0]:
                if 0 <= neighbor[1] < array.shape[1]:                
                    if array[neighbor[0]][neighbor[1]] == 1:
                        continue
                else:
                    continue
            else:
                continue
            if neighbor in close_set and tentative_g_score >= gscore.get(neighbor, 0):
                continue
            
            # ์ด์›ƒ ๋…ธ๋“œ์˜ ์ด ๋น„์šฉ์ด ํ˜„์žฌ๊นŒ์ง€ ๊ณ„์‚ฐํ•œ ๋น„์šฉ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜, ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ผ๋ฉด ์ด ๋น„์šฉ๊ณผ ์ด์ „๋…ธ๋“œ ๊ฐฑ์‹ , ์šฐ์„ ์ˆœ์œ„ ํ์— ์ถ”๊ฐ€        
            if  tentative_g_score < gscore.get(neighbor, 0) or neighbor not in [i[1]for i in oheap]:
                came_from[neighbor] = current
                gscore[neighbor] = tentative_g_score
                fscore[neighbor] = tentative_g_score + heuristic(neighbor, goal)
                heapq.heappush(oheap, (fscore[neighbor], neighbor))
                
    return False

 

์ด๋Ÿฐ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

nmap = np.array([
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,1,1,1,0,0,0],
    [0,0,0,0,1,0,1,0,0,0],
    [0,0,0,0,1,0,1,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0]
])

์ด๋Ÿฐ array ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.

๋นจ๊ฐ„์ (0,0) ์—์„œ ํŒŒ๋ž€์ (4,5) ๊นŒ์ง€์˜ ์ตœ์†Œ ๋ฃจํŠธ๋ฅผ ์•Œ๊ณ ์‹ถ์Šต๋‹ˆ๋‹ค.

(์ผ๋ฐ˜์ ์ธ x,y ๋ฐ์นด๋ฅดํŠธ ์ขŒํ‘œํ‰๋ฉด์ด ์•„๋‹ˆ๋ผ array ๋ฅผ ๊ตฌํ˜„ํ•œ ์ขŒํ‘œ์ž„์„ ๊ฐ์•ˆํ•ด์ฃผ์„ธ์š”.(์ฐจํ›„์ˆ˜์ •))

 

์ฃผํ™ฉ์ƒ‰ ์ ์„ ์ด์œผ๋ฉด ๋นจ๊ฐ„์ ๊ณผ ํŒŒ๋ž€์ ์˜ ์ตœ์†Œ ๋น„์šฉ ๊ตฌ๊ฐ„์ž…๋‹ˆ๋‹ค.

 

 

 

ํ™œ์šฉ

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ตœ๋‹จ ๋น„์šฉ ๊ฑฐ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค๋Š” ์ ์€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ , A*๋Š” ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•ด ์ข€๋” ํšจ์œจ์ ์œผ๋กœ ์ฐพ์„์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ด๋Š” ๋ฏธ๋กœ์ฐพ๊ธฐ์— ํ™œ์šฉํ•˜๊ธฐ ์‰ฝ๊ณ , ๋”ฐ๋ผ์„œ ๊ฒฝ๋กœ ๊ณ„ํš, ๊ฒŒ์ž„ ์ธ๊ณต์ง€๋Šฅ, ์ž์œจ์ฃผํ–‰ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

์ฐธ๊ณ  ๋งํฌ

https://aliencoder.tistory.com/32

 

[Python] ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ(Euclidean Distance), ๋งจํ•˜ํƒ„ ๊ฑฐ๋ฆฌ(Manhattan Distance), ํ•ด๋ฐ ๊ฑฐ๋ฆฌ(Hamming Distance)๋ฅผ ์ด

์ฃผ์š” ๊ฐœ๋… ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ(Euclidean Distance) ๋งจํ•˜ํƒ„ ๊ฑฐ๋ฆฌ(Manhattan Distance) ํ•ด๋ฐ ๊ฑฐ๋ฆฌ(Hamming Distance) ๋‘ ์  ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์œ ์‚ฌ๋„(Similarity)์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค. ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ํ•ด๋‹น ๋ฐ์ดํ„ฐ

aliencoder.tistory.com

https://choiseokwon.tistory.com/210

 

ํŒŒ์ด์ฌ A* (A-star) ์ตœ๋‹จ ๊ฒฝ๋กœ ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜

A* ๊ธธ ์ฐพ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ 1968๋…„์— Peter Hart, Nils Nilsson, Bertram Raphael์— ์˜ํ•ด ์ตœ์ดˆ ๊ณต๊ฐœ๋๋‹ค. ์šฐ์„  Node ํด๋ž˜์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌํ˜„๋  ๊ฒƒ์ด๋ฉฐ, ์•„๋ž˜ ํด๋ž˜์Šค๋ฅผ ๋ณด๊ณ  ๊ธ€์„ ์ฝ์œผ๋ฉด ์ข€ ๋” ํŽธํ•  ๊ฒƒ์ด๋‹ค. class Nod

choiseokwon.tistory.com

https://velog.io/@1ncursio/A-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%84-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EC%9E%90-Python3

 

A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ด๋ณด์ž [Python3]

์ง€๋‚œ ์‹œ๊ฐ„์—๋Š” A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ž‘๋™ ๋ฐฉ์‹์„ ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.๊ทธ๋Ÿผ ์˜ค๋Š˜์€ ์‹ค์ œ๋กœ A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•ด ๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.์šฐ์„  ์ด์ „ ์‹œ๊ฐ„์— ์ž๋ฃŒ๋กœ ์‚ฌ์šฉํ•œ ๊ทธ๋ฆผ์„ ๋ฆฌ์ŠคํŠธ๋กœ ํ‘œํ˜„ํ•ด๋ด…์‹œ๋‹ค. 7 by 7 ๋ฆฌ์Šค

velog.io

 

728x90

'CS - Roadmap.sh > 3. Common Algorithms' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

3.6 Greedy Algorithms - 3.6.1 Huffman Coding  (0) 2024.02.03
3.6 Greedy Algorithms  (0) 2024.02.02
3.5 Graph - 3.5.4 Dijkstraโ€™s Algorithm  (2) 2024.01.30
3.5 Graph - 3.5.3 Bellman Fordโ€™s Algorithm  (1) 2024.01.29
3.5 Graph - 3.5.2 Depth First Search(DFS)  (1) 2024.01.29