์•Œ๊ณ ๋ฆฌ์ฆ˜/๊ฐœ๋…

[Swift] BFS(Breadth-First Search, ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰)์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž

๊ฒฝํ‘ธ 2023. 2. 2. 19:00
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”~ 

 

์˜ค๋Š˜์€ ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰( BFS, Breadth-First Search )์ด๋ž€?

 

๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์€ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. 

 

์•„๋ž˜์˜ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ BFS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

 

 

 

์•ž์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ถ€ํ„ฐ ํ™•์ธํ•˜๊ฒŒ ๋˜๋Š”๋ฐ

์˜ˆ๋ฅผ ๋“ค์–ด์„œ 1์„ ๊ฐ€์žฅ ๋จผ์ € ํƒ์ƒ‰ํ•˜๊ณ  ๋‚˜๋ฉด ์ธ์ ‘ํ•œ 8, 5, 2๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

 

๋‹ค์Œ์€ 6๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ 9๊นŒ์ง€ ํƒ์ƒ‰์„ ์ง„ํ–‰ํ•˜๊ฒ ์ฃ ?

 

์ฆ‰, ๊ฐ™์€ ๋ ˆ๋ฒจ์— ์žˆ๋Š” ๋…ธ๋“œ๋“ค๋ถ€ํ„ฐ ํƒ์ƒ‰์„ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ 8๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋“  2๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜ ๋“  ์ˆœ์„œ๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 

์ค‘์š”ํ•œ ์ ์€ ๊ฐ™์€ ๋ ˆ๋ฒจ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ์ „๋ถ€ ํƒ์ƒ‰ํ•˜๊ณ  ๋‹ค์Œ ๋ ˆ๋ฒจ๋กœ ๋„˜์–ด๊ฐ„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

โœ”๏ธŽ Swift๋กœ ๊ตฌํ˜„ํ•ด ๋ณด๊ธฐ

์œ„์˜ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ๊ทธ๋ž˜ํ”„๋ฅผ ํ†ตํ•ด BFS๋ฅผ ๊ตฌํ˜„ํ•ด ๋ณด์ž.

 

1. ํ( Queue )

 

BSF๋Š” ๋ณดํ†ต ๋‘ ๊ฐœ์˜ ํ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

ํ๋Š” ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ค˜์œผ๋‹ˆ ์—ฌ๊ธฐ์„œ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

(1) ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ

(2) ๋ฐฉ๋ฌธํ•ด์•ผ ํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ

 

2. ์ธ์ ‘๋ฆฌ์ŠคํŠธ( Adjacency List )

 

๊ทธ๋ž˜ํ”„๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š”

์ธ์ ‘ ํ–‰๋ ฌ ๊ทธ๋ž˜ํ”„์™€ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹ ๋‘ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ๋Š” ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ธ์ ‘๋ฆฌ์ŠคํŠธ๋ž€ ๋ง ๊ทธ๋Œ€๋กœ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜์—ดํ•œ ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

1 8 5 2  
8 1 6 4 3
5 1      
2 1 9    
6 8 10 7  
4 8      
3 8      
9 2      
10 6      
7 6      

 

์œ„์˜ ๊ฐ’๋“ค์„ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

let graph: [String: [Int]] = [
    "1" : [8, 5, 2],
    "8" : [1, 6, 4, 3],
    "5" : [1],
    "2" : [1, 9],
    "6" : [8, 10, 7],
    "4" : [8],
    "3" : [8],
    "9" : [2],
    "10" : [6],
    "7" : [6]
]

 

2. BFS

์„ค๋ช…์€ ์ฃผ์„์œผ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

func breadthFirstSearch(graph: [String: [Int]], start: String) -> [String] {

    // ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ
    var visitedQueue: [String] = []
    // ๋ฐฉ๋ฌธํ•ด์•ผํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ
    var needVisitQueue: [String] = [start]
    
    while !needVisitQueue.isEmpty {
        
        let node: String = String(needVisitQueue.removeFirst())
        
        // ์ด๋ฏธ ๋ฐฉ๋ฌธํ–ˆ๋˜ ๋…ธ๋“œ๋ผ๋ฉด continue ์ฒ˜๋ฆฌ
        if visitedQueue.contains(node) {
            continue
        }
        
        visitedQueue.append(node)
        // ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
        // ๋งŒ์•ฝ ๊ฐ€์žฅ ์ฒ˜์Œ์— "1"์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด 1๊ณผ ์ธ์ ‘ํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ needVisitQueue์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •
        needVisitQueue += graph[node].map{ $0.map { String($0) } } ?? []
    }
    
    return visitedQueue
}

print(breadthFirstSearch(graph: graph, start: "1"))
// ["1", "8", "5", "2", "6", "4", "3", "9", "10", "7"]

 

์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์•ˆ๋…• ~ ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป

 

๋ฐ˜์‘ํ˜•