学校的景点见得最短路径问题

来源:互联网 发布:成都java 编辑:程序博客网 时间:2024/04/30 09:06
package sy10;public class GenerateGraph {public final static int INFINITY = Integer.MAX_VALUE;public static MGraph generateMGraph() {Object vexs[] = { "学校正门", "学校东门", "学校西门", "学校北门", "食堂", "磁悬浮列车实验室" , "樱花大道", "图书馆", "体育场", "体育馆", "游泳馆", "礼堂", "教学楼", "宿舍"};int[][] arcs = { {INFINITY, INFINITY, INFINITY, INFINITY, 35, INFINITY ,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,5,INFINITY,INFINITY},{INFINITY,INFINITY, INFINITY, INFINITY, INFINITY, INFINITY ,INFINITY,INFINITY,INFINITY,INFINITY,75,INFINITY,INFINITY,10},{INFINITY,INFINITY,INFINITY,INFINITY,30,INFINITY,INFINITY,5,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY },{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,15,50,INFINITY,15,20,INFINITY,INFINITY,INFINITY},{35, INFINITY, 30, INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,60,INFINITY,INFINITY,40,INFINITY,INFINITY },{ INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY,INFINITY,INFINITY,45,INFINITY,INFINITY,10,INFINITY,INFINITY } ,{INFINITY,INFINITY,INFINITY,15,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY},{INFINITY,INFINITY,5,50,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY},{INFINITY,INFINITY,INFINITY,INFINITY,60,45,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,50,INFINITY,INFINITY},{INFINITY,INFINITY,INFINITY,15,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,20,INFINITY,INFINITY,100},{INFINITY,75,INFINITY,20,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,20,INFINITY,INFINITY,INFINITY,INFINITY},{5,INFINITY,INFINITY,INFINITY,40,10,INFINITY,INFINITY,50,INFINITY,INFINITY,INFINITY,25,INFINITY},{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,25,INFINITY,20},{INFINITY,10,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,100,INFINITY,INFINITY,20,INFINITY},};MGraph G = new MGraph(GraphKind.UDN, 14, 19, vexs, arcs);return G;}}
package sy10;// 图的种类 有向图、有向网、无向图、无向网public enum GraphKind {UDG, // 无向图(UnDirected Graph)DG, // 有向图(Directed Graph)UDN, // 无向网(UnDirected Network)DN; // 有向网(Directed Network)}
package sy10;//图的接口public interface IGraph {void createGraph();//创建一个图int getVexNum(); // 返回顶点数int getArcNum();// 返回边数Object getVex(int v) throws Exception;// 返回v表示结点的值, 0 <= v < vexNumint locateVex(Object vex);// 给定顶点的值vex,返回其在图中的位置,如果图中不包含此顶点,则返回-1int firstAdjVex(int v) throws Exception; // 返回v的第一个邻接点,若v没有邻接点,则返回-1,其中0≤v<vexNumint nextAdjVex(int v, int w) throws Exception;// 返回v相对于w的下一个邻接点,若w是v的最后一个邻接点,则返回-1,其中0≤v, w<vexNum}
package sy10;/** *  * 线性表的接口 *  */public interface IList {public void clear(); // 将一个已经存在的线性表置成空表public boolean isEmpty(); // 判断当前线性表中的数据元素个数是否为0,若为0则函数返回true,否则返回falsepublic int length(); // 求线性表中的数据元素个数并由函数返回其值public Object get(int i) throws Exception;// 读取到线性表中的第i个数据元素并由函数返回其值。其中i取值范围为:0≤i≤length()-1,如果i值不在此范围则抛出异常public void insert(int i, Object x) throws Exception;// 在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i取值范围为:0≤i≤length()。如果i值不在此范围则抛出异常,当i=0时表示在表头插入一个数据元素x,当i=length()时表示在表尾插入一个数据元素xpublic void remove(int i) throws Exception;// 将线性表中第i个数据元素删除。其中i取值范围为:0≤i≤length()- 1,如果i值不在此范围则抛出异常public int indexOf(Object x);// 返回线性表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1public void display();// 输出线性表中的数据元素}

package sy10;import java.util.Scanner;//图的数组表示法public class MGraph implements IGraph {public final static int INFINITY = Integer.MAX_VALUE;private GraphKind kind;// 图的种类标志private int vexNum, arcNum;// 图的当前顶点数和边数private Object[] vexs;// 顶点private int[][] arcs;// 邻接矩阵public MGraph() {this(null, 0, 0, null, null);}public MGraph(GraphKind kind, int vexNum, int arcNum, Object[] vexs,int[][] arcs) {this.kind = kind;this.vexNum = vexNum;this.arcNum = arcNum;this.vexs = vexs;this.arcs = arcs;}// 创建一个图public void createGraph() {Scanner sc = new Scanner(System.in);System.out.println("请输入图的类型:");GraphKind kind = GraphKind.valueOf(sc.next());switch (kind) {case UDG:createUDG();// 构造无向图return;case DG:createDG();// 构造有向图return;case UDN:createUDN();// 构造无向网return;case DN:createDN();// 构造有向网return;}}// 创建无向图private void createUDG() {// 略Scanner sc = new Scanner(System.in);System.out.println("请分别输入图的顶点数、图的变数:");vexNum = sc.nextInt();arcNum = sc.nextInt();vexs = new Object[vexNum];System.out.println("请分别输入图的各个顶点:");for (int v = 0; v < vexNum; v++)vexs[v] = sc.next();arcs = new int[vexNum][vexNum];for (int v = 0; v < vexNum; v++)for ( int u = 0; u < vexNum; u++)arcs[v][u] = 0;System.out.println("请输入各个边的两个顶点");for (int k = 0; k < arcNum; k++){int v = locateVex(sc.next());//System.out.println(locateVex(sc.next()));//System.out.println(v);int u = locateVex(sc.next());arcs[v][u] = arcs[u][v] = 1;}}// 创建有向图private void createDG() {}// 创建无向网private void createUDN() {Scanner sc = new Scanner(System.in);System.out.println("请分别输入图的顶点数、图的边数:");vexNum = sc.nextInt();arcNum = sc.nextInt();vexs = new Object[vexNum];System.out.println("请分别输入图的各个顶点:");for (int v = 0; v < vexNum; v++)// 构造顶点向量vexs[v] = sc.next();arcs = new int[vexNum][vexNum];for (int v = 0; v < vexNum; v++)// 初始化邻接矩阵for (int u = 0; u < vexNum; u++)arcs[v][u] = INFINITY;System.out.println("请输入各个边的顶点及其权值:");for (int k = 0; k < arcNum; k++) {int v = locateVex(sc.next());int u = locateVex(sc.next());arcs[v][u] = arcs[u][v] = sc.nextInt();}}// 创建有向网private void createDN() {Scanner sc = new Scanner(System.in);System.out.println("请分别输入图的顶点数、图的边数:");vexNum = sc.nextInt();arcNum = sc.nextInt();vexs = new Object[vexNum];System.out.println("请分别输入图的各个顶点:");for (int v = 0; v < vexNum; v++)// 构造顶点向量vexs[v] = sc.next();arcs = new int[vexNum][vexNum];for (int v = 0; v < vexNum; v++)// 初始化邻接矩阵for (int u = 0; u < vexNum; u++)arcs[v][u] = INFINITY;System.out.println("请输入各边的顶点及其权值:");for (int k = 0; k < arcNum; k++) {int v = locateVex(sc.next());int u = locateVex(sc.next());arcs[v][u] = sc.nextInt();}}// 返回顶点数public int getVexNum() {return vexNum;}// 返回边数public int getArcNum() {return arcNum;}// 给定顶点的值vex,返回其在图中的位置,如果图中不包含此顶点,则返回-1public int locateVex(Object vex) {for (int v = 0; v < vexNum; v++)if (vexs[v].equals(vex))return v;return -1;}// 返回v表示结点的值, 0 <= v < vexNumpublic Object getVex(int v) throws Exception {if (v < 0 && v >= vexNum)throw new Exception("第" + v + "个顶点不存在!");return vexs[v];}// 返回v的第一个邻接点,若v没有邻接点则返回-1, 0 <= v < vexnumpublic int firstAdjVex(int v) throws Exception {if (v < 0 && v >= vexNum)throw new Exception("第" + v + "个顶点不存在!");for (int j = 0; j < vexNum; j++)if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)return j;return -1;}// 返回v相对于w的下一个邻接点,若w是v的最后一个邻接点,则返回-1,其中0≤v, w<vexNumpublic int nextAdjVex(int v, int w) throws Exception {if (v < 0 && v >= vexNum)throw new Exception("第" + v + "个顶点不存在!");for (int j = w + 1; j < vexNum; j++)if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)return j;return -1;}public GraphKind getKind() {return kind;}    public void setArcNum(int arcNum) {        this.arcNum = arcNum;    }    public void setArcs(int[][] arcs) {        this.arcs = arcs;    }    public void setKind(GraphKind kind) {        this.kind = kind;    }    public void setVexNum(int vexNum) {        this.vexNum = vexNum;    }    public void setVexs(Object[] vexs) {        this.vexs = vexs;    }public int[][] getArcs() {return arcs;}public Object[] getVexs() {return vexs;}}

package sy10;public class ShortestPath_DIJ {private boolean[][] P;// v0到其余顶点的最短路径, 若P[v][w]为true,则w是从v0到v当前求得最短路径上的顶点private int[] D;// v0到其余顶点的带权长度public final static int INFINITY = Integer.MAX_VALUE;// 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及其权值D[v]public void DIJ(MGraph G, int v0) {int vexNum = G.getVexNum();P = new boolean[vexNum][vexNum];D = new int[vexNum];boolean[] finish = new boolean[vexNum];// finish[v]为true当且仅当v属于S,即已经求得从v0到v的最短路径for (int v = 0; v < vexNum; v++) {finish[v] = false;D[v] = G.getArcs()[v0][v];for (int w = 0; w < vexNum; w++)P[v][w] = false;// 设空路径if (D[v] < INFINITY) {P[v][v0] = true;P[v][v] = true;}}D[v0] = 0;// 初始化,v0顶点属于S集finish[v0] = true;int v = -1;// 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集for (int i = 1; i < vexNum; i++) {// 其余G.getVexNum-1个顶点int min = INFINITY;// 当前所知离v0顶点的最近距离for (int w = 0; w < vexNum; w++)if (!finish[w])if (D[w] < min) {v = w;min = D[w];}finish[v] = true;// 离v0顶点最近的v加入S集for (int w = 0; w < vexNum; w++)// 更新当前最短路径及距离if (!finish[w] && G.getArcs()[v][w] < INFINITY&& (min + G.getArcs()[v][w] < D[w])) { // 修改D[w]和P[w],w属于V-SD[w] = min + G.getArcs()[v][w];System.arraycopy(P[v], 0, P[w], 0, P[v].length);P[w][w] = true;}}}public int[] getD() {return D;}public boolean[][] getP() {return P;}//public static void main(String[] args) throws Exception {//MGraph G = GenerateGraph.generateMGraph();//ShortestPath_DIJ dij = new ShortestPath_DIJ();//dij.DIJ(G, 0);////dij.display(G);//}// 用于输出最短路径上的各各顶点及权值public void display(MGraph G,int b, int r) throws Exception {if (D != null) {System.out.println(G.getVex(b)+"到各各顶点的最短路径上的点及最短距离分别是:");System.out.println();//System.out.print( G.getVex(b) + "到"  + G.getVex(r) + "请沿着这条路走,是最短的距离: ");for (int i = 0; i < P.length; i++) {System.out.print(i+" ");System.out.print( G.getVex(b) + "   到   "  + G.getVex(i) + "请沿着这条路走,是最短的距离: ");System.out.println();for (int j = 0; j < P[i].length; j++) {if (P[i][j])//System.out.println("请沿着这条路线走,距离最短,");System.out.print(G.getVex(j) + " ");}System.out.println();System.out.println("最短距离为: " + D[i] +"米");System.out.println();}System.out.println("因此"+G.getVex(b) + "  到    "  + G.getVex(r) +  "最短距离为: " + D[r] +"米");}}}

package sy10;/** *  * 顺序线性表及其基本操作 *  */public class SqList implements IList {private Object[] listElem; // 线性表存储空间private int curLen; // 当前长度// 顺序表的构造函数,构造一个存储空间容量为maxSize的线性表public SqList(int maxSize) {curLen = 0; // 置顺序表的当前长度为0listElem = new Object[maxSize];// 为顺序表分配maxSize个存储单元}// 将一个已经存在的线性表置成空表public void clear() {curLen = 0; // 置顺序表的当前长度为0}// 判断当前线性表中数据元素个数是否为0,若为0则函数返回true,否则返回falsepublic boolean isEmpty() {return curLen == 0;}// 求线性表中的数据元素个数并由函数返回其值public int length() {return curLen; // 返回顺序表的当前长度}// 读取到线性表中的第i个数据元素并由函数返回其值。其中i取值范围为:0≤i≤length()-1,如果i值不在此范围则抛出异常public Object get(int i) throws Exception {if (i < 0 || i > curLen - 1) // i小于0或者大于表长减1throw new Exception("第" + i + "个元素不存在"); // 输出异常return listElem[i]; // 返回顺序表中第i个数据元素}// 在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i取值范围为:0≤i≤length()。如果i值不在此范围则抛出异常,当i=0时表示在表头插入一个数据元素x,当i=length()时表示在表尾插入一个数据元素xpublic void insert(int i, Object x) throws Exception {if (curLen == listElem.length) // 判断顺序表是否已满throw new Exception("顺序表已满");// 输出异常if (i < 0 || i > curLen) // i小于0或者大于表长throw new Exception("插入位置不合理");// 输出异常for (int j = curLen; j > i; j--)listElem[j] = listElem[j - 1];// 插入位置及之后的元素后移listElem[i] = x; // 插入xcurLen++;// 表长度增1}// 将线性表中第i个数据元素删除。其中i取值范围为:0≤i≤length()- 1,如果i值不在此范围则抛出异常public void remove(int i) throws Exception {if (i < 0 || i > curLen - 1) // i小于1或者大于表长减1throw new Exception("删除位置不合理");// 输出异常for (int j = i; j < curLen - 1; j++)listElem[j] = listElem[j + 1];// 被删除元素之后的元素左移curLen--; // 表长度减1}// 返回线性表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1public int indexOf(Object x) {int j = 0;// j为计数器while (j < curLen && !listElem[j].equals(x))// 从顺序表中的首结点开始查找,直到listElem[j]指向元素x或到达顺序表的表尾j++;if (j < curLen)// 判断j的位置是否位于表中return j; // 返回x元素在顺序表中的位置elsereturn -1;// x元素不在顺序表中}// 输出线性表中的数据元素public void display() {for (int j = 0; j < curLen; j++)System.out.print(listElem[j] + " ");System.out.println();// 换行}// 实现对顺序表就地逆置public void reverse() {for (int i = 0,j=curLen-1; i < j; i++,j--) {Object temp = listElem[i];listElem[i] = listElem[j];listElem[j] = temp;}}// 实现对顺序表右移k位public void shit(int k) {int n=curLen,p=0,i,j,l;        Object temp;     for(i=1;i<=k;i++)          if(n%i==0&&k%i==0) //求n和k的最大公约数p              p=i;        for(i=0;i<p;i++){           j=i;           l=(i+n-k)%n;           temp=listElem[i];           while(l!=i){             listElem[j]=listElem[l];             j=l;             l=(j+n-k)%n;           }// 循环右移一步        listElem[j]=temp;        }    }}


package sy10;import java.util.Scanner;public class SY10_Graph1{public static void main(String[] args) throws Exception{SqList L = new SqList(14);L.insert(0, "这里是正门,代号为0,历史悠久,距离礼堂5米,距离食堂35米");L.insert(1, "这里是学校的东校门,代号为1,校门历史悠久,距离游泳馆75米,距离宿舍10米,具体体育馆100米");L.insert(2, "这里是西校门,代号2, 距离图书馆5米,距离食堂30米");L.insert(3," 这里是北校门,代号为3, 距离图书馆50米,距离樱花大道15米,距离体育馆9米,距离游泳馆20米");L.insert(4, "这里是食堂,代号4, 距离……介绍……此处是省略相关的信息");L.insert(5, "这是磁悬浮列车实验室,代号5,介绍……此处是省略相关的信息");L.insert(6, "这里是樱花大道, 代号6, 介绍……此处是省略相关的信息");L.insert(7,  "这里是图书馆,代号7 , 介绍……此处是省略相关的信息");L.insert(8, "这里是体育馆,代号8, 介绍……此处是省略相关的信息");L.insert(9, "这里是体育馆,代号9, 介绍……此处是省略相关的信息");L.insert(10,  "这里是游泳馆,代号10, 介绍……此处是省略相关的信息");L.insert(11, "这里是礼堂,代号11, 介绍……此处是省略相关的信息");L.insert(12,  "这里是教学楼,代号12,介绍……此处是省略相关的信息");L.insert(13, "这里是宿舍,代号13,介绍……此处是省略相关的信息");Scanner sc = new Scanner(System.in);while (true){System.out.println("请输入你想了解的景区地方:");System.out.println("----------------------------------------");System.out.println("0--正门   1--东门   2--西门   3--北校门   4--食堂");System.out.println("5--磁悬浮列车实验室    6--樱花大道    7--图书馆   8--体育场   9--体育馆");System.out.println("10--游泳馆    11--礼堂   12--教学楼   13--宿舍   14-选择最短路径   15--退出");System.out.println("----------------------------------------");System.out.println("请输入选择:(0 - 15)");int i = sc.nextInt();switch (i){case 0: System.out.println("正校门情况为:");System.out.println(L.get(0));break;case 1: System.out.println("东校门情况为:");System.out.println(L.get(1));break;case 2: System.out.println("西校门情况:");System.out.println(L.get(2));break;case 3: System.out.println("北校门情况为:");System.out.println(L.get(3));break;case 4: System.out.println("食堂情况为:");System.out.println(L.get(4));break;case 5: System.out.println("磁悬浮列车实验室情况为:");System.out.println(L.get(5));break;case 6: System.out.println("樱花大道情况为:");System.out.println(L.get(6));break;case 7: System.out.println("图书馆情况为:");System.out.println(L.get(7));break;case 8: System.out.println("体育场情况为:");System.out.println(L.get(8));break;case 9: System.out.println("体育馆情况为:");System.out.println(L.get(9));break;case 10: System.out.println("游泳馆情况为:"); System.out.println(L.get(10));break;case 11: System.out.println("礼堂情况为:"); System.out.println(L.get(11));break;case 12: System.out.println("教学楼情况为:"); System.out.println(L.get(12));break;case 13: System.out.println("宿舍情况为:"); System.out.println(L.get(13));break; case 14: System.out.println("输入你想要去的两个地方,计算机帮你计算最小距离,用数字输入");// ShortestPath_DIJ little = new ShortestPath_DIJ();// Object first = sc.next();// Object second = sc.next();//      little.DIJ(G, 0);         int v = sc.nextInt();                  int  s = sc.nextInt(); MGraph G = GenerateGraph.generateMGraph(); ShortestPath_DIJ dij = new ShortestPath_DIJ(); dij.DIJ(G, v); dij.display(G,v, s); break;case 15: return;}}}}

这是用java写成的关于学校内各个景点见得最短路径,把上面的每个代码分别放到一个.Java文件当中,写成八个文件,最后调用主类就可以得到想要的,我试过了,挺好的
0 0