import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Kevin
* @data 4/24/2022 8:48 PM
* @description Agv小车最短路径计算
**/
public class AgvLoader {
public static void main(String[] args) {
calculate(allNode.get(2),allNode.get(12),new ArrayList<Integer>(),0);
System.out.println("最佳路径是");
System.out.println(bestLoad);
System.out.println("最佳路径长度是");
System.out.println(bestLen);
}
/**
* 地图上的点实体类,有向图实现
*/
public static class Node{
// 节点标识
public Integer id;
// 可以到达的节点标识集合
public List<Integer> next;
public Node(Integer id, List<Integer> next) {
this.id = id;
this.next = next;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Integer> getNext() {
return next;
}
public void setNext(List<Integer> next) {
this.next = next;
}
}
// 全局点位Map
private static Map<Integer,Node> allNode = new HashMap<>();
// 全局相邻点位的路径和 key是两相邻点位map
private static Map<HashMap<Integer,Integer>,Integer> allLen = new HashMap<>();
// 记录最佳路径集合
private static List<Integer> bestLoad = new ArrayList<>();
// 记录最佳路径的路径和
private static Integer bestLen = Integer.MAX_VALUE;
static {
// 初始化路径map
ArrayList<Integer> integers1 = new ArrayList<>();
integers1.add(2);
integers1.add(5);
allNode.put(1,new Node(1,integers1));
ArrayList<Integer> integers2 = new ArrayList<>();
integers2.add(1);
integers2.add(3);
allNode.put(2,new Node(2,integers2));
ArrayList<Integer> integers3 = new ArrayList<>();
integers3.add(2);
integers3.add(6);
integers3.add(4);
allNode.put(3,new Node(3,integers3));
ArrayList<Integer> integers4 = new ArrayList<>();
integers4.add(3);
integers4.add(8);
allNode.put(4,new Node(4,integers4));
ArrayList<Integer> integers5 = new ArrayList<>();
integers5.add(1);
integers5.add(6);
integers5.add(9);
allNode.put(5,new Node(5,integers5));
ArrayList<Integer> integers6 = new ArrayList<>();
integers6.add(5);
integers6.add(7);
integers6.add(9);
integers6.add(11);
allNode.put(6,new Node(6,integers6));
ArrayList<Integer> integers7 = new ArrayList<>();
integers7.add(6);
integers7.add(8);
allNode.put(7,new Node(7,integers7));
ArrayList<Integer> integers8 = new ArrayList<>();
integers8.add(4);
integers8.add(7);
integers8.add(12);
allNode.put(8,new Node(8,integers8));
ArrayList<Integer> integers9 = new ArrayList<>();
integers9.add(5);
integers9.add(10);
allNode.put(9,new Node(9,integers9));
ArrayList<Integer> integers10 = new ArrayList<>();
integers10.add(9);
integers10.add(11);
allNode.put(10,new Node(10,integers10));
ArrayList<Integer> integers11 = new ArrayList<>();
integers11.add(10);
integers11.add(12);
allNode.put(11,new Node(11,integers11));
ArrayList<Integer> integers12 = new ArrayList<>();
integers12.add(8);
integers12.add(11);
allNode.put(12,new Node(12,integers12));
// 初始化点位距离map
allLen.put(creatAllLenKey(1,2),50);
allLen.put(creatAllLenKey(2,3),5);
allLen.put(creatAllLenKey(6,3),5);
allLen.put(creatAllLenKey(6,11),5);
allLen.put(creatAllLenKey(3,4),5);
allLen.put(creatAllLenKey(4,8),5);
allLen.put(creatAllLenKey(8,7),5);
allLen.put(creatAllLenKey(7,6),5);
allLen.put(creatAllLenKey(6,5),5);
allLen.put(creatAllLenKey(6,9),5);
allLen.put(creatAllLenKey(5,1),5);
allLen.put(creatAllLenKey(5,9),5);
allLen.put(creatAllLenKey(9,10),5);
allLen.put(creatAllLenKey(10,11),5);
allLen.put(creatAllLenKey(11,12),5);
allLen.put(creatAllLenKey(12,8),5);
}
/**
* 计算最短路径
* @param start 起点
* @param end 终点
* @param currentThrough 当前经过的点位集合
* @param currentLength 当前经过的点位路径长度
*/
public static void calculate(Node start, Node end, List<Integer> currentThrough, Integer currentLength){
// 边界判断
if (start == null || end == null){
return;
}
// 如果当前路径和大于已经找到的最小路径和 那就可以直接返回了
if (currentLength >= bestLen){
return;
}
// 找到了
if (start == end){
currentThrough.add(end.getId());
System.out.print("找到了-->");
System.out.print(currentThrough);
System.out.print("路径和是--->");
System.out.println(currentLength);
// 保存最佳路径 前面已经判断,这里无需判断
bestLoad = currentThrough;
bestLen = currentLength;
return;
}
// 这个判断要放到最下面
if (start.next == null || start.next.size() == 0){
return;
}
// 又回到经过的点了,直接返回
if (currentThrough.contains(start.getId())){
return;
}
// 将start存入当前经过的点位集合
currentThrough.add(start.getId());
// 递归寻找下面在全局经过点位里不存在的点
List<Integer> noThrough = new ArrayList<>();
for (Integer integer : start.next) {
if (!currentThrough.contains(integer)){
noThrough.add(integer);
}
}
// 如果所有点都已经经过了,那就直接返回
if (noThrough.size() == 0){
return;
}else {
for (Integer integer : noThrough) {
// 这里需要拷贝一份进行传递,不能传入引用地址
calculate(allNode.get(integer),end,copyList(currentThrough),currentLength + getLen(start.getId(),integer));
}
}
}
/**
* 创建allLen的key
* @param n1
* @param n2
* @return
*/
public static HashMap<Integer,Integer> creatAllLenKey(int n1, int n2){
HashMap<Integer, Integer> map = new HashMap<>();
map.put(n1,n2);
return map;
}
/**
* 获取两点间的距离
* @param n1
* @param n2
* @return
*/
public static Integer getLen(int n1, int n2){
HashMap<Integer, Integer> key1 = creatAllLenKey(n1, n2);
Integer value1 = allLen.get(key1);
if (value1 != null){
return value1;
}else {
return allLen.get(creatAllLenKey(n2, n1)) ;
}
}
/**
* List拷贝
* @param list
* @return
*/
public static List<Integer> copyList(List<Integer> list){
ArrayList<Integer> copy = new ArrayList<>();
copy.addAll(list);
return copy;
}
}
10-20
714
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-16
4696
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)