1.dijkstra
/*
* Dijkstra最短路径。
* 即,统计图中"顶点vs"到其它各个顶点的最短路径。
*
* 参数说明:
* vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
* prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
* dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
*/
public void dijkstra(int vs, int[] prev, int[] dist) {
// flag[i]=true表示"顶点vs"到"顶点i"的最短路径已成功获取
boolean[] flag = new boolean[mVexs.length];
// 初始化
for (int i = 0; i < mVexs.length; i++) {
flag[i] = false; // 顶点i的最短路径还没获取到。
prev[i] = 0; // 顶点i的前驱顶点为0。
dist[i] = mMatrix[vs][i]; // 顶点i的最短路径为"顶点vs"到"顶点i"的权。
}
// 对"顶点vs"自身进行初始化
flag[vs] = true;
dist[vs] = 0;
// 遍历mVexs.length-1次;每次找出一个顶点的最短路径。
int k=0;
for (int i = 1; i < mVexs.length; i++) {
// 寻找当前最小的路径;
// 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
int min = INF;
for (int j = 0; j < mVexs.length; j++) {
if (flag[j]==false && dist[j]<min) {
min = dist[j];
k = j;
}
}
// 标记"顶点k"为已经获取到最短路径
flag[k] = true;
// 修正当前最短路径和前驱顶点
// 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
for (int j = 0; j < mVexs.length; j++) {
int tmp = (mMatrix[k][j]==INF ? INF : (min + mMatrix[k][j]));
if (flag[j]==false && (tmp<dist[j]) ) {
dist[j] = tmp;
prev[j] = k;
}
}
}
// 打印dijkstra最短路径的结果
System.out.printf("dijkstra(%c): \n", mVexs[vs]);
for (int i=0; i < mVexs.length; i++)
System.out.printf(" shortest(%c, %c)=%d\n", mVexs[vs], mVexs[i], dist[i]);
}
2.A*
import java.util.ArrayList;
// A*算法寻路
public class AStar2 {
public static final int[][] maps = {
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
};
public static int straight = 10;
public static int diagonal = 14;
// 开放列表
public static ArrayList<Node> openList = new ArrayList<>();
// 闭合列表
public static ArrayList<Node> colseList = new ArrayList<>();
// 方向
public static int[][] direct = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
public static void main(String[] args) {
//定点:起点终点
Node start = new Node(5, 1);
Node end = new Node(5, 4);
Node endNode = findPath(start, end);
printMap(maps, start, end);
ArrayList<Node> arrayList = endNode != null ? getPaths(endNode) : null;
printPaths(arrayList);
}
// 从起点开始,找到到终点的一条最短路径
private static Node findPath(Node start, Node end) {
start.G = 0;
openList.add(start);
while (!openList.isEmpty()) {
//从开放列表中拿到最小F节点
Node cureNode = minFINOpenList(openList);
openList.remove(cureNode);
// 将该节点加入到闭合列表中
colseList.add(cureNode);
// 当前节点的全部合法邻居
ArrayList<Node> neighbors = getNeighbor(cureNode);
for (Node nbrNode : neighbors) {
// 邻居已经在openList
if (exists(openList, nbrNode) != null)
updateG(cureNode, nbrNode);
// 邻居不在openList
else joinOpenList(cureNode, nbrNode, end);
}
if (exists(openList, end) != null)
return exists(openList, end);
}
return null;
}
private static ArrayList<Node> getPaths(Node endNode) {
ArrayList<Node> arrayList = new ArrayList<>();
Node parent = endNode;
while (parent != null) {
arrayList.add(parent);
parent = parent.parent;
}
return arrayList;
}
private static int calStep(Node node, Node cur) {
if (inLine(node, cur))
return straight;
else return diagonal;
}
private static int calH(Node endNode, Node nbrNode) {
return Math.abs(endNode.y - nbrNode.y) + Math.abs(endNode.x - nbrNode.x);
}
// 计算距离起点的距离
private static int calG(Node cureNode, Node nbrNode) {
int step = calStep(cureNode, nbrNode);
return cureNode.G + step;
}
private static boolean inLine(Node nbr, Node cur) {
if (nbr.x == cur.x || nbr.y == cur.y)
return true;
return false;
}
// 途径当前节点到达节点node的路径G会不会更短
private static void updateG(Node cureNode, Node nbrNode) {
int step = calStep(cureNode, nbrNode);
int G = calG(cureNode, nbrNode);
if (G < nbrNode.G) {
nbrNode.G = G;
nbrNode.parent = cureNode;
nbrNode.calcF();
}
}
private static void joinOpenList(Node curNode, Node nbrNode, Node endNode) {
openList.add(nbrNode);
nbrNode.parent = curNode;
nbrNode.G = calG(curNode, nbrNode);
nbrNode.H = calH(endNode, nbrNode);
nbrNode.calcF();
}
// 达到当前节点的可达,且不在closeList中的邻居节点
private static ArrayList<Node> getNeighbor(Node cureNode) {
ArrayList<Node> arrayList = new ArrayList<>();
//从当前节点想八个方向扩散
for (int i = 0; i < 8; i++) {
int newRow = cureNode.x + direct[i][0];
int newCol = cureNode.y + direct[i][1];
//当前邻居节点: 可达、不在closeList中
if (isAccesse(newRow, newCol) && !exists(colseList, newRow, newCol)) {
arrayList.add(new Node(newRow, newCol));
}
}
return arrayList;
}
private static Node exists(ArrayList<Node> colseList, Node cur) {
for (Node node : colseList) {
if (node.x == cur.x && node.y == cur.y)
return node;
}
return null;
}
private static boolean exists(ArrayList<Node> colseList, int newX, int newY) {
for (Node node : colseList) {
if (node.x == newX && node.y == newY)
return true;
}
return false;
}
// 可达性分析(非障碍物)
private static boolean isAccesse(int newX, int newY) {
if (0 <= newX && newX < maps.length && 0 <= newY && newY < maps[0].length)
return maps[newX][newY] == 0;
return false;
}
// 从开放列表中找到最小F=G+H的节点
private static Node minFINOpenList(ArrayList<Node> openList) {
Node min = openList.get(0);
for (Node node : openList) {
if (node.F < min.F)
min = node;
}
return min;
}
private static void printMap(int[][] maps, Node start, Node end) {
for (int col = 0; col < maps[0].length; col++) {
System.out.print("\t" + col + "");
}
System.out.print("\n-----------------------------------------\n");
int count = 0;
for (int row = 0; row < maps.length; row++) {
for (int col = 0; col < maps[0].length; col++) {
if (col == 0)
System.out.print(count++ + "|\t");
if (row == start.x && col == start.y || row == end.x && col == end.y)
System.out.print("X\t");
else
System.out.print(maps[row][col] + "\t");
}
System.out.println();
}
System.out.println();
}
public static void printPaths(ArrayList<Node> arrayList) {
if (arrayList == null) {
System.out.println("无路可走");
return;
}
// 地图形式
for (int col = 0; col < maps[0].length; col++) {
System.out.print("\t" + col + "");
}
System.out.print("\n-----------------------------------------\n");
int count = 0;
for (int row = 0; row < maps.length; row++) {
for (int col = 0; col < maps[0].length; col++) {
if (col == 0)
System.out.print(count++ + "|\t");
if (exists(arrayList, row, col)) {
System.out.print("X\t");
} else {
System.out.print(maps[row][col] + "\t");
}
}
System.out.println();
}
System.out.println();
// 路径形式
for (int i = arrayList.size() - 1; i >= 0; i--) {
if (i == 0)
System.out.print(arrayList.get(i));
else
System.out.print(arrayList.get(i) + "->");
}
System.out.println();
}
}
3.BFS
private static void bfs(HashMap<Character, LinkedList<Character>> graph,HashMap<Character, Integer> dist,char start)
{
Queue<Character> q=new LinkedList<>();
q.add(start);//将s作为起始顶点加入队列
dist.put(start, 0);
int i=0;
while(!q.isEmpty())
{
char top=q.poll();//取出队首元素
i++;
System.out.println("The "+i+"th element:"+top+" Distance from s is:"+dist.get(top));
int d=dist.get(top)+1;//得出其周边还未被访问的节点的距离
for (Character c : graph.get(top)) {
if(!dist.containsKey(c))//如果dist中还没有该元素说明还没有被访问
{
dist.put(c, d);
q.add(c);
}
}
}
}
4.dfs
private static void dfs(HashMap<Character , LinkedList<Character>> graph,HashMap<Character, Boolean> visited)
{
visit(graph, visited, 'u');//为了和图中的顺序一样,我认为控制了DFS先访问u节点
visit(graph,visited,'w');
}
private static void visit(HashMap<Character , LinkedList<Character>> graph,HashMap<Character, Boolean> visited,char start)
{
if(!visited.containsKey(start))
{
count++;
System.out.println("The time into element "+start+":"+count);//记录进入该节点的时间
visited.put(start, true);
for (char c : graph.get(start))
{
if(!visited.containsKey(c))
{
visit(graph,visited,c);//递归访问其邻近节点
}
}
count++;
System.out.println("The time out element "+start+":"+count);//记录离开该节点的时间
}
}