1. 程式人生 > >(Java資料結構和演算法)最短路徑---Dijkstra+Floyd

(Java資料結構和演算法)最短路徑---Dijkstra+Floyd

參考博文

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);	
	}
}

在這裡插入圖片描述