#1 ๊ทธ๋ํ์ ํ์
๋๋น ์ฐ์ ํ์ - ์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์
์ํค๋ฐฑ๊ณผ, ์ฐ๋ฆฌ ๋ชจ๋์ ๋ฐฑ๊ณผ์ฌ์ .
ko.wikipedia.org
๊ทธ๋ํ์ ๊ฐ ์ ์ ์ ํ๋ฒ์ฉ ๋ฐฉ๋ฌธํ ํ์๊ฐ ์๋ค๊ณ ํด๋ณด์. ๊ทธ ๋ฐฉ๋ฌธ์ ๋ฐฉ๋ฒ์๋ ํฌ๊ฒ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. ํ๋๋ ๋๋น ์ฐ์ ํ์์ด๋ค. ๋ ๋ค๋ฅธ ํ๋๋ ๊น์ด ์ฐ์ ํ์์ด๋ค. ๋ณธ ๊ฒ์๊ธ์์๋ ๋๋น ์ฐ์ ํ์๋ฒ์ ๋ค๋ฃฌ๋ค. (๊น์ด ์ฐ์ ํ์์ ๋ํด์๋ ์ด ๊ฒ์๊ธ์์ ๋ค๋ฃฌ๋ค)
#2 ์๊ณ ๋ฆฌ์ฆ

์๋๋ผ๋ฉด ์์๋๋ฅผ ํตํด ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐํ๊ณ ์ฝ๋๋ก ๋์ด๊ฐ๋ ํธ์ด ์ดํดํ๊ธฐ ์ข์ง๋ง, ๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ทธ๋ฅ ์ฝ๋๋ถํฐ ๋ณด๋ ๊ฒ ์คํ๋ ค ์ดํด๊ฐ ๋ ๋น ๋ฅด๋ค๊ณ ์๊ฐํ๋ค. ๋ค๋ง, ์ธ์ ๋ฐฐ์ด (Adjacency Array)์ ์ง์์ ๋ํด์๋ ์๊ณ ์์ด์ผ ํ๋ค๋ ์ ์ ํ๋ค. ์ฌ๊ธฐ์ ์ฌ์ฉํ ์ธ์ ๋ฐฐ์ด์ ์ด ๊ฒ์๊ธ์ ์๋ค (๊ฐ์ค์น๊ฐ ์๋ ๋ฌดํฅ ๊ทธ๋ํ).
๋์ ์ '๋๋น ์ฐ์ ' ํ์์ด๋ผ๋ ์ด๋ฆ์ด ๋ถ์๋์ง๋ ์ค๋ช
ํ ๊ฐ์น๊ฐ ์๋ค. ๋๋น ์ฐ์ ํ์์ ๋ค๋ฅธ ๋ง๋ก '๋ด ์์ ์ฐ์ ' ํ์์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ํ๋ ๊น์ด์ ๋๋ฎ์ด๊ฐ ์ ๊ทธ๋ํ์ฒ๋ผ y์ถ๊ณผ ํํํ๊ฒ ๊ทธ๋ ค์ง๋ค. ๋ฐ๋ผ์ ๋ด ์์์ ์ฐ์ ์ผ๋ก ํ์ํ๋ค๋ ๋ง์, (2 โ 3 โ 4) โ (5 โ 6 โ 7 โ 8) โ ...์ ๊ฐ์ ์์ผ๋ก ํ์ํ๋ค๋ ๋ง์ด ๋๋ค (๊ฐ์ ๊ดํธ ๋ด์ ์ ์ ๋ค์ ์๋ก ์์๊ฐ ๋ค๋ฐ๋ ์๋ ์์ (#3 ์ฐธ์กฐ)). ์ด ํ์์ x์ถ(๋๋น)๋ฅผ ์ฐ์ ํด ์ด๋ํ๋ ๋ชจ์์ด ๋๋ค (y์ถ ์ด๋์ x์ถ ํ์์ด ์ข
๋ฃ๋ ํ์ ์ํ๋๋ค. ์ฐ์ ์์๊ฐ ์๋ ๊ฒ์ด๋ค). ๊ทธ๋์ ๋๋น ์ฐ์ ํ์์ด๋ผ ๋ถ๋ฅธ๋ค.
#3 ์ฝ๋ - ์ฝํ๋ฆฐ
#3-1 ๊ธฐ๋ณธ ์ฝ๋
import java.util.*
fun main() {
// (1) listOfAdjacencyArray[n]์ด ๊ฐ์ง๋ ์๋ฏธ๋ฅผ ์์์ผ ํ๋ค (์ค๋ช
์ฐธ์กฐ)
val listOfAdjacencyArray = listOf(
arrayOf(1, 2),
arrayOf(0, 3, 4),
arrayOf(0, 4),
arrayOf(1),
arrayOf(1, 2)
)
bfs(listOfAdjacencyArray, 0) // 0๋ฒ ์ ์ (vertex)์์ ํ์ ์์
}
fun bfs(listOfAdjacencyArray: List<Array<Int>>, startVertex: Int) {
// (2) Queue๋ก ํ์ ์์๋ฅผ ๊ฒฐ์ ํ๋ค. discovered๋ Queue์ ์ด๋ฏธ ์๊ฑฐ๋, ๋ฐฉ๋ฌธ์ด ์๋ฃ๋ ์ ์ ๋ค์ ๊ธฐ๋กํ๋ Set(์งํฉ)์ด๋ค
val queue: Queue<Int> = LinkedList()
val discovered = mutableSetOf<Int>()
// (3) startVertex๋ถํฐ Queue์ ๋ฃ๋๋ค. ๋์์ discovered์๋ ์ถ๊ฐํ๋ค.
queue.add(startVertex)
discovered.add(startVertex)
while (queue.isNotEmpty()) {
// (4) ์ ์ ์ Queue์์ ๋นผ๋ด๊ณ , ๋ฐฉ๋ฌธํด์ ์งํํ ์ผ์ ์ํํ๋ค. ์ฌ๊ธฐ์ doSomethingFunction()์ผ๋ก ํํํ๋ค
val vertex = queue.remove()
// doSomethingFunction(vertex)
println("Visit complete: $vertex")
// (5) (4)์์ ๋นผ๋๋(remove()) ์ ์ ์ ์ด์ ์ ์ ๋ง๋ค (6)์ ์ํ
for (neighborVertex in listOfAdjacencyArray[vertex]) {
// (6) discovered ๋ชฉ๋ก์ ์๋ค๋ฉด, Queue์ ์ถ๊ฐํ๊ณ ๋์์ discovered์๋ ์ถ๊ฐํ๋ค
if (neighborVertex !in discovered) {
queue.add(neighborVertex)
discovered.add(neighborVertex)
}
}
}
}
(1) listOfAdjacencyArray[n]์ด ๊ฐ์ง๋ ์๋ฏธ๋ฅผ ์์์ผ ํ๋ค
์ ์ ์ ๋ถ์ฌ๋ ๋ฒํธ๊ฐ 0 ~ N์ผ ๋, listOfAdjacencyArray[n]์ n๋ฒ ์ ์ ์ ์ฐ๊ฒฐ๋ ์ด์(neighbor) ์ ์ ๋ค์ ๋ฐฐ์ด์ ์๋ฏธํ๋ค.
(2) Queue๋ก ํ์ ์์๋ฅผ ๊ฒฐ์ ํ๋ค. discovered๋ ...
Queue๋ก ํ์ ์์๋ฅผ ๊ฒฐ์ ํ๋ค๋ ๋ง์, Queue์ add๋ ์์๋๋ก ๋ฐฉ๋ฌธํ๋ค๋ ์ด์ผ๊ธฐ๊ฐ ๋๋ค.
(3) startVertex๋ถํฐ Queue์ ๋ฃ๋๋ค. ๋์์ discovered์๋ ์ถ๊ฐํ๋ค.
์์ ์ ์ ์ Queue์ discovered ๊ฐ๊ฐ์ ์ถ๊ฐํ๋ค.
(4) ์ ์ ์ Queue์์ ๋นผ๋ด๊ณ , ๋ฐฉ๋ฌธ...
queue.remove()๋์ด doSomethingFunction()์ด ์ํ๋๋ ์์ ๋ถํฐ 'ํด๋น ์ ์ ์ ๋ฐฉ๋ฌธํ๋ค'๊ณ ๋ณผ ์ ์๋ค. ๊ด์ ์ ๋ฐ๋ผ, discovered์ ๋ชฉ๋ก์ด ์ถ๊ฐ๋๋ ์๊ฐ์ ์ ์ ์ ๋ฐฉ๋ฌธํ๋ค๊ณ ๋ณผ ์๋ ์๊ฒ ์ผ๋, ๋ง์ฝ ๊ทธ ๊ด์ ์ด๋ผ๋ฉด doSomethingFunction()์ ์์น๋ฅผ discovered.add() ์งํ๋ก ์ด๋์์ผ์ผ ํ ๊ฒ์ด๋ค. ์ด ๊ฒฝ์ฐ์ ์ฝ๋๋ #3-3์ ์๋ค.
(5) (4)์์ ๋นผ๋๋(remove()) ์ ์ ์ ์ด์ ์ ์ ๋ง๋ค (6)์ ์ํ
listOfAdjacencyArray[n]์ ๋ฐฉ๊ธ ๋ฐฉ๋ฌธ ์๋ฃํ ์ ์ n์ ์ฐ๊ฒฐ๋ ์ด์ ์ ์ ๋ค์ ๋ฐฐ์ด์ด๋ค. ์ด ๋ฐฐ์ด์ ์์๋ง๋ค (6)์ ์ํํ๋ค.
(6) discovered ๋ชฉ๋ก์ ์๋ค๋ฉด, Queue์ ์ถ๊ฐํ๊ณ ๋์์ discovered์๋ ์ถ๊ฐํ๋ค
๋ฐฐ์ด listOfAdjacencyArray[vertex]์ ๊ฐ ์์๋ฅผ Queue์ ๋ฃ๋๋ค. #2์ ๋ด์ฉ ์ค (2 โ 3 โ 4) โ (5 โ 6 โ 7 โ 8) โ ...์์ ๊ดํธ ์์ ์์๋ ๋ฐ๋ ์ ์๋ค๊ณ ํ ์ด์ ๊ฐ ์ด ๋๋ฌธ์ด๋ค. ๋ง์ฝ #2์ ๊ทธ๋ํ์ ์ธ์ ๋ฐฐ์ด์ ๋ง๋ค ๋ listOfAdjacencyArray[1] = { 3, 4, 2 }๋ก ๋์๋ค๋ฉด (3 โ 4 โ 2) โ ...์์ผ๋ก Queue์ ๋ค์ด๊ฐ ๊ฒ์ด๊ณ , listOfAdjacencyArray[1] = { 4, 2, 3 }๋ก ๋์๋ค๋ฉด (4 โ 2 โ 3) โ ...์์ผ๋ก Queue์ ๋ค์ด๊ฐ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ Queue๋ ์ ์
์ ์ถ์ด๋ฏ๋ก, ๋น์ฐํ ๋ฐฉ๋ฌธ ์์ ๋ํ ๋๊ฐ์ด ๋ฐ๋ผ๊ฐ ๊ฒ์ด๋ค.
#3-2 ์ ๋ค๋ฆญ์ ์ด์ฉํ ์ฝ๋
import java.util.*
import kotlin.collections.HashMap
fun main() {
// (1) mapOfAdjacencyArray[n]์ด ๊ฐ์ง๋ ์๋ฏธ๋ฅผ ์์์ผ ํ๋ค (์ค๋ช
์ฐธ์กฐ)
val mapOfAdjacencyArray = HashMap<String, Array<String>>()
mapOfAdjacencyArray["๊ฐ์์ง"] = arrayOf("๊ณ ์์ด", "์ฌ์ด")
mapOfAdjacencyArray["๊ณ ์์ด"] = arrayOf("๊ฐ์์ง", "์ฝ๋ฟ์", "ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด")
mapOfAdjacencyArray["์ฌ์ด"] = arrayOf("๊ฐ์์ง", "ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด")
mapOfAdjacencyArray["์ฝ๋ฟ์"] = arrayOf("๊ณ ์์ด")
mapOfAdjacencyArray["ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด"] = arrayOf("๊ณ ์์ด", "์ฌ์ด")
bfs(mapOfAdjacencyArray, "๊ฐ์์ง") // "๊ฐ์์ง" ์ ์ (vertex)์์ ํ์ ์์
}
fun <T> bfs(mapOfAdjacencyArray: Map<T, Array<T>>, startVertex: T) {
// (2) Queue๋ก ํ์ ์์๋ฅผ ๊ฒฐ์ ํ๋ค. discovered๋ Queue์ ์ด๋ฏธ ์๊ฑฐ๋, ๋ฐฉ๋ฌธ์ด ์๋ฃ๋ ์ ์ ๋ค์ ๊ธฐ๋กํ๋ Set(์งํฉ)์ด๋ค
val queue: Queue<T> = LinkedList()
val discovered = mutableSetOf<T>()
// (3) startVertex๋ถํฐ Queue์ ๋ฃ๋๋ค. ๋์์ discovered์๋ ์ถ๊ฐํ๋ค.
queue.add(startVertex)
discovered.add(startVertex)
while (queue.isNotEmpty()) {
// (4) ์ ์ ์ Queue์์ ๋นผ๋ด๊ณ , ๋ฐฉ๋ฌธํด์ ์งํํ ์ผ์ ์ํํ๋ค. ์ฌ๊ธฐ์ doSomethingFunction()์ผ๋ก ํํํ๋ค
val vertex = queue.remove()
// doSomethingFunction(vertex)
println("Visit complete: $vertex")
// (5) (4)์์ ๋นผ๋ธ ์ ์ ์ ์ด์ ์ ์ ๋ง๋ค (6)์ ์ํ
for (neighborVertex in mapOfAdjacencyArray[vertex]!!) {
// (6) discovered ๋ชฉ๋ก์ ์๋ค๋ฉด, Queue์ ์ถ๊ฐํ๊ณ ๋์์ discovered์๋ ์ถ๊ฐํ๋ค
if (neighborVertex !in discovered) {
queue.add(neighborVertex)
discovered.add(neighborVertex)
}
}
}
}
์ง๊ธ๊น์ง ์ ์ ์ ํธ์์ Intํ์ด๋ผ๊ณ ๋ง ๋ค๋ค์ง๋ง, ์ ์ ์ ๊ตฌ๋ถํ๋ ๊ธฐ์ค์ด ๋ค๋ฅธ ๋ฐ์ดํฐํ์ผ ์๋ ์๋ค. ๊ทธ ๊ฒฝ์ฐ์ ์ฌ์ฉํ ์ ์๋๋ก ์ ๋ค๋ฆญ์ ์ด์ฉํด ๋ฆฌํฉํ ๋งํ ์ฝ๋๋ค. listOfAdjacencyArray๊ฐ mapOfAdjacencyArray๋ก ๋ฐ๋ ๊ฒ์๋ ์ฃผ๋ชฉํ์. listOfAdjacencyArray์ index๋ ๋ฐ๋์ Int์ฌ์ผ ํ๋ค๋ ์ ์ฝ ์กฐ๊ฑด์ด ์๊ธฐ์ ์ด index์ ์ญํ ์, mapOfAdjacencyArray์ key๊ฐ ์ํํ๊ฒ ๋ง๋ค์๋ค.
#3-3 doSomethingFunction() ์์น ๋ณ๊ฒฝ
import java.util.*
fun main() {
// (1) mapOfAdjacencyArray[n]์ด ๊ฐ์ง๋ ์๋ฏธ๋ฅผ ์์์ผ ํ๋ค (์ค๋ช
์ฐธ์กฐ)
val mapOfAdjacencyArray = HashMap<String, Array<String>>()
mapOfAdjacencyArray["๊ฐ์์ง"] = arrayOf("๊ณ ์์ด", "์ฌ์ด")
mapOfAdjacencyArray["๊ณ ์์ด"] = arrayOf("๊ฐ์์ง", "์ฝ๋ฟ์", "ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด")
mapOfAdjacencyArray["์ฌ์ด"] = arrayOf("๊ฐ์์ง", "ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด")
mapOfAdjacencyArray["์ฝ๋ฟ์"] = arrayOf("๊ณ ์์ด")
mapOfAdjacencyArray["ํฐ๋จธ๋ฆฌ์ค๋ชฉ๋์ด"] = arrayOf("๊ณ ์์ด", "์ฌ์ด")
bfs(mapOfAdjacencyArray, "๊ฐ์์ง") // "๊ฐ์์ง" ์ ์ (vertex)์์ ํ์ ์์
}
fun <T> bfs(mapOfAdjacencyArray: Map<T, Array<T>>, startVertex: T) {
// (2) Queue๋ก ํ์ ์์๋ฅผ ๊ฒฐ์ ํ๋ค. visited๋ Queue์ ์ด๋ฏธ ์๊ฑฐ๋, ๋ฐฉ๋ฌธ์ด ์๋ฃ๋ ์ ์ ๋ค์ ๊ธฐ๋กํ๋ Set(์งํฉ)์ด๋ค
val queue: Queue<T> = LinkedList()
val visited = mutableSetOf<T>()
// (3) startVertex๋ถํฐ Queue์ ๋ฃ๋๋ค. visited์๋ ์ถ๊ฐํจ๊ณผ ๋์์ ๋ฐฉ๋ฌธํด์ ์งํํ ์ผ์ ์ํํ๋ค. ์ฌ๊ธฐ์ doSomethingFunction()์ผ๋ก ํํํ๋ค
queue.add(startVertex)
visited.add(startVertex)
// doSomethingFunction(startVertex)
println("Visit complete: $startVertex")
while (queue.isNotEmpty()) {
// (4) ์ ์ ์ Queue์์ ์ ๊ฑฐํ๋ค
val vertex = queue.remove()
// (5) (4)์์ ๋นผ๋ธ ์ ์ ์ ์ด์ ์ ์ ๋ง๋ค (6)์ ์ํ
for (neighborVertex in mapOfAdjacencyArray[vertex]!!) {
// (6) visited ๋ชฉ๋ก์ ์๋ค๋ฉด, Queue์ ๋ฃ๊ณ visited์๋ ์ถ๊ฐํจ๊ณผ ๋์์ ๋ฐฉ๋ฌธํด์ ์งํํ ์ผ์ ์ํํ๋ค. ์ฌ๊ธฐ์ doSomethingFunction()์ผ๋ก ํํํ๋ค
if (neighborVertex !in visited) {
queue.add(neighborVertex)
visited.add(neighborVertex)
// doSomethingFunction(neighborVertex)
println("Visit complete: $neighborVertex")
}
}
}
}
Queue์์ ๋นผ๋ผ ๋๊ฐ ์๋๋ผ, ๋ฑ๋กํ ๋ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ ๊ฒ์ผ๋ก ์ทจ๊ธํ๋ฉด doSomethingFunction()์ ์์ ๊ฐ์ ์ฝ๋๋ก ๋ณ๊ฒฝํ ์๋ ์๋ค. ์ด ๊ฒฝ์ฐ (๋ ธ๋๋ฅผ ๋ฐ๊ฒฌ) == (๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ)์ด๋ฏ๋ก, Set์ ์ด๋ฆ๋ #3-1์์ ์ฌ์ฉํ ์ด๋ฆ์ธ discovered๊ฐ ์๋ visited๋ก ๋ณ๊ฒฝํ๋ค.
#4 ์์ฝ
๋๋น ์ฐ์ ํ์์ ์ธ์ ๋ฐฐ์ด์ ์์๋ค์ Queue์ ๋ฃ๋๋ค.
'๊นจ์ ๊ฐ๋ ๐ > ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ (Greedy Algorithm) (0) | 2024.10.30 |
---|---|
๊ทธ๋ํ - ๊น์ด ์ฐ์ ํ์ (DFS, Depth-First Search) (0) | 2024.09.23 |
๊ทธ๋ํ - ๊ทธ๋ํ์ ์ข ๋ฅ์ ํํ (0) | 2024.01.09 |
๋์ ํ๋ก๊ทธ๋๋ฐ (Dynamic Programming), ์ํฅ์(Bottom-up) ๋ฐ ํํฅ์(Top-down) ์ ๊ทผ (0) | 2024.01.04 |
์ ๋ ฌ - ํต ์ ๋ ฌ (Quick Sort) (0) | 2023.12.01 |