Dijkstra算法以及java实现_02(代码部分)

来源:互联网 发布:阿里云ecs 发送邮件 编辑:程序博客网 时间:2024/05/21 14:57

1.数据库表的设计:
这里写图片描述

dijsname1和dijsname2是有向图中的两个点。qinmid是这两个点之间的亲密度,将亲密度的值作为边的权值大小。

2.对数据库中数据进行增删改查操作:

//这里主要实现了insert(插入)操作和查找操作(通过两个点查找亲密度)package com.graduat.dao.impl;public class DijstraImpl implements DijstTestDao {    private static final String INSERT = "insert into dijsttest(dijsname1,dijsname2,qinmid) values(?,?,?)";    private static final String FINDBYDN = "select qinmid from dijsttest where dijsname1=? and dijsname2=? ";    @Override    public void insert(DijstTest dijstTest) throws Exception {        PreparedStatement prep = null;        Connection conn = null;        try {            conn = DBConnection.getConnection();            prep = conn.prepareStatement(INSERT, Statement.RETURN_GENERATED_KEYS);            prep.setString(1, dijstTest.getDijsname1());            prep.setString(2, dijstTest.getDijsname2());            prep.setInt(3, dijstTest.getQinmid());            prep.executeUpdate();            ResultSet rst = prep.getGeneratedKeys();            rst.next();            int id = rst.getInt(1);            dijstTest.setId(id);        } finally {            DBConnection.close(prep, conn);        }    }    @Override    public DijstTest findByDn(String Dname1, String Dname2) throws Exception {        // TODO Auto-generated method stub        PreparedStatement prep = null;        Connection conn = null;        DijstTest dijstTest = null;        ResultSet rst = null;        try {            conn = DBConnection.getConnection();            prep = conn.prepareStatement(FINDBYDN);            prep.setString(1, Dname1);            prep.setString(2,Dname2);            rst = prep.executeQuery();            if(rst.next()) {                dijstTest = new DijstTest();                dijstTest.setQinmid(rst.getInt("qinmid"));            }        } finally {            DBConnection.close(prep, conn);        }        return dijstTest;    }}

3.定义节点信息:

public class Node {//定义节点的name属性和child孩子属性,并且实现其get和set方法。    private String name;    private Map<Node,Integer> child = new HashMap<Node, Integer>();    public Node(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Map<Node,Integer> getChild() {        return child;    }    public void setChild(Map<Node,Integer> child) {        this.child = child;    }

4.初始化所有节点:

public class MapBuilder {    String nodetestdemo = null;    DijstTestDao dijks = DijstraFactory.getDijistra();    DijstTest d;    public Node build(Set<Node> open, Set<Node> close, List<Node> lists) throws Exception {        Node n1;        for (int i = 0; i < lists.size(); i++) {            n1 = lists.get(i);            for (int j = 0; j < lists.size(); j++) {                if (n1 != lists.get(j)) {//通过两个节点信息在数据库中查找亲密度权值。                    d = dijks.findByDn(lists.get(i).getName(), lists.get(j).getName());                    if(d != null)                        n1.getChild().put(lists.get(j), d.getQinmid());                }            }        }        // 遍历node类型的数组        // 现在求每个点到其他点的最短距离之和已经实现,要循环抽象求和的最小值,输出最小中心结点和最短距离。        Node nn = null;        //close数组用来保存源节点信息        //open数组用来保存除了源节点之外的所有节点信息        for (int i = 0; i < lists.size(); i++) {            if( nodetestdemo.equals(lists.get(i).getName()) ) {                nn = lists.get(i);                close.add(lists.get());            }            else                open.add(lists.get(i));        }        return nn;    }}

5.核心算法:

public class Dijkstra {    ArrayList<String> list = new ArrayList<String>();    Set<Node> open = new HashSet<Node>();    Set<Node> close = new HashSet<Node>();    Map<String, Integer> path = new HashMap<String, Integer>();// 封装路径距离    Map<String, String> pathInfo = new HashMap<String, String>();// 封装路径信息    String testpppp = null;    ArrayList<String> listlist = new ArrayList<String>();    ArrayList<Integer> listlist1 = new ArrayList<Integer>();//通过输入两个节点的名字,去数据库中查找亲密度权值大小//可直接到达则直接返回,否则返回最大值    public int finddistance(String num1, String num2) throws Exception {        DijstTestDao dijks = DijstraFactory.getDijistra();        DijstTest d = dijks.findByDn(num1, num2);        if (d != null) {            return d.getQinmid();        } else {            return Integer.MAX_VALUE;        }    }    public Node init(List<Node> nodes) throws Exception {        // 初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE        //list.size()是初始输入节点的个数        String[] t = new String[list.size()];        for (int i = 0; i < list.size(); i++) {            t[i] = list.get(i);        }        for (int i = 0; i < t.length; i++) {            if (t[i] == testpppp) {                continue;            } else {            //将两节点的路径信息和路径长度分别存储在path和pathInfo中。                path.put(t[i], finddistance(testpppp, t[i]));                pathInfo.put(t[i], testpppp + "->" + t[i]);            }        }        // 将初始节点放入close,其他节点放入open        MapBuilder mapBuilder = new MapBuilder();        mapBuilder.nodetestdemo = testpppp;        Node start = mapBuilder.build(open, close, nodes);        return start;    }    public void computePath(Node start) {        Node nearest = getShortestPath(start);// 取距离start节点最近的子节点,放入close        if (nearest == null) {            return;        }        close.add(nearest);        open.remove(nearest);        Map<Node, Integer> childs = nearest.getChild();        for (Node child : childs.keySet()) {            if (open.contains(child)) {// 如果子节点在open中                Integer newCompute = path.get(nearest.getName())                        + childs.get(child);                if (path.get(child.getName()) > newCompute) {// 之前设置的距离大于新计算出来的距离                    path.put(child.getName(), newCompute);                    pathInfo.put(                            child.getName(),                            pathInfo.get(nearest.getName()) + "->"                                    + child.getName());                }            }        }        computePath(start);// 重复执行自己,确保所有子节点被遍历        computePath(nearest);// 向外一层层递归,直至所有顶点被遍历    }    @SuppressWarnings({ "static-access", "rawtypes" })    public void printPathInfo(ArrayList<String> bigList,ArrayList<Integer> bigList1) {        Set<Map.Entry<String, String>> pathInfos = pathInfo.entrySet();        Collection<Integer> values = path.values();        int sum = 0;        int sum_end = 0;        for (Map.Entry<String, String> pathInfo : pathInfos) {                   listlist.add(testpppp+"->"+pathInfo.getKey());               bigList.add(testpppp+"->"+pathInfo.getKey());        }        for (Integer object : values) {            sum = Integer.parseInt(object.toString());            sum_end = sum_end + sum;                listlist1.add(sum);             bigList1.add(sum);        }        System.out.println("和为sumend=" + sum_end);        System.out.println(testpppp);        Main main = new Main();        main.sum = sum_end;        main.testp = testpppp;    }    /**     * 获取与node最近的子节点,根据距离去判断远近关系     */    private Node getShortestPath(Node node) {        Node res = null;        int minDis = Integer.MAX_VALUE;        Map<Node, Integer> childs = node.getChild();        for (Node child : childs.keySet()) {            if (open.contai`s(child)) {                int distance = childs.get(child);                if (distance < minDis) {                    minDis = distance;                    res = child;                }            }        }        return res;    }}

6.测试main函数:

public class Main {    int sumend = 0;    static int sum = 0;    static String testp = null;    ArrayList<String> listlist = new ArrayList<String>();    ArrayList<String> listlist1 = new ArrayList<String>();    static ArrayList<String> bigList = new ArrayList<String>();    static ArrayList<Integer> bigList1 = new ArrayList<Integer>();    public static void main(String[] args) throws Exception {    //在main函数中输入测试数组        String t[] = new String[] { "A", "B", "C", "D", "E", "F", "G", "H" };        Main.getShort(t);        int instance =findShortInstance("A","D");        System.out.println(instance);    }    public static String getShort(String[] ss) throws Exception {        Map<String, Integer> map = new HashMap<String, Integer>();        String aa = null;        ArrayList<String> list = new ArrayList<String>();        for (int i = 0; i < ss.length; i++) {            list.add(ss[i]);        }        Dijkstra test;        List<Node> lists = new ArrayList<Node>();        for (int i = 0; i < ss.length; i++) {            Node node = new Node(ss[i]);            lists.add(node);        }        for (int i = 0; i < ss.length; i++) {            test = new Dijkstra();            test.list = list;            test.testpppp = ss[i];            Node start = test.init(lists);            test.computePath(start);            test.printPathInfo(bigList,bigList1);            map.put(testp, sum);        }         for (Map.Entry<String, Integer> me : map.entrySet()) {                 }        if (map != null) {            Collection<Integer> c = map.values();            Object[] obj = c.toArray();            Arrays.sort(obj);            int value = (int) obj[0];            System.out.println("中心点距离其他所有点的最短距离为" + value);            for (Map.Entry entry : map.entrySet()) {                if (value == (int) entry.getValue()) {                aa = (String) entry.getKey();                }            }        }        return aa;      }    public static int findShortInstance(String a, String b)throws Exception {        int instance = -1;                for(int i=0; i<bigList.size(); i++){                        if(bigList.get(i).contains(a) && bigList.get(i).contains(b)){                instance = bigList1.get(i);                return instance;            }        }        return instance;    }}