Dijkstra算法

package com.xl.test01;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Node {
    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;
    }

}


class MapBuilder {
    public Node build(Set<Node> open, Set<Node> close) {
        Node nodeA = new Node("A");
        Node nodeB = new Node("B");
        Node nodeC = new Node("C");
        Node nodeD = new Node("D");
        Node nodeE = new Node("E");
        Node nodeF = new Node("F");
        //使用node类里的getchild()方法,再利用散列映射的put方法,将其他节点和权值关联后添加进去
        nodeA.getChild().put(nodeB, 6);
        nodeA.getChild().put(nodeC, 3);
        nodeB.getChild().put(nodeA, 6);
        nodeB.getChild().put(nodeC, 2);
        nodeB.getChild().put(nodeD, 5);
        nodeC.getChild().put(nodeA, 3);
        nodeC.getChild().put(nodeB, 2);
        nodeC.getChild().put(nodeD, 3);
        nodeC.getChild().put(nodeE, 4);
        nodeD.getChild().put(nodeB, 5);
        nodeD.getChild().put(nodeC, 3);
        nodeD.getChild().put(nodeF, 3);
        nodeD.getChild().put(nodeE, 2);
        nodeE.getChild().put(nodeC, 4);
        nodeE.getChild().put(nodeD, 2);
        nodeE.getChild().put(nodeF, 5);
        nodeF.getChild().put(nodeD, 3);
        nodeF.getChild().put(nodeE, 5);
        open.add(nodeB);
        open.add(nodeC);
        open.add(nodeD);
        open.add(nodeE);
        open.add(nodeF);
        close.add(nodeA);
        return nodeA;
    }

}

class Dijkstra {

    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>();//封装路径信息
    public Node init() {
        //初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE
        path.put("B", 6);
        pathInfo.put("B", "A->B");
        path.put("C", 3);
        pathInfo.put("C", "A->C");
        path.put("D", Integer.MAX_VALUE);
        pathInfo.put("D", "A->D");
        path.put("E", Integer.MAX_VALUE);
        pathInfo.put("E", "A->E");
        path.put("F", Integer.MAX_VALUE);
        pathInfo.put("F", "A->F");

        //将初始节点放入close,其他节点放入open
        Node start = new MapBuilder().build(open, close);
        return start;

    }


    /**
     * 获取与node最近的子节点
     */

    private Node getShortestPath(Node node) {
        Node res = null;
        int minDis = Integer.MAX_VALUE;
        Map<Node, Integer> childs = node.getChild();
        // 遍历与Node相连接的所有节点,选取其中距离最短的节点
        for (Node child : childs.keySet()) {//keyset()方法用来返回键即节点
            if (open.contains(child)) {
                int distance = childs.get(child);
                if (distance < minDis) {
                    minDis = distance;
                    res = child;
                }
            }
        }
        return res;

    }



    /*

     * 计算路径
     */

    public void computePath(Node start) {

        //取距离start节点最近的子节点,放入close
        Node nearest = getShortestPath(start);
        if (nearest == null) {
            return;
        }

        close.add(nearest);     //已遍历的

        open.remove(nearest);   //未遍历的
        Map<Node, Integer> childs = nearest.getChild();//getChild()返回child 对象,

        //child中存储了各节点到相邻节点的距离·
        for (Node child : childs.keySet()) {//遍历最近的节点
            if (open.contains(child)) {//如果子节点在open中
                Integer newCompute = path.get(nearest.getName()) + childs.get(child);
                //Map接口的get()方法用来返回key所对应的value,
                //此句是用来计算neareset这个节点到每个子节点的距离
                if (newCompute < path.get(child.getName())) {
                    //新计算出来的距离小于之前设置的距离
                    path.put(child.getName(), newCompute);
                    pathInfo.put(child.getName(), pathInfo.get(nearest.getName()) + "->" + child.getName());
                }

                //本if语句可以用来更新A到子节点的最短距离

            }
        }

        computePath(start);//重复执行自己,确保所有子节点被遍历
        computePath(nearest);//向外一层层递归,直至所有顶点被遍历

    }

    public void printPathInfo() {

        //entrySet()返回此映射中包含的映射关系的set视图

        Set<Map.Entry<String, String>> pathInfos = pathInfo.entrySet();

        for (Map.Entry<String, String> pathInfo : pathInfos) {

            System.out.println(pathInfo.getKey() + ":" + pathInfo.getValue());

        }

    }
}


class DijkstraTest {
    public static void main(String args[]) throws Exception {
        Dijkstra test = new Dijkstra();
        Node start = test.init();
        test.computePath(start);
        test.printPathInfo();

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值