单源最短路径-分支界限法

        单源最短路径-分支界限法-优先队列式。这里使用无回路的有向图,便于构建树。构建好树后,从根结点作为起始源,加入结点队列,然后判断获取队列中最短的路径结点做为活结点,将活结点的所有子结点加入队列,移除活结点。这里需要注意活结点的子结点加入时需要判断是否在现有队列中已存在同一个路径点(就是有向图的点),如果存在需要用最短的替换,就是分支界限法中所谓的剪枝。

package test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by saishangmingzhu on 2018/12/4.
 * 单源最短路径
 */
public class SingleSourceShortestPath {
    public static void main(String[] arg) {
        new SingleSourceShortestPath().branchAndBoundMethod();
    }


    /**
     * 分支界限法-优先队列式
     */
    public void branchAndBoundMethod() {
        List<Point> pointList=new ArrayList<>();
        pointList.add(new Point("A",0));
        pointList.add(new Point("B",0));
        pointList.add(new Point("C",0));
        pointList.add(new Point("D",0));
        pointList.add(new Point("E",0));
        pointList.add(new Point("F",0));
        pointList.add(new Point("G",0));
        pointList.add(new Point("H",0));
        pointList.add(new Point("I",0));
        pointList.add(new Point("J",0));
        pointList.add(new Point("K",0));
        Map<String,Integer> pathMap=new HashMap<>();
        pathMap.put("AB",2);
        pathMap.put("AC",3);
        pathMap.put("AD",4);
        pathMap.put("BE",7);
        pathMap.put("BF",2);
        pathMap.put("BC",3);
        pathMap.put("CF",9);
        pathMap.put("CG",2);
        pathMap.put("DG",2);
        pathMap.put("EH",1);
        pathMap.put("EI",1);
        pathMap.put("FI",3);
        pathMap.put("FG",2);
        pathMap.put("GI",5);
        pathMap.put("GJ",1);
        pathMap.put("HK",1);
        pathMap.put("IK",1);
        pathMap.put("JI",2);
        pathMap.put("JK",2);
        //构造树
        Node root=new Node(pointList.get(0),"A",0);
        again(pointList, pathMap, root);
        System.out.println(root);
        List<Node> nodeList=new ArrayList<>();
        List<Node> resultNodeList=new ArrayList<>();
        nodeList.add(root);
        while (nodeList.size()>0) {
            //判断list中最小的结点node
            Node liveNode = getMinNode(nodeList);
            //做为活结点,记录,取出子结点list
            resultNodeList.add(liveNode);
            List<Node> childList = liveNode.getChildNodeList();
            for (Node childNode : childList) {
                //判断子结点中是否有重复的路径点point
                //if重复,取短的
                //else,加入nodelist
                addNode(childNode, nodeList);
            }
            //移除活结点
            nodeList.remove(liveNode);
        }
        for (Node node:resultNodeList){
            System.out.println(node.getPoint().getName()+":"+node.getPath()+":"+node.getValue());
        }

    }
    public void addNode(Node childNode,List<Node> nodeList){
        boolean flag=true;
        for (Node node:nodeList){
            if(node.getPoint()==childNode.getPoint()){
                if (node.getValue()>childNode.getValue()){
                    node=childNode;
                }
                flag=false;
            }
        }
        if (flag) {
            nodeList.add(childNode);
        }
    }

    public Node getMinNode(List<Node> nodeList){
        int minV=Integer.MAX_VALUE;
        Node minNode=null;
        for (Node node:nodeList){
            if (node.getValue()<minV){
                minV=node.getValue();
                minNode=node;
            }
        }
        return minNode;
    }

    private void again(List<Point> pointList, Map<String, Integer> pathMap, Node parent) {
        for (Point p:pointList){
            String key=parent.getPoint().getName()+p.getName();
            if (pathMap.containsKey(key)){
                Node node=new Node(p,parent.getPath()+p.getName(),parent.getValue()+pathMap.get(key));
                parent.getChildNodeList().add(node);
                again(pointList, pathMap, node);
            }
        }
    }

    
    class Node{
        Point point;
        String path;
        int value;
        List<Node> childNodeList=new ArrayList<>();

        public Node(Point point, String path, int value) {
            this.point = point;
            this.path = path;
            this.value = value;
        }

        public List<Node> getChildNodeList() {
            return childNodeList;
        }

        public void setChildNodeList(List<Node> childNodeList) {
            this.childNodeList = childNodeList;
        }

        public Point getPoint() {
            return point;
        }

        public void setPoint(Point point) {
            this.point = point;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }
}
class Point{
    String name;
    int index;

    public Point(String name, int index) {
        this.name = name;
        this.index = index;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}


猜你喜欢

转载自blog.51cto.com/zuohao1990/2326235