Algorithm/μΈν”„λŸ°(inflearn)

[ μžλ°”μŠ€ν¬λ¦½νŠΈ(JavaScript) ] section09 - 1 - κ·Έλž˜ν”„μ™€ 인접행렬

YWTechIT 2021. 10. 6. 12:14
728x90

πŸ“ section09 - 1 - κ·Έλž˜ν”„μ™€ 인접행렬

이번 μ„Ήμ…˜μ€ κ·Έλž˜ν”„μ™€ 탐색(DFS, BFS)에 λŒ€ν•΄μ„œ λ°°μš΄λ‹€. μ§€κΈˆμ€ 문제λ₯Ό 풀지 μ•Šκ³  κ·Έλž˜ν”„μ— λŒ€ν•΄ κ°„λ‹¨ν•˜κ²Œ μ•Œμ•„λ³΄λŠ” μ‹œκ°„μ„ κ°€μ Έλ³΄μž. κ·Έλž˜ν”„λŠ” λ‹€μŒκ³Ό 같이 이루어진닀.

 

  1. Vertex: 정점, λ…Έλ“œ
  2. Edge: λ…Έλ“œμ™€ λ…Έλ“œλ₯Ό μ—°κ²°ν•˜λŠ” κ°„μ„ 
  3. graph: 2차원 λ°°μ—΄μ—μ„œλŠ” indexκ°€ 정점(vertex) λ²ˆν˜Έλ‹€.

 

κ·Έλž˜ν”„μ˜ μ’…λ₯˜λŠ” 3가지가 μžˆλ‹€. μž…λ ₯이 μ£Όμ–΄μ§ˆ λ•Œ graphλ³„λ‘œ μ–΄λ–»κ²Œ μž…λ ₯ν•˜λŠ”μ§€ μ½”λ“œλ‘œ λ‚˜νƒ€λƒˆλ‹€. (μ—¬κΈ°μ„œλŠ” 인접 ν–‰λ ¬λ‘œ ν‘œν˜„ν•¨)

 

1. 무방ν–₯ κ·Έλž˜ν”„(unDirected Graph): λ°©ν–₯이 μ—†λŠ” κ·Έλž˜ν”„ 즉, μ–‘λ°©ν–₯인 κ·Έλž˜ν”„λ‹€. μž…λ ₯은 보톡 [a, b] ν˜•νƒœλ‘œ μ£Όμ–΄μ§€λŠ”λ° μ—¬κΈ°μ„œ graph[a][b]=1, graph[b][a]=1을 λͺ¨λ‘ μˆ˜ν–‰ν•œλ‹€.

 

 

// 인접행렬
let node = 5;
let edge = 5;

console.log(unDirectedGraph(node, edge));

function unDirectedGraph(node, edge){
  let graph = Array.from(Array(node+1), () => Array(edge+1).fill(0));
  let input = [[1, 2], [1, 3], [2, 4], [3, 4], [2, 5]];

  for (let [a, b] of input){
    graph[a][b] = 1;
    graph[b][a] = 1;
  }

  return graph;
}

πŸ‘‰πŸ½ [
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 1, 1, 0, 0 ],
  [ 0, 1, 0, 0, 1, 1 ],
  [ 0, 1, 0, 0, 1, 0 ],
  [ 0, 0, 1, 1, 0, 0 ],
  [ 0, 0, 1, 0, 0, 0 ]
]

 

2. λ°©ν–₯ κ·Έλž˜ν”„(directed Graph): λ°©ν–₯이 μ •ν•΄μ Έ μžˆλŠ” κ·Έλž˜ν”„λ‹€. 무방ν–₯ κ·Έλž˜ν”„μ™€λŠ” 달리 정점이 κ°€λ¦¬ν‚€λŠ” λ°©ν–₯만 graph에 μž…λ ₯ν•œλ‹€.

 

 

// 인접행렬
console.log(directedGraph(node, edge));

function directedGraph(node, edge){
  let graph = Array.from(Array(node+1), () => Array(edge+1).fill(0));
  let input = [[1, 2], [1, 3], [2, 4], [3, 4], [2, 5]];

  for (let [a, b] of input){
    graph[a][b] = 1;
  }

  return graph;
}

πŸ‘‰πŸ½ [
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 1, 1, 0, 0 ],
  [ 0, 0, 0, 0, 1, 1 ],
  [ 0, 0, 0, 0, 1, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ]
]

 

3. κ°€μ€‘μΉ˜ λ°©ν–₯ κ·Έλž˜ν”„(weighted directed Graph): λ°©ν–₯ κ·Έλž˜ν”„μ΄λ©΄μ„œ κ°€μ€‘μΉ˜λ„ 같이 λ‚˜νƒ€λ‚Έ κ·Έλž˜ν”„μ΄λ‹€. ν•œ λ„μ‹œμ—μ„œ λ‹€λ₯Έ λ„μ‹œλ‘œ 이동할 λ•Œ λ“œλŠ” λΉ„μš©κ³Ό 같은 λ¬Έμ œμ—μ„œ λ“±μž₯ν•œλ‹€. μž…λ ₯을 a, b, c둜 λ°›μ•„ graph[a][b]=c 처럼 λΉ„μš©κΉŒμ§€ 같이 graph에 μž…λ ₯ν•΄μ•Όν•œλ‹€.

 

 

// 인접행렬
console.log(weightedDirectedGraph(node, edge));

function weightedDirectedGraph(node, edge){
  let graph = Array.from(Array(node+1), () => Array(edge+1).fill(0));
  let input = [[1, 2, 2], [2, 5, 5], [3, 4, 5], [1, 3, 4], [4, 2, 2]];

  for (let [a, b, c] of input){
    graph[a][b] = c;
  }

  return graph;
}

πŸ‘‰πŸ½ [
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 2, 4, 0, 0 ],
  [ 0, 0, 0, 0, 0, 5 ],
  [ 0, 0, 0, 0, 5, 0 ],
  [ 0, 0, 2, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ]
]

 

728x90

 

μœ„μ—μ„œλŠ” 인접 ν–‰λ ¬λ‘œ λ‚˜νƒ€λƒˆλŠ”λ°, κ·Έλž˜ν”„μ˜ 값을 λ‚˜νƒ€λ‚Ό λ•ŒλŠ” 인접 ν–‰λ ¬κ³Ό 인접 리슀트의 방식이 μžˆλ‹€. 각각의 νŠΉμ§•μ€ λ‹€μŒκ³Ό κ°™λ‹€.

 

 

1. 인접행렬(adjacency-matrix): λ…Έλ“œμ™€ κ°„μ„ μ˜ 정보λ₯Ό ν–‰λ ¬λ‘œ ν‘œν˜„ν•˜λŠ” 방법, κ°„μ„ μ˜ κ°œμˆ˜μ™€ 상관없이 λͺ¨λ“  정점을 ν‘œν˜„ν•΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— μ •μ μ˜ κ°œμˆ˜κ°€ λ§Žμ„μˆ˜λ‘ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ λŠ˜μ–΄λ‚œλ‹€. κ°€μ€‘μΉ˜λ₯Ό λ°©ν–₯κ·Έλž˜ν”„λŠ” 인접 ν–‰λ ¬λ‘œ λ‚˜νƒ€λ‚Έλ‹€. 무방ν–₯, λ°©ν–₯μ„±κ·Έλž˜ν”„ 문제λ₯Ό ν’€ λ•Œ μ •μ μ˜ κ°―μˆ˜κ°€ 10,000 μ΄ν•˜λΌλ©΄ μΈμ ‘ν–‰λ ¬λ‘œ ν’€μž.

 

// graph에 값을 μž…λ ₯ν•˜λŠ” 방법
let n = 5;
let m = 9;
let arr = [[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 5], [3, 4], [4, 2], [4, 5]];
let graph = Array.from(Array(n+1), () => Array(n+1).fill(0));

// 무방ν–₯ κ·Έλž˜ν”„
for (let [a, b] of arr){
    graph[a][b]=1;
    graph[b][a]=1;
}

// λ°©ν–₯ κ·Έλž˜ν”„
for (let [a, b] of arr){
    graph[a][b]=1;
}

// κ°€μ€‘μΉ˜ λ°©ν–₯ κ·Έλž˜ν”„
let graph = [[1, 2, 2], [2, 5, 5], [3, 4, 5], [1, 3, 4], [4, 2, 2]];

for (let [a, b, c] of arr){
    graph[a][b]=c;
}

 

2. μΈμ ‘λ¦¬μŠ€νŠΈ(adjacency-list): λ…Έλ“œμ™€ κ°„μ„ μ˜ 정보λ₯Ό 리슀트 ν˜•νƒœλ‘œ ν‘œν˜„ν•˜λŠ” 방법, μ—°κ²°λœ κ°„μ„ λ§Œ ν‘œμ‹œν•˜κΈ° λ•Œλ¬Έμ— 인접 행렬보닀 비ꡐ적 κ°„λ‹¨ν•˜λ‹€. μ •μ μ˜ μˆœμ„œλŠ” κΌ­ μ˜€λ¦„μ°¨μˆœμ΄ μ•„λ‹ˆμ–΄λ„ 상관없닀. 인접 리슀트둜 문제λ₯Ό ν’€ λ•ŒλŠ” μ •μ μ˜ 개수만큼 λ°˜λ³΅λ¬Έμ„ λŒλ¦¬λŠ”κ²ƒμ΄ μ•„λ‹ˆλΌ κ°„μ„ μ˜ 갯수 graph[v].length 만큼 λ°˜λ³΅λ¬Έμ„ λŒλ €μ•Ό μ‹€ν–‰ 속도λ₯Ό 높일 수 μžˆλ‹€. 인접 λ¦¬μŠ€νŠΈμ— μžˆλŠ” 정점은 ν•„μˆ˜λ‘œ ν•œ λ²ˆμ”© λ“€λ €μ•Ό ν•˜λŠ” μ •μ μ΄λ―€λ‘œ (μ™œλƒν•˜λ©΄ 이미 μ—°κ²°λ˜μ–΄μžˆλŠ” μ •μ λ§Œ ν‘œμ‹œν•˜κΈ° λ•Œλ¬Έ) 쑰건문에 graph[v][i]둜 값을 ν™•μΈν•˜λŠ” λŒ€μ‹  visited μ—¬λΆ€λ§Œ 확인해주면 λœλ‹€. μ •μ μ˜ κ°œμˆ˜κ°€ 10,000 이상일 λ•ŒλŠ” 인접 리슀트λ₯Ό μ‚¬μš©ν•˜μž.

 

// graph에 값을 μž…λ ₯ν•˜λŠ” 방법
let n = 5;
let m = 9;
let arr = [[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 5], [3, 4], [4, 2], [4, 5]];
let graph = Array.from(Array(n+1), () => Array());

// λ°©ν–₯ κ·Έλž˜ν”„
for (let [a, b] of arr){
    graph[a].push(b);
}

console.log(graph)
πŸ‘‰πŸ½ [ [], [ 2, 3, 4 ], [ 1, 3, 5 ], [ 4 ], [ 2, 5 ], [] ]
λ°˜μ‘ν˜•