일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Java
- jquery 필터선택자
- 자바 재귀 조합
- 서로소
- java Collections.sort()
- 자바스크립트 이벤트중지
- 순열코드
- 후위표기
- 순열 재귀
- 자바
- java lambda
- 자바스크립트 이벤트처리
- jquery dom 계층 선택자
- 재귀
- 조합 재귀
- jquery 이벤트 처리
- str to char array
- char to str
- jquery 속성선택자
- 자바 순열 코드
- Interface
- 재귀함수
- 상속
- 알고리즘
- 자바입출력
- java 내부 클래스
- 자바 조합 재귀
- inner class
- 알고리즘 그래프
- parseInt()
- Today
- Total
유블로그
[알고리즘] 최단 경로 - 다익스트라, 벨만포드, 플로이드워샬 알고리즘 본문
- 최단 경로 : 간선의 가중치가 있는 그래프에서 두 정점 사이의 경로들 중에 간선의 가중치의 합이 최소인 경로
- 하나의 시작 정점에서 끝 정점까지의 최단 경로
- 다익스트라(dijkstra) 알고리즘 : 음의 가중치 허용X, 그리디 알고리즘의 일종.
- 벨만-포드(Bellman-Ford) 알고리즘 : 음의 가중치 허용.
- 모든 정점들에 대한 최단 경로
- 플로이드-워샬(Floyd-Warshall) 알고리즘
< Dijkstra 알고리즘 >
- 시작정점에서의 거리가 최소인 정점을 선택해 나가면서 최단 경로를 구하는 방식이다.
- 탐욕 기법을 사용한 알고리즘으로 MST의 프림 알고리즘과 유사하다.
s: 시작 정점, A: 인접행렬, D: 시작정점에서 자신 정점까지의 최단 거리
V: 정점 집합, U: 선택된 정점 집합
Dijkstra(s, A, D)
U = {s};
For 모든 정점 v
D[v] ← A[s][v] // s에서 v로 가는 직접 비용
While U ≠ V
D[w]가 최소인 정점 w∈ V-U 선택
U ← U ∪ {w}
For w에 인접한 모든 미방문 정점 v
D[v] ← min(D[v], D[w] + A[w][v])
다익스트라 자바 구현 코드
: priority queue 를 사용하면 가중치 비교 시간을 줄일 수 있다.
public class DijkstraTest2_PQ {
static class Vertex implements Comparable<Vertex> {
int no, totalDistance;
public Vertex(int no, int totalDistance) {
super();
this.no = no;
this.totalDistance = totalDistance;
}
@Override
public int compareTo(Vertex o) {
return this.totalDistance - o.totalDistance;
}
}
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int V = Integer.parseInt(in.readLine());
int start = 0;
int end = V-1;
final int INFINITY = Integer.MAX_VALUE;
int[][] matrix = new int[V][V]; // 인접 행렬
int[] distance = new int[V]; // 출발지에서 자신까지 오는 최단 거리
boolean[] visited = new boolean[V]; // 처리한 장점 여부 관리
for (int i = 0; i < V; i++) {
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
for (int j = 0; j < V; j++) {
matrix[i][j] = Integer.parseInt(st.nextToken());
}
}
PriorityQueue<Vertex> pQueue = new PriorityQueue<>();
Arrays.fill(distance, INFINITY); // 처음엔 아무데도 못가게
distance[start] = 0; // 자신에서 자신으로 가는 비용은 0
pQueue.offer(new Vertex(start, distance[start]));
Vertex current = null;
while(!pQueue.isEmpty()) {
current = pQueue.poll(); // distance 최소인 vertex가 나옴
if(visited[current.no]) continue; //PQ에 남아있던 totalDistance의 최소비용보다 더 큰 상태
visited[current.no] = true;
if(current.no == end) break; // 출발지로부터 모든 노드의 최단거리 구하려면 이거 지우기
// 2단계: 선택된 current 정점을 경유지로 해서 아직 방문하지 않은 다른 정점으로의 최단경로 비용 계산하여 유리하면 update
for (int j = 0; j < V; j++) {
// 방문하지 않았고, 내 자신으로 가는 노드 아니고, distance가 경유지를 방문하여 지나가는게 더 최소이면 update
if(!visited[j] && matrix[current.no][j] != 0 && distance[j] > current.totalDistance + matrix[current.no][j]) {
distance[j] = current.totalDistance + matrix[current.no][j];
pQueue.offer(new Vertex(j, distance[j]));
}
}
}
System.out.println(distance[end]); // 도착지까지 최단 구할 때
} // end of main
}
'알고리즘' 카테고리의 다른 글
[컴퓨팅사고력] 알고리즘에 필요하거나 도움될 수 있는 것들 (0) | 2020.10.04 |
---|---|
[알고리즘] 동적계획법(Dynamic Programming) (0) | 2020.10.03 |
[알고리즘] Prim 알고리즘 (0) | 2020.08.31 |
[알고리즘] 백트래킹(Backtracking) (0) | 2020.08.27 |
[알고리즘] 리스트 (0) | 2020.08.09 |