小时候的游戏(二):最短路径算法1

来源:互联网 发布:淘宝350模板怎么样 编辑:程序博客网 时间:2024/06/10 09:50

 

最短路径算法是算法课上的一项重要内容。周末看了网易公开课上的那门算法导论,从第17课开始讲关于图的问题。由于语言的关系,看的不是太明白。后来,只好拿起纸和笔,对照书,一步一步地写,才明白dijkstra算法(以下简称D算法)的过程。但是,明白是一回事,用代码实现又是另外一回事。所以,又花了几个小时的时间,程序才算是运行正常,得到正确答案。快泪奔了。程序现在还仍谈不上什么性能,仅是运行而已。

 

如果说有值得总结的,对自己而言,第一,写程序还是晚上有效率;第二,开始CODE之前,还是需要用纸和笔,可能更效率;第三,是需要不断地练习。

 

D算法用到S、C两个顶点集合和一个整型数组D。其中S用来存放已选择的最短路径上的顶点;C用来存放未选择的顶点;D数组存放顶点1到其他顶点的最短路径的权值之和。S的初始值为顶点1,C的初始值为除顶点1之外的顶点,D的初始值是顶点1 到它直接指向的每个顶点权值,不直接指向的顶点,或者说,暂时不可达的顶点权值为正无穷大。设为正无穷大的原因,主要是算法在后面计算是否需要更该顶点的权值时用到。

 

1、初始化 S、C、D;

2、根据集合C中的顶点,查找D中最小值,找到该顶点后,将其放入S,同时在C中移除该顶点。

3、更新D值

4、重复2,直到C集合为空。

 

大致思路就是这样,如有不正确的地方,欢迎指正。JAVA代码如下:

 

import java.util.*;/*    *  Node: */class Node {int val;Node() { val = 0;}Node(int index) {this.val = index;}void dispNode() {System.out.print(this.val);}}/* * Edge:  */class Edge {int val;Node fromNode;Node toNode;Edge(){val = 0;fromNode = null;toNode = null;}Edge(int v, Node from, Node to){val= v;fromNode = from;toNode = to;}void dispEdge(){System.out.print("<"+fromNode.val+","+toNode.val+":"+val+">");}} /* * Graph */class Graph {ArrayList<Node> nodes;ArrayList<Edge> edges;Graph(ArrayList<Node> n, ArrayList<Edge> e){nodes = n;edges = e;}void dispGraph(){System.out.print("Node:\t");for(Node n:nodes){n.dispNode();System.out.printf(" ");}System.out.println();System.out.print("Edges:\t");for(Edge e:edges ){e.dispEdge();System.out.printf(" ");}System.out.println();}// for get L(u,v)int min(int i,int j){return ((i)<(j)) ? (i):(j);}void printState(ArrayList<Node> S,ArrayList<Node> C, int [] D){    System.out.println();    System.out.println("========================");        //display    System.out.print("S:\t{");    for(Node n: S)    System.out.print(n.val+" ");    System.out.print("}");        //display C    System.out.println();    System.out.print("C:\t{");    for (Node n: C)System.out.print(n.val+" ");    System.out.print("}");    // display DSystem.out.println();System.out.print("D:\t[");for (int i:D)System.out.print(i+" ");System.out.print("]");System.out.println();//display edges//dispGraph();}/* find shortest path that from node 1 to each node of Graph */void findShortestPath() {// initiate S,C,D,v;ArrayList<Node> S = new ArrayList<Node>();ArrayList<Node> C = new ArrayList<Node>();int[] D = new int[nodes.size()-1];Node v = new Node();// initiate SS.add(nodes.get(0));// initiate Cfor (int i=1; i<nodes.size(); i++)C.add(nodes.get(i));// initiate Dint k=0;for(Edge e:edges) {if (e.fromNode.val == 1)D[k++] = e.val;}for (int i=0; i<D.length-1; i++)if (D[i] == 0)D[i] = 10000;// print S, C, D before start.printState(S,C,D);System.out.println();// start to finding.Iterator<Node> it = C.iterator();  while(it.hasNext()) {// find minimal of D, for get v.int id = 0;int minimalOfD = D[0];for(int i=1; i<C.size(); i++)minimalOfD = min(minimalOfD,D[i]);for(int i=0; i<C.size(); i++)if(D[i] == minimalOfD)id = i;// initial vv= C.get(id);// print vSystem.out.println("v = "+ v.val);// update S, CS.add(v);C.remove(id);// update Dint L = 0;for (int i=0; i<C.size(); i++){for (Edge e : edges){if (e.fromNode.val == v.val && e.toNode.val == C.get(i).val) {L = D[id]+ e.val; D[e.toNode.val-2] = min(D[e.toNode.val-2],L);printState(S,C,D);}}}}// _while}// _findShortestPath()} // _class Graphclass GraphDemo {public static void main (String[] args) {// initiate Graphint[][] edgesMatrix = {{0,50,30,100,10},{0,0,0,0,0},{0,5,0,0,0},{0,20,50,0,3},{0,0,0,10,0}};int nodeNum = edgesMatrix.length;ArrayList<Node> ns = new ArrayList<Node>();ArrayList<Edge> es = new ArrayList<Edge>();// add each Nodefor(int i=1; i<= nodeNum; i++){Node n = new Node(i);ns.add(n);}// add each edgefor(int i=0; i<nodeNum; i++)for(int j=0; j<nodeNum; j++)if(edgesMatrix[i][j] != 0) {Edge e = new Edge(edgesMatrix[i][j],ns.get(i),ns.get(j));es.add(e);}// create the instance of GraphGraph G = new Graph(ns,es);// display the Nodes and Edges of GraphG.dispGraph();// find shortest-path from Node f to Node tG.findShortestPath();}}