源代碼存放在git,其中還有其他算法實現:https://github.com/zhangpei
git地址bisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
https://github.com/zhangpeibisha/dataStructure.git
dijkstra算法簡單思想:
1.使用兩個集合,一個存已經遍歷了的節點,一個存還未遍歷的節點。集合格式{U(10)}代表起點到U節點距離爲10
2.基於廣度遍歷
3.求解兩步走:
第一步,找到還未訪問節點,且其中最短路徑的節點,並將這個最短路徑存入已經遍歷的節點。
第二部,通過找到的最短路徑節點,去修正其他爲訪問節點到起點的最短路徑。
上代碼:
city類:
import java.util.ArrayList;
import java.util.List;
/**
* Create by [email protected] on 2018/4/22.
*/
public class City {
// 城市名字
private String cityName;
// 與該城市鄰接的城市
private List<Distance> distance;
public City() {
init();
}
/**
* 初始化這個對象,因爲當前城市到當前城市的距離默認爲0
*/
public void init() {
distance = new ArrayList<>();
distance.add(new Distance(this, this, 0.0));
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public List<Distance> getDistance() {
return distance;
}
public void setDistance(List<Distance> distance) {
this.distance = distance;
}
public City addDistance(City toCity) {
this.distance.add(new Distance(this, toCity));
return this;
}
public City addDistance(City toCity, double distance) {
this.distance.add(new Distance(this, toCity, distance));
return this;
}
}
Distance類:
/**
* Create by [email protected] on 2018/4/22.
*
* 此爲原始路徑距離
*/
public class Distance {
// 起點城市
private City fromCity;
// 目的城市
private City toCity;
// 兩個城市之間的距離 爲空則爲無窮大
private double distance = Integer.MAX_VALUE-1;
public Distance(City fromCity, City toCity) {
this.fromCity = fromCity;
this.toCity = toCity;
}
public Distance(City fromCity, City toCity, double distance) {
this.fromCity = fromCity;
this.toCity = toCity;
this.distance = distance;
}
public City getFromCity() {
return fromCity;
}
public void setFromCity(City fromCity) {
this.fromCity = fromCity;
}
public City getToCity() {
return toCity;
}
public void setToCity(City toCity) {
this.toCity = toCity;
}
public Double getDistance() {
return distance;
}
public void setDistance(Double distance) {
this.distance = distance;
}
}
ShortPath類:
/**
* Create by [email protected] on 2018/4/22.
*
* 城市與城市之間的最短路徑
*/
public class ShortPath {
// 出發城市
private City fromCity;
// 目的城市
private City toCity;
// 途徑地
private Queue<City> ways;
// 兩個城市之間的需要走的距離
private Double distance;
public ShortPath(City fromCity, City toCity) {
this.fromCity = fromCity;
this.toCity = toCity;
}
public City getFromCity() {
return fromCity;
}
public void setFromCity(City fromCity) {
this.fromCity = fromCity;
}
public City getToCity() {
return toCity;
}
public void setToCity(City toCity) {
this.toCity = toCity;
}
public Queue<City> getWays() {
return ways;
}
public void setWays(Queue<City> ways) {
this.ways = ways;
}
public Double getDistance() {
return distance;
}
public void setDistance(Double distance) {
this.distance = distance;
}
}
Dijkstra類:
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* Create by [email protected] on 2018/4/22.
* <p>
* 具體算法
*/
public class CityDijKstra {
// 起點城市
private final City startCity;
private final City endCity;
// 使用鄰接矩陣表示地圖
private List<City> map;
// 求出來的最短路徑結果保存,若爲空則沒有路徑可達
private ShortPath shortPath;
public CityDijKstra(City startCity, City endCity, List<City> map) {
this.startCity = startCity;
this.endCity = endCity;
this.map = map;
init();
}
private void dijkstra(int citySize, int startIndex, int endIndex) {
// 保存起點城市到其他城市的最短長度
double[] shortPath = new double[citySize];
// 標記城市是否被求的最短路徑
boolean[] marked = new boolean[citySize];
// 保存最短路徑訪問
Queue<City>[] paths = new LinkedList[citySize];
// 起點和其他點的距離
List<Distance> startDistance = map.get(startIndex).getDistance();
//初始化paths
for (int i = 0; i < citySize; i++) {
Queue<City> queue = new LinkedList<>();
queue.offer(startCity);
queue.offer(map.get(i));
paths[i] = queue;
}
// 自己訪問自己距離爲0 且不必在求最短路徑,因此標記爲true
shortPath[startIndex] = 0;
marked[startIndex] = true;
for (int i = 1; i < citySize; i++) {
/**
* 此部分計算起點到其他爲標記點中最短路徑的那個點
*/
// 記錄頂點能到達點的最短距離的下標
int k = -1;
// 距離爲Integer.MAX_VALUE表示不可達
double mind = Integer.MAX_VALUE;
for (int j = 0; j < citySize; j++) {
double dis = startDistance.get(j).getDistance();
if (!marked[j] && dis < mind) {
mind = dis;
k = j;
}
}
shortPath[k] = mind;
marked[k] = true;
/**
* 此部分根據k點修正起點到其他所有節點的前驅節點及距離
*/
for (int j = 0; j < citySize; j++) {
//起點到k點的最短距離 + k點到j點的最短距離
double dis = startDistance.get(k).getDistance() +
map.get(k).getDistance().get(j).getDistance();
// 判斷j點是否被標記,若沒有被標記,且dis小於直達距離,則修正最短距離
if (!marked[j] && dis < startDistance.get(j).getDistance()) {
map.get(startIndex)
.getDistance()
.get(j).setDistance(dis);
Queue<City> queue = new LinkedList<>();
for (City city : paths[k]) {
queue.offer(city);
}
queue.offer(map.get(j));
paths[j] = queue;
}
}
}
display(shortPath, paths);
this.shortPath.setDistance(shortPath[endIndex]);
this.shortPath.setWays(paths[endIndex]);
}
private void init() {
// 初始化最短路徑結果中的起始城市和目的城市
shortPath = new ShortPath(startCity, endCity);
int citySize = map.size();
int startIndex = map.indexOf(startCity);
int endIndex = map.indexOf(endCity);
dijkstra(citySize, startIndex, endIndex);
display(map);
}
private void display(double[] dis, Queue<City>[] paths) {
for (int i = 0; i < dis.length; i++) {
System.out.print(startCity.getCityName() + "到" + map.get(i).getCityName());
System.out.print("的距離爲:" + dis[i]);
System.out.println();
System.out.print(startCity.getCityName() + "到" + map.get(i).getCityName());
System.out.print("的路徑爲:");
for (City city : paths[i]) {
System.out.print(city.getCityName() + " ");
}
System.out.println();
}
}
private void display(List<City> cities){
System.out.println("==========================");
for (City city : cities) {
for (int i = 0; i <city.getDistance().size() ; i++) {
System.out.print(city.getCityName() + "到");
if (city.getDistance().get(i).getDistance() < Integer.MAX_VALUE/2)
System.out.print(city.getDistance().get(i).getToCity().getCityName() +
"距離爲" +
city.getDistance().get(i).getDistance());
else
System.out.print(city.getDistance().get(i).getToCity().getCityName() +
"距離爲不可達");
System.out.println();
}
}
}
}
測試類:ShortPahtTest:
import java.util.ArrayList;
import java.util.List;
/**
* Create by [email protected] on 2018/4/22.
* <p>
* 最短路徑算法測試
*/
public class ShortPathTest {
public static void main(String[] args) {
double MAX = Integer.MAX_VALUE;
City chongqing = new City();
chongqing.setCityName("重慶0");
City guangzhou = new City();
guangzhou.setCityName("廣州1");
City shenzheng = new City();
shenzheng.setCityName("深圳2");
City huizhou = new City();
huizhou.setCityName("惠州3");
City shanghai = new City();
shanghai.setCityName("上海4");
chongqing.addDistance(guangzhou,10.0)
.addDistance(shenzheng)
.addDistance(huizhou,30.0)
.addDistance(shanghai,100.0);
guangzhou.addDistance(chongqing)
.addDistance(shenzheng,50.0)
.addDistance(huizhou)
.addDistance(shanghai);
shenzheng.addDistance(guangzhou)
.addDistance(chongqing)
.addDistance(huizhou)
.addDistance(shanghai,10.0);
huizhou.addDistance(guangzhou)
.addDistance(shenzheng,20.0)
.addDistance(chongqing)
.addDistance(shanghai,60.0);
shanghai.addDistance(guangzhou)
.addDistance(shenzheng)
.addDistance(huizhou)
.addDistance(chongqing);
List<City> cities = new ArrayList<City>();
cities.add(chongqing);
cities.add(guangzhou);
cities.add(shenzheng);
cities.add(huizhou);
cities.add(shanghai);
CityDijKstra cityDijKstra = new CityDijKstra(chongqing,shenzheng,cities);
}
}