package MapAlgorithms;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
* @author MohnSnow
* @time 2015年6月18日 下午3:52:18
*
*/
public class Graph {
public static class City
{
String name;
int id;
static int idCounter = 0;
public City(String name)
{
this.name = name;
id = idCounter++;
}
}
public static class Map
{
double[][] A;
public Map(int n)
{
A = new double[n][n];
for (int i = 0; i < A.length; i++)
{
for (int j = 0; j < A.length; j++)
{
if (i == j)
A[i][j] = 0;
else
A[i][j] = -1;
}
}
}
ArrayList<City> cities = new ArrayList<City>();
private double[] D;
private void relax(int u, int v)
{
if (D[v] > D[u] + A[v][u])
D[v] = D[u] + A[v][u];
}
private double[][] DD = null;
public void floydWarshall()
{
DD = new double[A.length][A.length];
int i, j, k;
for (i = 0; i < A.length; i++)
{
for (j = 0; j < A.length; j++)
{
if (A[i][j] > 0)
DD[i][j] = A[i][j];
else if (i == j)
DD[i][j] = 0;
else
DD[i][j] = 99999999;
}
}
for (k = 0; k < A.length; k++)
for (i = 0; i < A.length; i++)
for (j = 0; j < A.length; j++)
{
if (DD[i][j] > DD[i][k] + DD[k][j])
{
DD[i][j] = DD[i][k] + DD[k][j];
}
}
}
public void printFloydWarshallForOneCity(City city)
{
System.out.println("floydWarshall:");
if (DD == null)
{
floydWarshall();
}
for (int i = 0; i < A.length; i++)
{
System.out.printf("from %s to %s shortest path is:%f\n", city.name, cities.get(i).name, DD[city.id][i]);
}
}
public void dijkstra(City city)
{
dijkstra(city.id);
System.out.println("dijkstra:");
for (int i = 0; i < A.length; i++)
{
System.out.printf("from %s to %s shortest path is:%f\n", city.name, cities.get(i).name, D[i]);
}
}
public void dijkstra(int srcId)
{
D = new double[A.length];
for (int i = 0; i < A.length; i++)
{
D[i] = 999999999;
}
D[srcId] = 0;
int[] q = new int[A.length];
int ql = 0, qf = 0; //队列
for (int i = 0; i < A.length; i++)
q[ql++] = i;
while (qf != ql)
{
int min = qf;
for (int i = qf; i < ql; i++)
{
if (D[q[i]] < D[q[min]])
{
min = i;
}
}
int id = q[qf];
q[qf] = q[min];
q[min] = id; //q[qf] is the min
int u = q[qf++];
for (int i = 0; i < A.length; i++)
{
if (A[u][i] > 0)
{
relax(u, i);
}
}
}
}
public void bellmanFord(City city)
{
bellmanFord(city.id);
System.out.println("bellmanFord:");
for (int i = 0; i < A.length; i++)
{
System.out.printf("from %s to %s shortest path is:%f\n", city.name, cities.get(i).name, D[i]);
}
}
public void bellmanFord(int srcId)
{
D = new double[A.length];
for (int i = 0; i < A.length; i++)
{
D[i] = 99999999;//无穷大
}
D[srcId] = 0;
for (int i = 0; i < A.length; i++)//外层循环次数
{
for (int j = 0; j < A.length; j++)
{
for (int k = 0; k < A.length; k++)
{
if (A[j][k] > 0)
{
relax(j, k);
}
}
}
}
}
Queue<Integer> bfsQueue = new LinkedList<Integer>();
boolean[] bfsFlag;
int bsfPre[];
public void findPathByBFS(City src, City dst)
{
System.out.printf("bfs find path between '%s' and '%s'!\n", src.name, dst.name);
findPathByBFS(src.id, dst.id);
printBFS(dst.id);
}
public void findPathByBFS(int srcId, int dstId)
{
bsfPre = new int[A.length];
bfsQueue.clear();
bfsFlag = new boolean[A.length];
for (int i = 0; i < A.length; i++)
{
bfsFlag[i] = false;
bsfPre[i] = -1;
}
bfsQueue.offer(srcId);
bfsFlag[srcId] = true;
while (!bfsQueue.isEmpty())
{
int current = bfsQueue.poll();
for (int index = 0; index < A.length; index++)
{
if (current == index)
continue;
if (A[current][index] > 0) //两者相连
{
if (index == dstId)//找到目标了
{
bfsFlag[index] = true;
bsfPre[index] = current;
return;//直接返回
}
if (bfsFlag[index] == false)//如果未访问过
{
bfsFlag[index] = true;
bsfPre[index] = current;
bfsQueue.offer(index);
}
}
}
}
}
private void printBFS(int dstId)
{
int index = dstId;
do
{
System.out.printf("<-%s", cities.get(index).name);
index = bsfPre[index];
} while (index != -1);
System.out.println();
}
ArrayList<Integer> dfsPath = new ArrayList<Integer>();
boolean[] dfsFlag;
private void printDFS()
{
for (Integer node : dfsPath)
{
System.out.printf("->%s", cities.get(node).name);
}
System.out.println();
}
public void findPathByDFS(City src, City dst)
{
System.out.printf("dfs find path between '%s' and '%s'!\n", src.name, dst.name);
findPathByDFS(src.id, dst.id);
}
public void findPathByDFS(int srcId, int dstId)
{
dfsPath.clear();
dfsFlag = new boolean[A.length];
for (int i = 0; i < A.length; i++)
{
dfsFlag[i] = false;
}
dfsPath.add(srcId);
dfsFlag[srcId] = true;
dfs(srcId, dstId);
printDFS();
}
private void dfs(int srcId, int dstId)
{
for (int index = 0; index < A[srcId].length; index++)
{
if (srcId == index)
continue;
if (A[srcId][index] > 0)//两者连接
{
if (index == dstId)//找到目标了
{
dfsFlag[index] = true;
dfsPath.add(index);
return;
}
if (dfsFlag[index] == false)//如果该节点未访问过
{
dfsFlag[index] = true;
dfsPath.add(index);
dfs(index, dstId);
if (dfsFlag[dstId] == false)//目标没找到
dfsPath.remove(index);
else
return;
}
}
}
}
public void createEdge(City a, City b, double w)
{
A[a.id][b.id] = w;
A[b.id][a.id] = w;//added by me!
cities.add(a.id, a);
cities.add(b.id, b);
}
public String toString()
{
String r = "I am a map of " + A.length + " cities.";
r += " My connections are:\n";
for (int i = 0; i < A.length; i++)
{
for (int j = 0; j < A[0].length; j++)
r += A[i][j] + "\t";
r += "\n";
}
return r;
}
}
public static void main(String[] args)
{
Map M = new Map(12);
City a = new City("a");
City b = new City("b");
City c = new City("c");
City d = new City("d");
City e = new City("e");
City f = new City("f");
City g = new City("g");
City h = new City("h");
City i = new City("i");
City j = new City("j");
City k = new City("k");
City l = new City("l");
M.createEdge(a, b, 3);
M.createEdge(a, c, 5);
M.createEdge(a, d, 4);
M.createEdge(b, f, 6);
M.createEdge(c, d, 2);
M.createEdge(c, g, 4);
M.createEdge(d, e, 1);
M.createEdge(d, h, 5);
M.createEdge(e, f, 2);
M.createEdge(e, i, 4);
M.createEdge(f, j, 5);
M.createEdge(g, h, 3);
M.createEdge(g, k, 6);
M.createEdge(h, i, 6);
M.createEdge(h, k, 7);
M.createEdge(i, j, 3);
M.createEdge(i, l, 5);
M.createEdge(j, l, 9);
M.createEdge(k, l, 8);
System.out.println("the graph is:\n");
System.out.println(M);
System.out.println();
System.out.println("findPathByDFS:a to k");
M.findPathByDFS(a, k);
System.out.println();
System.out.println("findPathByBFS:a to k");
M.findPathByBFS(a, k);
System.out.println();
System.out.println("bellmanFord from a:");
M.bellmanFord(a);
System.out.println();
System.out.println("dijkstra from a:");
M.dijkstra(a);
System.out.println();
System.out.println("bellmanFord,print example from a:");
M.floydWarshall();
M.printFloydWarshallForOneCity(a);
}
}