欢迎使用CSDN-markdown编辑器

来源:互联网 发布:划船机品牌 知乎 编辑:程序博客网 时间:2024/05/18 01:50

最短路径算法

基于广度优先的Dijkstra算法,本算法针对的问题如下:

  • 无向图
  • 不带权
  • 文件读取
  • 最短路径算法
  • JAVA实现
  • 离线写博客

一 问题描述
1.无向图中某个顶点作为源点
2.求出图中所有顶点到源点的最短路径

二 算法实现思路
1.源点的最短路径距离为0,从源点开始,采用广度优先的顺序,首先将与源点邻接的顶点的路径求出,然后再依次求解图中其他顶点的最短路径。
2.由于顶点的最短路径的求解顺序 是一个 广度优先的顺序,因此需要一个辅助队列。初始时,将源点的最短路径距离设置为0,将源点入队列。
3.然后,在一个while循环中,从队列中弹出顶点,遍历该顶点的邻接点,若该邻接点的距离未被更新过(表示该邻接点未被访问过),更新邻接点的最短路径距离为 该顶点的距离加上1,并将所有的邻接点入队列。

三 测试结果:
保存文件:
0,0,1,4
1,0,2,7
2,0,3,3
3,1,2,3
4,1,4,2
5,3,4,3
6,2,5,2
7,4,5,2

四:代码

import java.io.File;import java.util.Collection;import java.util.LinkedHashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Queue;public class NonDirectedGraph {    public static void main(String[] args) {        String graphFilePath;        if(args.length == 0)            graphFilePath = "F:\\xxx";        else            graphFilePath = args[0];        String graphContent = FileUtil.read(graphFilePath, null);//文件读取        NonDirectedGraph graph = new NonDirectedGraph(graphContent);//构建        graph.unweightedShortestPath();//算法实现        graph.showDistance();//展示    }    //起始点——声明    private Vertex startVertix;     //图——数据结构——哈希映射(键值对)    private Map<String, Vertex> nonDirectedGraph;       //无向图——构造器    public NonDirectedGraph(String graphContent) {        nonDirectedGraph=new LinkedHashMap<>();//哈希映射        buildGraph(graphContent);//构图    }    //构图——函数    private void buildGraph(String graphContent) {        String[] lines=graphContent.split("\n");//内容行数组        String startNodeLabel, endNodeLabel;//开始点的标签,结束点的标签        Vertex startNode, endNode;//开始结束点        for(int i=0;i<lines.length;i++){            String[] nodesInfo=lines[i].split(",");//每个顶点的信息            startNodeLabel=nodesInfo[1];//读取顶点信息,并且设置开始点的标签            endNodeLabel=nodesInfo[2];//同上            //根据标签获取结束点            endNode=nonDirectedGraph.get(endNodeLabel);//根据结束标签获得结束点            if(endNode==null){//结束点不存在                endNode=new Vertex(endNodeLabel);//新                nonDirectedGraph.put(endNodeLabel,endNode);//放入无向图            }            //根据标签获取开始点            startNode = nonDirectedGraph.get(startNodeLabel);            if(startNode == null){                 startNode = new Vertex(startNodeLabel);                 nonDirectedGraph.put(startNodeLabel, startNode);            }            //开始和结束点的边,对于无向图而言,起点和终点都要添加边            Edge e=new Edge(endNode);            endNode.adjEdge.add(e);            startNode.adjEdge.add(e);        }        //以文件中第一行第二列的那个标识顶点作为源点        startVertix=nonDirectedGraph.get(lines[0].split(",")[1]);    }    //顶点-定义    private class Vertex{        private String vertixLable="";//顶点是否已经访问的标志        private List<Edge> adjEdge;//顶点的邻接边        private int dist;//顶点距离上一顶点的距离        private Vertex preVertex;//上一个顶点        //构造函数        public Vertex(String vertixLable) {            this.vertixLable=vertixLable;//是否访问过            adjEdge=new LinkedList<>();//邻边列表            dist=Integer.MAX_VALUE;//距离初始化为最大值            preVertex=null;//上一顶点初始为空        }    }    //边-定义    private class Edge{        private Vertex endVeritx;//边的结束顶点        public Edge(Vertex endVeritx) {            this.endVeritx=endVeritx;        }    }    //实现算法    //无权最短路径,源点到无向图中各个顶点之间的最短路径    //需要一个队列来保存图中的顶点,初始时,源点入队列,然后以广度的形式向外扩散求解其他顶点的最短路径    private void unweightedShortestPath(Vertex s) {        Queue<Vertex> queue=new LinkedList<>();//顶点队列        s.dist=0;//源点距离初始为0        queue.offer(s);//源点入队列        while(!queue.isEmpty()) {//队列非空            Vertex v=queue.poll();//读取队列第一个元素            for(Edge e:v.adjEdge){//v 顶点的每个顶点                if(e.endVeritx.dist==Integer.MAX_VALUE){//如果这个顶点(e.endVertex)未被访问(每个顶点只会入队列一次)                    e.endVeritx.dist=v.dist+1;//更新距离,加一个顶点                    queue.offer(e.endVeritx);//结束顶点入队                    e.endVeritx.preVertex=v;//结束顶点的前一个顶点为V顶点                }            }        }    }    public void unweightedShortestPath(){        unweightedShortestPath(startVertix);    }       //打印图中所有顶点到源点的距离及路径    public void showDistance() {        Collection<Vertex> vertexs=nonDirectedGraph.values();        for(Vertex vertex:vertexs){            System.out.print(vertex.vertixLable+"<——");            Vertex tempPreNode=vertex.preVertex;            while(tempPreNode!=null){                System.out.print(tempPreNode.vertixLable+"<——");                tempPreNode=tempPreNode.preVertex;            }            System.out.println("距离="+vertex.dist);        }    }}
0 0