單源最短路徑-分支界限法-優先隊列式。這裏使用無迴路的有向圖,便於構建樹。構建好樹後,從根結點做爲起始源,加入結點隊列,而後判斷獲取隊列中最短的路徑結點作爲活結點,將活結點的全部子結點加入隊列,移除活結點。這裏須要注意活結點的子結點加入時須要判斷是否在現有隊列中已存在同一個路徑點(就是有向圖的點),若是存在須要用最短的替換,就是分支界限法中所謂的剪枝。java
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; } }