首语
图的最短路径
- 从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径,解决最短路径通常有Dijkstra算法。
迪杰斯特拉算法(Dijkstra)
- 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
代码实现
private final static int MAXVEX = 9;
private final static int MAXWEIGHT = 65535;
private int[] shortTablePath = new int[MAXVEX];//记录的是v0到某顶点的最短路径和
/**
* 获取一个图的最短路径
*
* @param graph
*/
public void shorttestPathDijstra(Graph graph) {
int min;
int k = 0;//记录下标
boolean[] isgetPath = new boolean[MAXVEX];
for (int v = 0; v < graph.getVertexSize(); v++) {
shortTablePath[v] = graph.getMatrix()[0][v];//获取v0这一行的权值数组
}
shortTablePath[0] = 0;
isgetPath[0] = true;
for (int v = 1; v < graph.getVertexSize(); v++) {
min = MAXWEIGHT;
for (int w = 0; w < graph.getVertexSize(); w++) {
if (!isgetPath[w] && shortTablePath[w] < min) {
k = w;
min = shortTablePath[w];
}
}
isgetPath[k] = true;
for (int j = 0; j < graph.getVertexSize(); j++) {
if (!isgetPath[j] && (min + graph.getMatrix()[k][j] < shortTablePath[j])) {
shortTablePath[j] = min + graph.getMatrix()[k][j];
}
}
}
for (int i = 0; i < shortTablePath.length; i++) {
System.out.println("V0到V" + i + "的最短路径为:" + shortTablePath[i]+"\n");
}
}
拓扑排序
- 在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称为AOV网(Activity On Vertex Network)。
- 设G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,·········,Vn,满足若从顶点Vi到Vj有一条路径,则在顶点序列中顶点Vi必在Vj之前。则我们称这样的顶点序列为一个拓扑序列。
代码实现
public int numVertexes;
private VertexNode[] adjList;//邻接顶点的一维数组
public DnGraphToplogic(int numVertexes){
this.numVertexes=numVertexes;
}
//边表顶点
class EdgeNode{
private int adjVert;
private EdgeNode next;
private int weight;
public EdgeNode(int adjVert){
this.adjVert=adjVert;
}
}
//邻接顶点
class VertexNode{
private int in;//入度
private String data;
private EdgeNode firstEdge;
public VertexNode(int in,String data){
this.in=in;
this.data=data;
}
}
/**
* 拓扑排序
*/
private void topologicalSort() throws Exception {
Stack<Integer> stack = new Stack<>();
int count=0;
int k=0;
for (int i = 0; i < numVertexes; i++) {
if (adjList[i].in==0){
stack.push(i);
}
}
while (!stack.isEmpty()){
int pop=stack.pop();
System.out.println("顶点"+adjList[pop].data);
count++;
for(EdgeNode node=adjList[pop].firstEdge;node!=null;node=node.next){
k=node.adjVert;//下标
if (--adjList[k].in==0){
stack.push(k);//入度为0,入栈
}
}
}
if (count<numVertexes){
throw new Exception("拓扑排序失败!!!");
}
}
private void createGraph(){
VertexNode node0 = new VertexNode(0,"v0");
VertexNode node1 = new VertexNode(0,"v1");
VertexNode node2 = new VertexNode(2,"v2");
VertexNode node3 = new VertexNode(0,"v3");
VertexNode node4 = new VertexNode(2,"v4");
VertexNode node5 = new VertexNode(3,"v5");
VertexNode node6 = new VertexNode(1,"v6");
VertexNode node7 = new VertexNode(2,"v7");
VertexNode node8 = new VertexNode(2,"v8");
VertexNode node9 = new VertexNode(1,"v9");
VertexNode node10 = new VertexNode(1,"v10");
VertexNode node11 = new VertexNode(2,"v11");
VertexNode node12 = new VertexNode(1,"v12");
VertexNode node13 = new VertexNode(2,"v13");
adjList = new VertexNode[numVertexes];
adjList[0] =node0;
adjList[1] =node1;
adjList[2] =node2;
adjList[3] =node3;
adjList[4] =node4;
adjList[5] =node5;
adjList[6] =node6;
adjList[7] =node7;
adjList[8] =node8;
adjList[9] =node9;
adjList[10] =node10;
adjList[11] =node11;
adjList[12] =node12;
adjList[13] =node13;
node0.firstEdge = new EdgeNode(11);node0.firstEdge.next = new EdgeNode(5);node0.firstEdge.next.next = new EdgeNode(4);
node1.firstEdge = new EdgeNode(8);node1.firstEdge.next = new EdgeNode(4);node1.firstEdge.next.next = new EdgeNode(2);
node2.firstEdge = new EdgeNode(9);node2.firstEdge.next = new EdgeNode(6);node2.firstEdge.next.next = new EdgeNode(5);
node3.firstEdge = new EdgeNode(13);node3.firstEdge.next = new EdgeNode(2);
node4.firstEdge = new EdgeNode(7);
node5.firstEdge = new EdgeNode(12);node5.firstEdge.next = new EdgeNode(8);
node6.firstEdge = new EdgeNode(5);
node8.firstEdge = new EdgeNode(7);
node9.firstEdge = new EdgeNode(11);node9.firstEdge.next = new EdgeNode(10);
node10.firstEdge = new EdgeNode(13);
node12.firstEdge = new EdgeNode(9);
}