κ·Έλν(Graph) μλ£κ΅¬μ‘°μ νμ
κ·Έλν(Graph)
- λΉμ ν μλ£κ΅¬μ‘°
- μμλ€ κ°
n:m
μ κ΄κ³λ₯Ό κ°μ§λ μλ£κ΅¬μ‘° - μ¬λ¬Ό νΉμ μ¬λ, μΆμμ κ°λ λ±μ κ΄κ³μ±μ ννν μλ£κ΅¬μ‘°
- μ μ (vertex)λ€μ μ§ν©κ³Ό μ΄λ€μ μ°κ²°νλ κ°μ (Edge)λ€μ μ§ν©μΌλ‘ ꡬμ±λ μλ£κ΅¬μ‘°
- μ°¨μ(Degree) : μ μ μ μ°κ²°λ κ°μ μ μ
κ·Έλνμ μ ν
- 무ν₯ κ·Έλν(Undirected Graph) : κ°μ μ λ°©ν₯μ΄ μμ΄ μ μ κ° μ°κ²°κ΄κ³λ§ λνλΈ κ·Έλν
- μ ν₯ κ·Έλν(Directed Graph) : κ°μ μ λ°©ν₯μ΄ μμ΄ μΆλ° μ μ κ³Ό λμ°© μ μ μ λνλΈ κ·Έλν
- κ°μ€μΉ κ·Έλν(Weighted Graph) : κ°μ μ κ°μ€μΉκ° λΆμ¬λμ΄ νΉμ μ μ κ° κ±°λ¦¬, μ΄λ λΉμ©, κΈ°ν κ°μ€μΉ λ±μ κ°μ ννν κ·Έλν
- μ¬μ΄ν΄ μλ λ°©ν₯ κ·Έλν(DAG, Directed Acyclic Graph) : ν μ μ μμ λ€λ₯Έ μ μ λ€μ λμ λ€μ μμ μκ² λμμ€λ μνμ μΈ μ¬μ΄ν΄μ΄ μ‘΄μ¬νμ§ μλ, μΌλ°©ν₯μ± κ·Έλν
-
νΈλ¦¬λ κ·Έλνμ μΌμ’
- λΆλͺ¨ λ Έλμ μμ λ Έλ μ¬μ΄μλ μ μΌν κ²½λ‘κ° μ‘΄μ¬ν¨
μΈμ μ μ κ³Ό κ·Έλν κ²½λ‘
- μΈμ (Adjacency) : λ μ μ μ¬μ΄μ κ°μ μ΄ μ‘΄μ¬ν κ²½μ° λ μ μ μ μ°κ²°λμ΄ μκ³ μΈμ ν κ²μ
-
κ²½λ‘(Path) : ν μ μ μμ μμνμ¬ λ€λ₯Έ μ μ κΉμ§ λλ¬νκΈ°κΉμ§μ κ°μ μ 보
- λ¨μ κ²½λ‘ : μμ μ μ κ³Ό λ μ μ μ μ μΈνκ³ μ€λ³΅λ μ μ μ΄ μμ
- μ¬μ΄ν΄(Cyclic) : κ²½λ‘μ μμ μ μ κ³Ό λ μ μ μ΄ κ°μ
κ·Έλνμ νν
μΈμ νλ ¬(Adjacent Matrix)
- V * V ν¬κΈ°μ 2μ°¨μ λ°°μ΄μ μ΄μ©νμ¬ λ μ μ μ¬μ΄ κ°μ μ μ 무λ₯Ό μ μ₯
- νκ³Ό μ΄μ μΈλ±μ€λ λ μ μ μ ννν¨
- 무ν₯ κ·Έλνμ κ²½μ° 2μ°¨μ λ°°μ΄ μμ κΈ°μΈκΈ°κ° -1μΈ κ°μμ μ§μ μ΄ μ‘΄μ¬νλ€κ³ μκ°νκ³ μ΄ μ§μ μ κΈ°μ€μΌλ‘ μλ‘ λμΉνλ ννλ‘ κ°μ΄ λ€μ΄κ° μμ
- κ°μ€μΉκ° μλ κ·Έλνμ κ²½μ°
boolean
ν λ°°μ΄μ μμ±νμ¬, κ°μ μ΄ μ‘΄μ¬νλ©΄true
, κ°μ μ΄ μμΌλ©΄false
λ₯Ό μ μ₯ν μ μμ - κ°μ€μΉκ° μλ κ·Έλνμ κ²½μ° λ°°μ΄μ κ°μ κ°μ€μΉ κ°μ μ μ₯ν μ μμ
-
μΈμ νλ ¬μ μ΄μ©νμ¬ κ·Έλνλ₯Ό ννν κ²½μ° ν¬μ κ·Έλν(Sparse Graph) νν μ λ©λͺ¨λ¦¬ λλΉκ° λ°μν μ μμ
- ν¬μ κ·Έλνλ κ·Έλνμ μ μ μ¬μ΄ κ°μ μ΄ λΉκ΅μ μ μ κ·Έλνλ₯Ό μλ―Έ (<-> λ°μ§ κ·Έλν(Dense Graph))
- μ μ μ€μ¬ λ¬Έμ λ₯Ό ν΄κ²°ν λ μ ν©
public void adjacentMatrix() {
int[][] vertexs = {{1, 2}, {1, 4}, {3, 2}, {4, 5}, {5, 3}}; // μΈμ μ μ μ 보
int N; // μ μ μ κ°μ
boolean[][] adjMatrix = new boolean[N][N]; // κ°μ€μΉκ° μλ μΈμ νλ ¬
for (int i=0; i<vertexs.length; i++) {
int from = vertexs[i][0];
int to = vertexs[i][1];
adjMatrix[from][to] = true;
adjMatrix[to][from] = true;
}
}
μΈμ 리μ€νΈ(Adjacent List)
- νλμ μ μ μ λν μΈμ μ μ λ€μ μ°κ²° 리μ€νΈμ λ Έλ ννλ‘ μ μ₯
- 리μ€νΈμ μΈλ±μ€λ κ·Έλνμ λͺ¨λ μ μ μ ννν¨
-
무ν₯ κ·Έλνμ κ²½μ° μΈμ ν μ μ aμ bλ₯Ό ννν λ μ μ aλ₯Ό 리μ€νΈμ μΈλ±μ€μ λμΉμν€κ³ μ μ bλ λ Έλ ννλ‘ λ¦¬μ€νΈμ a μΈλ±μ€μ μ μ₯ν¨. λ°λλ‘ μ μ b μμ 리μ€νΈμ μΈλ±μ€μ λμΉμν€κ³ μ μ aλ λ Έλ ννλ‘ λ¦¬μ€νΈμ b μΈλ±μ€μ μ μ₯ν΄μΌ ν¨.
- 무ν₯ κ·Έλνμ λ
Έλ μ =
κ°μ μ μ * 2
- 무ν₯ κ·Έλνμ λ
Έλ μ =
-
μ ν₯ κ·Έλνλ μ§μΆ μ μ λ§ λ¦¬μ€νΈμ μΈλ±μ€μ λμΉμν€κ³ μ§μ μ μ λ§ λ Έλ ννλ‘ μ μ₯νλ©΄ λ¨
- μ ν₯ κ·Έλνμ λ
Έλ μ =
κ°μ μ μ
- μ ν₯ κ·Έλνμ λ
Έλ μ =
- ꡬνμ΄ μ‘°κΈ κΉλ€λ‘μ§λ§ κ°μ μ΄ λΉκ΅μ μ μ ν¬μ κ·Έλνλ₯Ό νννκΈ°μ μΈμ νλ ¬λ³΄λ€ ν¨μ¨μ μ
- μ μ μ€μ¬ λ¬Έμ λ₯Ό ν΄κ²°ν λ μ ν©
class adjacentList() {
static class Node {
int vertex; // μΈμ μ μ μΈλ±μ€
Node link; // μΈμ μ μ λ§ν¬
public Node(int vertex, Node link) {
super();
this.vertex = vertex;
this.link = link;
}
}
public void adjacentList() {
int[][] vertexs = {{1, 2}, {1, 4}, {3, 2}, {4, 5}, {5, 3}}; // μΈμ μ μ μ 보
int N; // μ μ μ κ°μ
Node[] adjList = new Node[N]; // κ°μ€μΉκ° μλ μΈμ νλ ¬
for (int i=0; i<vertexs.length; i++) {
int from = vertexs[i][0];
int to = vertexs[i][1];
adjList[from] = new Node(to, adjMatrix[from]);
adjList[to] = new Node(from, adjMatrix[to]);
}
}
}
κ°μ 리μ€νΈ(Edge List)
- λ μ μ μ λν κ°μ μ체λ₯Ό κ°μ²΄λ‘ νννμ¬ λ¦¬μ€νΈλ‘ μ μ₯
- κ°μ μ νννλ λ μ μ (μμ μ μ , λ μ μ )μ μ 보λ₯Ό νν
κ·Έλν νμ
λΉμ ν μλ£κ΅¬μ‘°μΈ κ·Έλνμ λͺ¨λ μ μ μ λΉ μ§μμ΄ νμνλ κΈ°λ²
νΈλ¦¬ μλ£κ΅¬μ‘°μ λμΌνκ² λλΉ μ°μ νμκ³Ό κΉμ΄ μ°μ νμ κΈ°λ²μ΄ μ‘΄μ¬ν¨. νΈλ¦¬μ κ²½μ° μμ λ Έλμκ² μ°κ²°λ λΆλͺ¨ λ Έλλ λ¨ νκ°λ§ μ‘΄μ¬νλ―λ‘ ν λ Έλμ λμ°©ν μ μλ μΆλ°μ μ ν΄λΉ λ Έλμ λΆλͺ¨λ Έλ νλλΏμ. νμ§λ§, κ·Έλνμ κ²½μ° ν μ μ μ μΈμ ν μ μ μ΄ μ¬λ¬κ°μΌ μ μμΌλ―λ‘ ν΄λΉ μ μ μΌλ‘ λμ°©ν μ μλ μΆλ°μ μ΄ μ¬λ¬κ°μ.
λ°λΌμ κ·Έλνμμμ νμμμλ μ μ μ λν λ°©λ¬Έ 체ν¬λ₯Ό νμμ μΌλ‘ ν΄μ£Όμ΄μΌμ§ κ°μ μ μ μ μ€λ³΅ν΄μ λ°©λ¬Ένμ§ μμ!!
λλΉ μ°μ νμ(BFS, Breadth First Search)
- νμ μμ μ μ λΆν° λͺ¨λ μΈμ ν μ μ λ€μ μ°¨λ‘λλ‘ λ°©λ¬Έν λ€, λ°©λ¬Ένλ μ μ μ μμμ μΌλ‘ νμ¬ λ€μ ν΄λΉ μ μ μ μΈμ ν μ μ λ€μ λͺ¨λ λ°©λ¬Ένλ λ°©μ
- μΈμ ν μ μ μ λν νμμ΄ λλμΌ ν΄λΉ μ μ λ€μ μΈμ ν λ Έλλ₯Ό λ°©λ¬Έν μ μμΌλ―λ‘ μ μ μ μΆ ννμ μλ£κ΅¬μ‘°μΈ ν(Queue)λ₯Ό μ¬μ©νμ¬ κ΅¬νν μ μμ
// μΈμ νλ ¬ κ·Έλν bfs
public void adjMatrixBfs() {
Queue<Integer> q = new LinkedList<>(); // μμ μ μ μ μ₯
boolean[] visited = new boolean[N]; // μ μ λ°©λ¬Έ μ¬λΆ κΈ°μ΅
q.offer(0); // μμ μ μ μ μΈλ±μ€
visited[0] = true; // μμ μ μ λ°©λ¬Έ 체ν¬
while(!q.isEmpty()) {
int current = q.poll();
System.out.println(current + " ");
for (int i=0; i<N; i++) { // κ·Έλνμ λͺ¨λ μ μ μ λν΄
if (!visited[i] && adjMatrix[current][i]) { // μμ§ λ°©λ¬Έ μνκ³ νμ¬ μ μ μ μΈμ ν μ μ μ΄λ©΄
q.offer(i); // νμμ μν΄ ν 맨 λ·λ¨μ μ½μ
νκ³
visited[i] = true; // 미리 λ°©λ¬Έ μ²λ¦¬ν¨μΌλ‘μ¨ νμ μ μ μ΄ μ€λ³΅μ μΌλ‘ μ½μ
λλ κ²μ λ§μ
}
}
}
}
// μΈμ 리μ€νΈ κ·Έλν bfs
public void adjListBfs() {
Queue<Integer> q = new LinkedList<>(); // μμ μ μ μ μ₯
boolean[] visited = new boolean[N]; // μ μ λ°©λ¬Έ μ¬λΆ κΈ°μ΅
q.offer(0); // μμ μ μ μ μΈλ±μ€
visited[0] = true; // μμ μ μ λ°©λ¬Έ 체ν¬
while(!q.isEmpty()) {
int current = q.poll();
System.out.println(current + " ");
for (Node i=adjList[current]; i!=null; i=i.link) { // νμ¬ μ μ μ μΈμ 리μ€νΈμ μ μ₯λ μΈμ ν μ μ λ€μ λν΄μλ§
if (!visited[i.vertex]) { // μμ§ λ°©λ¬Έ μνμΌλ©΄
q.offer(i.vertex); // νμμ μν΄ ν 맨 λ·λ¨μ μ½μ
νκ³
visited[i.vertex] = true; // 미리 λ°©λ¬Έ μ²λ¦¬ν¨μΌλ‘μ¨ νμ μ μ μ΄ μ€λ³΅μ μΌλ‘ μ½μ
λλ κ²μ λ§μ
}
}
}
}
κΉμ΄ μ°μ νμ(DFS, Depth First Search)
- μμ μ μ μ ν λ°©ν₯μΌλ‘ κ° μ μλ κ²½λ‘κ° μ‘΄μ¬ν λκΉμ§ κ³μν΄μ κΉκ² νμ. λ μ΄μ λ°©λ¬Έν μ μλ κ²½λ‘κ° μμΌλ©΄ λ§μ§λ§μΌλ‘ λ§λ¬λ κ°λ¦ΌκΈΈμ΄ μλ μ μ μΌλ‘ λμμ λ€λ₯Έ λ°©ν₯μ μ μ μ κ°μ λ°©μμΌλ‘ κ³μν΄μ κΉκ² νμνλ λ°©μ
- μΈμ ν μ μ μ μΈμ ν μ μ μ λ¨Όμ κΉκ² λ°©λ¬Ένλ€κ° λ°©λ¬Έν λ Έλκ° μμ κ²½μ° λμμμ λ€λ₯Έ μΈμ μ μ μΌλ‘ κΉκ² λ€μ΄κ°μΌ νλ―λ‘ μ¬κ·μ μΌλ‘ ꡬννκ±°λ, νμ μ μΆ ννμ μλ£κ΅¬μ‘°μΈ μ€ν(Stack)μ μ¬μ©νμ¬ κ΅¬νν μ μμ
// μΈμ νλ ¬ κ·Έλν bfs
public void dfs(int current, boolean[] visited) {
visited[current] = true; // νμ¬ νμ μ μ λ°©λ¬Έ μ²λ¦¬
System.out.println(current + " ");
for (int i=0; i<N; i++) { // κ·Έλνμ λͺ¨λ μ μ μ λν΄
// μμ§ λ°©λ¬Έ μνκ³ νμ¬ μ μ μ μΈμ ν μ μ μ΄λ©΄ ν΄λΉ μ μ μ λ€μ μμμ μΌλ‘ μΌμ μΈμ ν μ μ μ κΉκ² νμ
if (!visited[i] && adjMatrix[current][i]) dfs(i, visited);
}
}
// μΈμ 리μ€νΈ κ·Έλν dfs
public void dfs(int current, boolean[] visited) {
visited[current] = true; // νμ¬ νμ μ μ λ°©λ¬Έ μ²λ¦¬
System.out.println(current + " ");
for (Node i=adjList[current]; i!=null; i=i.link) { // νμ¬ μ μ μ μΈμ 리μ€νΈμ μ μ₯λ μΈμ ν μ μ λ€μ λν΄μλ§
// μμ§ λ°©λ¬Έ μνμΌλ©΄ ν΄λΉ μ μ μ λ€μ μμμ μΌλ‘ μΌμ μΈμ ν μ μ μ κΉκ² νμ
if (!visited[i.vertex]) dfs(i.vertex, visited);
}
}