之前在网上看到一个最短路径问题,写了自己的实现,本质上是递归创建树。
源码:
package graphDomain;
import java.util.HashMap;
import java.util.Map;
public class City {
private String name;
public City(String name) {
super();
this.name = name;
}
private Map<City,Integer> connections = new HashMap<City,Integer>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<City, Integer> getConnections() {
return connections;
}
}
package graphDomain;
import java.util.ArrayList;
import java.util.List;
public class CityMap {
private List<City> cities;
private String startCity;
private String endCity;
private String path;
private int cost;
public CityMap(){
cities = new ArrayList<City>();
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
public String getStartCity() {
return startCity;
}
public void setStartCity(String startCity) {
this.startCity = startCity;
}
public String getEndCity() {
return endCity;
}
public void setEndCity(String endCity) {
this.endCity = endCity;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
}
package graphDomain;
import java.util.ArrayList;
import java.util.List;
public class TreeNode {
private String name;//节点名(城市名)
private int cost;//花费
private List<TreeNode> childs;//子节点
public TreeNode(String name){
this.name = name;
childs = new ArrayList<TreeNode>();
}
public TreeNode(String name, int cost){
this.name = name;
this.cost = cost;
childs = new ArrayList<TreeNode>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public List<TreeNode> getChilds() {
return childs;
}
}
package graphDomain;
import java.util.Map;
import java.util.Set;
public class Tree {
private TreeNode root;//根节点
private int minCost;//最小花费
private String path;//最小花费对应最短路径
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getMinCost() {
return minCost;
}
public void setMinCost(int minCost) {
this.minCost = minCost;
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public Tree(){
root = null;
}
/**
* @param root 当前根节点(起点城市节点)
* @param city 起点城市
* @param endCity 终点城市
* @param path 起始路径名
* @param cost 耗费(默认填零)
* @return 返回起点城市所在根节点
*/
public TreeNode createTree(TreeNode root, City city, City endCity, String path, int cost){
//到了终点城市
if(city.getName().equals(endCity.getName())){
if(cost<=minCost||minCost==0){//如果此条路径花费小于当前最小花费
//则此花费为最小花费
this.minCost = cost;
//当前路径为最短路径
this.path = path;
}
return root;
}
if(root==null){
root = new TreeNode(city.getName());
}
Map<City,Integer> map = city.getConnections();
//获得city集合
Set<City> cities = map.keySet();
for(City c:cities){
if(!path.contains(c.getName())){
//若该城市还未在路径中
if(minCost!=0){//已经存在一条花费
if(cost>minCost){//若未到终点花费已经大于当前最小花费,则无需再往下走
continue;
}
}
TreeNode newNode = new TreeNode(c.getName(),map.get(c));
path = path+c.getName();
cost += map.get(c);
root.getChilds().add(createTree(newNode,c,endCity,path,cost));
//开始回溯,则需将path减去当前城市名,cost减去当前城市耗费
path = path.substring(0, path.length()-c.getName().length());
cost -= map.get(c);
}else{
//若此城市已在路径中
continue;
}
}
return root;
}
}
package graphDomain;
public class graphDemo1 {
/**
* 用树解决城市间最短路径问题
* @param args
*/
public static void main(String[] args) {
CityMap cm = new CityMap();
//创建城市实例并命名
City c1 = new City("汉");
City c2 = new City("乌");
City c3 = new City("渝");
City c4 = new City("京");
City c5 = new City("沪");
City c6 = new City("圳");
//建立城市之间的连接
c1.getConnections().put(c3, 7);
c1.getConnections().put(c6, 9);
c1.getConnections().put(c5, 3);
c1.getConnections().put(c4, 10);
c2.getConnections().put(c3, 18);
c2.getConnections().put(c4, 26);
c3.getConnections().put(c2, 18);
c3.getConnections().put(c1, 7);
c4.getConnections().put(c2, 26);
c4.getConnections().put(c1, 10);
c4.getConnections().put(c5, 5);
c5.getConnections().put(c1, 3);
c5.getConnections().put(c4, 5);
c6.getConnections().put(c1, 9);
//在地图中添加城市信息
cm.getCities().add(c1);
cm.getCities().add(c2);
cm.getCities().add(c3);
cm.getCities().add(c4);
cm.getCities().add(c5);
cm.getCities().add(c6);
Tree tree = new Tree();
tree.setRoot(tree.createTree(tree.getRoot(), c1, c4, c1.getName(),0));
System.out.println("最短路径:"+tree.getPath());
System.out.println("最短路径:"+tree.getMinCost());
}
}
计算汉到沪的最小耗费结果