您的位置:首页 > 理论基础 > 数据结构算法

算法——数据结构图的最短路径实现JAVA代码

2014-04-07 22:40 1081 查看
图求最短路径的Floyd和Dijkstra算法JAVA代码实现
package graph;/*** Created by Thinkpad on 2014/3/31.*/public class VertexType{private String name;private int id;public VertexType(int i, String a){id = i;name = a;}public String getName(){return name;}public void setName(String name){this.name = name;}public int getId(){return id;}public void setId(int id){this.id = id;}}
package graph;/*** Created by Thinkpad on 2014/3/31.*/public class EdgeType{protected int weight;public EdgeType(int weight){this.weight = weight;}}
package graph;import java.util.ArrayList;import java.util.HashMap;public class GraphMatrixOperator{private static final int INFINITY = 65535;private ArrayList<ArrayList<EdgeType>> arcList = new ArrayList<ArrayList<EdgeType>>();private ArrayList<VertexType> vertexes = new ArrayList<VertexType>();private HashMap<String, VertexType> vertexNodeHashMap = new HashMap<String, VertexType>();//    protected  int[] p;    /* 用于存储最短路径下标的数组 *///    protected  int[] d ;/* 用于存储到各点最短路径的权值和 */private int numVertexes;private int numEdges;public ArrayList<ArrayList<EdgeType>> getArcList(){return arcList;}public ArrayList<VertexType> getVertexes(){return vertexes;}public HashMap<String, VertexType> getVertexNodeHashMap(){return vertexNodeHashMap;}/* 建立无向网图的邻接矩阵表示 */public static void initMGraph(GraphMatrixOperator g){}protected static void initVertexes(GraphMatrixOperator g){for (int i = 0; i < g.numVertexes; i++) /* 读入顶点信息,建立顶点表 */{g.getVertexes().set(i, new VertexType(i, ""));}}protected static void initArcWithIJ(GraphMatrixOperator g){for (int i = 0; i < g.getNumVertexes(); i++){for (int j = i; j < g.getNumVertexes(); j++){g.getArcList().get(j).get(i).weight = g.getArcList().get(i).get(j).weight;}}}protected static void initNet(GraphMatrixOperator g){for (int i = 0; i < g.numVertexes; i++)/* 初始化图 */{for (int j = 0; j < g.numVertexes; j++){if (i == j){g.getArcList().get(i).set(j, new EdgeType(0));}else{g.getArcList().get(i).set(j, new EdgeType(INFINITY));g.getArcList().get(j).set(i, new EdgeType(INFINITY));}}}}private static void initArcList(GraphMatrixOperator g, int size){for (int i = 0; i < size; i++){ArrayList<EdgeType> al = new ArrayList<EdgeType>();g.getArcList().add(al);for (int j = 0; j < size; j++){if (i == j){al.add(new EdgeType(0));}else{al.add(new EdgeType(INFINITY));}}}}public static void addArcFromI2J(GraphMatrixOperator g, String a, String b, int w){addVex(g, a);addVex(g, b);g.getArcList().get(g.getVertexNodeHashMap().get(a).getId()).get(g.getVertexNodeHashMap().get(b).getId()).weight = w;g.getArcList().get(g.getVertexNodeHashMap().get(b).getId()).get(g.getVertexNodeHashMap().get(a).getId()).weight = w;}private static void addVex(GraphMatrixOperator g, String a){if (!g.getVertexNodeHashMap().containsKey(a)){int size = g.getVertexes().size();VertexType e = new VertexType(size, a);g.getVertexes().add(e);g.getVertexNodeHashMap().put(a, e);}}/*  Dijkstra算法,求有向网G的v0顶点到其余顶点v的最短路径p[v]及带权长度d[v] *//*  p[v]的值为前驱顶点下标,d[v]表示v0到v的最短路径长度和 */public static void shortestPath_Dijkstra(GraphMatrixOperator g, int v0, int[] p, int[] d){int v, w, k = 0, min;int maxvex = g.getNumVertexes();int[] finalInt = new int[maxvex];/* finalInt[w]=1表示求得顶点v0至vw的最短路径 */int n = g.numVertexes;for (v = 0; v < n; v++)    /* 初始化数据 */{finalInt[v] = 0;			/* 全部顶点初始化为未知最短路径状态 */d[v] = g.getArcList().get(v0).get(v).weight;/* 将与v0点有连线的顶点加上权值 */p[v] = -1;				/* 初始化路径数组P为-1  */}d[v0] = 0;  /* v0至v0路径为0 */finalInt[v0] = 1;    /* v0至v0不需要求路径 *//* 开始主循环,每次求得v0到某个v顶点的最短路径 */for (v = 1; v < n; v++){min = INFINITY;    /* 当前所知离v0顶点的最近距离 */for (w = 0; w < n; w++) /* 寻找离v0最近的顶点 */{if ((finalInt[w] == 0) && (d[w] < min)){k = w;min = d[w];    /* w顶点离v0顶点更近 */}}finalInt[k] = 1;    /* 将目前找到的最近的顶点置为1 */for (w = 0; w < n; w++) /* 修正当前最短路径及距离 */{/* 如果经过v顶点的路径比现在这条路径的长度短的话 */if ((0 == finalInt[w]) && ((min + g.getArcList().get(k).get(w).weight) < d[w])){ /*  说明找到了更短的路径,修改d[w]和p[w] */d[w] = min + g.getArcList().get(k).get(w).weight;  /* 修改当前路径长度 */p[w] = k;}}}System.out.println("final[]:");for (int i : finalInt){System.out.print(i);}System.out.println();}public static void main(String[] args){/* 求某点到其余各点的最短路径 */String[] src = new String[]{"a,b,1", "b,c,2", "a,c,4", "b,d,7"};GraphMatrixOperator g = createMGraph(src);logMGraph(g);int v0 = 0;main_Dijkstra(g, v0);main_floyd(g);}private static GraphMatrixOperator createMGraph(String[] src){GraphMatrixOperator g = new GraphMatrixOperator();initArcList(g, src.length);for (String s : src){System.out.println(s);String[] line = s.split(",");addArcFromI2J(g, line[0], line[1], Integer.valueOf(line[2]));}int size = g.getVertexes().size();g.setNumVertexes(size);g.setNumEdges(src.length);return g;}private static void logMGraph(GraphMatrixOperator g){for (VertexType vertexType : g.getVertexes()){System.out.print(vertexType.getName() + " ");}System.out.println();for (ArrayList<EdgeType> edgeTypes : g.getArcList()){for (EdgeType edgeType : edgeTypes){System.out.print(edgeType.weight + "  ");}System.out.println();}}private static void main_Dijkstra(GraphMatrixOperator g, int v0){int size = g.getVertexes().size();int[] p = new int[size];int[] d = new int[size];shortestPath_Dijkstra(g, v0, p, d);System.out.println("用于存储到各点最短路径的权值和:");for (int i : d){System.out.print(i + " ");}System.out.println();System.out.println("用于存储最短路径下标的数组 :");for (int i : p){System.out.print(i + " ");}System.out.println();System.out.println("最短路径倒序如下:");int j;for (int i = 1; i < g.numVertexes; ++i){System.out.print(v0 + "-" + i + ":");j = i;while (p[j] != -1){System.out.print(g.getVertexes().get(p[j]).getName());j = p[j];}System.out.println();}System.out.println("\n源点到各顶点的最短路径长度为:");for (int i = 1; i < g.numVertexes; ++i){System.out.print(g.getVertexes().get(v0).getName() + "-");System.out.print(g.getVertexes().get(i).getName() + ":");System.out.println(d[i]);}}public void setNumVertexes(int numVertexes){this.numVertexes = numVertexes;}public int getNumVertexes(){return numVertexes;}public void setNumEdges(int numEdges){this.numEdges = numEdges;}public int getNumEdges(){return numEdges;}/* Floyd算法,求网图G中各顶点v到其余顶点w的最短路径p[v][w]及带权长度d[v][w]。 */public static void shortestPath_Floyd(GraphMatrixOperator g, int[][] pList, int[][] dList){int size = g.numVertexes;for (int v = 0; v < size; ++v) /* 初始化D与P */{for (int w = 0; w < size; ++w){dList[v][w] = g.arcList.get(v).get(w).weight;	/* d[v][w]值即为对应点间的权值 */pList[v][w] = w;				/* 初始化P */}}for (int k = 0; k < size; ++k){for (int v = 0; v < size; ++v){for (int w = 0; w < size; ++w){if (dList[v][w] > dList[v][k] + dList[k][w]){/* 如果经过下标为k顶点路径比原两点间路径更短 */dList[v][w] = dList[v][k] + dList[k][w];/* 将当前两点间权值设为更小的一个 */pList[v][w] = pList[v][k];/* 路径设置为经过下标为k的顶点 */}}}}}public static void main_floyd(GraphMatrixOperator g){int size = g.getVertexes().size();int[][] pList = new int[size][size];int[][] dList = new int[size][size];shortestPath_Floyd(g, pList, dList);printPath(size, pList, dList);printDList(size, dList);printPList(size, pList);}private static void printPList(int size, int[][] pList){System.out.println("最短路径的下标P:");for (int v = 0; v < size; ++v){for (int w = 0; w < size; ++w){System.out.print(pList[v][w] + "-");}System.out.println();}}public static void printDList(int size, int[][] dList){System.out.println("最短路径的权值和D:");for (int v = 0; v < size; ++v){for (int w = 0; w < size; ++w){System.out.print(dList[v][w] + "-");}System.out.println();}}public static void printPath(int size, int[][] pList, int[][] dList){System.out.println("各顶点间最短路径如下:");for (int v = 0; v < size; ++v){for (int w = v + 1; w < size; w++){System.out.println(v + "-" + w + ":" + dList[v][w]);printPathFromV2W(pList, v, w);}}}public static void printPathFromV2W(int[][] pList, int v, int w){int k;k = pList[v][w];				/* 获得第一个路径顶点下标 */System.out.print(v + "-");	/* 打印源点 */while (k != w)				/* 如果路径顶点下标不是终点 */{System.out.print(k + "-");	/* 打印路径顶点 */k = pList[k][w];			/* 获得下一个路径顶点下标 */}System.out.println(w);	/* 打印终点 */}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: