Dijkstra 算法 Java实现

来源:互联网 发布:tensorflow anaconda 编辑:程序博客网 时间:2024/06/05 15:50

最近看文章看到Dijkstra 算法,想起大学的时候学习的算法导论这门课程

突然就想用java来实现下这个算法了,

以下就来介绍一下这个算法吧.

Dijkstra 算法主要是用来解决有向图单个点到其他点的最短路径的问题

然后我根据这个有向图来编写了Dijkstra 算法

这里写图片描述

public static void main(String[] args) {        //定义一个有向图        //定义一个集合,所有点的集合        List<String> DOT=new ArrayList<>();        DOT.add("A");        DOT.add("B");        DOT.add("C");        DOT.add("D");        DOT.add("E");        DOT.add("F");        DOT.add("G");        //定义一个集合,所有边到边的距离        Map<String,Integer> EGED=new HashMap<>();        EGED.put("AB",8);        EGED.put("AE",4);        EGED.put("AF",2);        EGED.put("BA",8);        EGED.put("BE",7);        EGED.put("BC",6);        EGED.put("CB",6);        EGED.put("CD",6);        EGED.put("DC",6);        EGED.put("DE",9);        EGED.put("DG",7);        EGED.put("EA",4);        EGED.put("EB",7);        EGED.put("ED",9);        EGED.put("EG",11);        EGED.put("EF",3);        EGED.put("FA",2);        EGED.put("FE",3);        EGED.put("FG",5);        EGED.put("GE",11);        EGED.put("GF",5);        EGED.put("GD",7);        //创建一个被选中的点的集合        LinkedList<String> choose=new LinkedList<>();        String Next=loop("A",DOT,choose,EGED);        String Next1=loop(Next,DOT,choose,EGED);        String Next2=loop(Next1,DOT,choose,EGED);        String Next3=loop(Next2,DOT,choose,EGED);        String Next4=loop(Next3,DOT,choose,EGED);        String Next5=loop(Next4,DOT,choose,EGED);        System.out.println("A"+"---"+Next+"---"+Next1+"---"+Next2+"---"+Next3+"---"+Next4+"---"+Next5);    }    public static String loop(String startPot,List DOT,List choose,Map<String,Integer> EGED){        //把起始点放入,这里我们选择A        choose.add(startPot);        DOT.remove(startPot);        //在边的集合中找到A开始的边        System.out.println(EGED.entrySet());        Map<String,Integer> map=new HashMap<>();        for (String s:EGED.keySet()) {            String TheKey=findroad(s,startPot+"\\w");            if (!("").equals(TheKey))            {                if (map.isEmpty())                {                    map.put(TheKey,EGED.get(TheKey));                }else{                    if (map.values().iterator().next()>EGED.get(TheKey)){                        map.clear();                        map.put(TheKey,EGED.get(TheKey));                    }                }            }        }        String Next="";        System.out.println(map.entrySet());        for (String s:map.keySet()) {            Next=s.substring(1);        }        System.out.println(Next);        //找到最短路径之后就把所有和这个点相关的路径删除        List a=new ArrayList<>();        for (String sD:EGED.keySet()) {            String TheKey=findroad(sD,"\\w*"+startPot+"\\w*");            if (!("").equals(TheKey))            {                a.add(TheKey);            }        }        for (int i = 0; i < a.size(); i++) {            EGED.remove(a.get(i));        }        System.out.println(EGED.entrySet());        return Next;    }    public static String findroad(String bian,String regEx){        Pattern pattern=Pattern.compile(regEx);        Matcher matcher=pattern.matcher(bian);        if (matcher.find())        {            return bian;        }else{            return "";        }    }

以上是代码
以下是运行输出

[GD=7, FA=2, GE=11, GF=5, EA=4, FE=3, EB=7, ED=9, DC=6, CB=6, BA=8, AB=8, BC=6, AE=4, AF=2, BE=7, CD=6, DE=9, EG=11, EF=3, DG=7, FG=5][AF=2]F[GD=7, GE=11, GF=5, FE=3, EB=7, ED=9, DC=6, CB=6, BC=6, BE=7, CD=6, DE=9, EG=11, EF=3, DG=7, FG=5][GD=7, GE=11, GF=5, FE=3, EB=7, ED=9, DC=6, CB=6, BC=6, BE=7, CD=6, DE=9, EG=11, EF=3, DG=7, FG=5][FE=3]E[GD=7, GE=11, EB=7, ED=9, DC=6, CB=6, BC=6, BE=7, CD=6, DE=9, EG=11, DG=7][GD=7, GE=11, EB=7, ED=9, DC=6, CB=6, BC=6, BE=7, CD=6, DE=9, EG=11, DG=7][EB=7]B[GD=7, DC=6, CB=6, BC=6, CD=6, DG=7][GD=7, DC=6, CB=6, BC=6, CD=6, DG=7][BC=6]C[GD=7, DC=6, CD=6, DG=7][GD=7, DC=6, CD=6, DG=7][CD=6]D[GD=7, DG=7][GD=7, DG=7][DG=7]G[]A---F---E---B---C---D---G

这是初版吧…没时间了..有时间在update一下,

其实dijkstra 算法的核心就是,在一堆有向图中,找一个起始点,然后查看和该点的连接中,最小的那个点,当作下一个起始点, 在本例中,A是出发点,第一次调用该循环的时候,AF-2是最小的,数值是2,所以F点是第二遍的起始点,但是我们已经用过了A,所以在下次循环里面的与A点相关的点我们都给删除掉,在进行循环,当边的那个集合为空时就给退出循环,路径也就找出来了.
当然,本文是最基础的实现,很多东西没考虑好,比如,很多个点怎么办,大量数据的时候怎么办,这么多循环的效率肯定非常低,
欢迎大家给建议,来提升该算法的性能,哈哈哈哈.
以上
2017-2-23

1 0
原创粉丝点击