(Java資料結構和演算法)最短路徑---Dijkstra+Floyd
阿新 • • 發佈:2018-11-25
Floyd演算法和Dijkstra演算法都不能針對帶有負權邊的圖,否則一直走負權邊,沒有最小,只有更小!!
Floyd演算法
import java.util.Scanner;
//Floyd演算法
class Graph{
public int[][] adjacencyMatrix;
public int vertexNumber;
public int arcNumber;
public static final int INF = 1000000;//這個值要設定的剛剛好,後面存在加運算,以防溢位
public void createGraph(){
Scanner scan = new Scanner(System.in);
System.out.print("請輸入圖的頂點數:");
vertexNumber = scan.nextInt();
System.out.print("請輸入圖的邊數:");
arcNumber = scan.nextInt();
adjacencyMatrix = new int[vertexNumber][vertexNumber];
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++ ){
adjacencyMatrix[i][j] = Graph.INF;
}
}
for(int i = 0; i < vertexNumber; i++){
adjacencyMatrix[i][i] = 0;
}
System.out.println("請輸入各條邊(頂點+空格+頂點+邊權):");
for(int i = 0; i < arcNumber; i++){
int x = scan.nextInt();
int y = scan.nextInt();
int w = scan.nextInt();
adjacencyMatrix[ x-1][y-1] = adjacencyMatrix[y-1][x-1] = w;
}
}
public void floyd(){
for(int k = 0; k < vertexNumber; k++){
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++){
if(adjacencyMatrix[i][k] + adjacencyMatrix[k][j] < adjacencyMatrix[i][j]){
adjacencyMatrix[i][j] = adjacencyMatrix[i][k] + adjacencyMatrix[k][j];
}
}
}
}
}
}
public class Main {
public static void main(String[] args){
Graph g = new Graph();
g.createGraph();
g.floyd();
for(int i = 0; i < g.vertexNumber; i++){
System.out.print(g.adjacencyMatrix[0][i]+" ");
}
System.out.println();
}
}
Dijkstra演算法
import java.util.Scanner;
//Floyd演算法
class Graph{
public int[][] adjacencyMatrix;
public int vertexNumber;
public int arcNumber;
public boolean[] visited;
public int[] distance;
public int[] pre;//記錄路徑
public static final int INF = 1000000;//這個值要設定的剛剛好,後面存在加運算,以防溢位
public void createGraph(){
Scanner scan = new Scanner(System.in);
System.out.print("請輸入圖的頂點數:");
vertexNumber = scan.nextInt();
System.out.print("請輸入圖的邊數:");
arcNumber = scan.nextInt();
adjacencyMatrix = new int[vertexNumber][vertexNumber];
visited = new boolean[vertexNumber];
distance = new int[vertexNumber];
pre = new int[vertexNumber];
for(int i = 0; i < vertexNumber; i++){
for(int j = 0; j < vertexNumber; j++){
adjacencyMatrix[i][j] = Graph.INF;
}
}
for(int i = 0; i < vertexNumber; i++){
adjacencyMatrix[i][i] = 0;
distance[i] = Graph.INF;
visited[i] = false;
pre[i] = -1;
}
System.out.println("請輸入各條邊(頂點+空格+頂點+邊權):");
for(int i = 0; i < arcNumber; i++){
int x = scan.nextInt();
int y = scan.nextInt();
int w = scan.nextInt();
adjacencyMatrix[x-1][y-1] = adjacencyMatrix[y-1][x-1] = w;
}
}
public void dijkstra(int st){
distance[st] = 0;
for(int i = 0; i < vertexNumber; i++){
int pos = st;
int min = Graph.INF;
//找到一個向外擴充套件的頂點
for(int j = 0; j < vertexNumber; j++){
if(visited[j] == false && distance[j] < min){
pos = j;
min = distance[j];
}
}
if(min == Graph.INF){//說明後繼沒有相連頂點了
break;
}
visited[pos] = true;
for(int j = 0; j < vertexNumber; j++){
if(visited[j]==false && distance[pos] + adjacencyMatrix[pos][j] < distance[j] ){
distance[j] = distance[pos] + adjacencyMatrix[pos][j];
pre[j] = pos;
}
}
}
//列印st到各個頂點的最短路徑及距離
for(int i = 0; i < vertexNumber; i++){
print(pre[i]);
System.out.println(i+1);
System.out.println("distance: "+distance[i]);
}
}
public void print(int en){
if(en == -1){
return;
}
print(pre[en]);
System.out.print((en+1)+"->");
}
}
public class Main {
public static void main(String[] args){
Graph g = new Graph();
g.createGraph();
g.dijkstra(0);
}
}