package com.demo.navtogether.utils; import android.graphics.Point; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; /** * My father is Object, ites purpose of 迪杰斯特拉算法 * * @purpose Created by Runt (qingingrunt2010@qq.com) on 2020-12-23. */ public class DijkstraUtils { HashMap distances;//每个点的信息集合 public DijkstraUtils(HashMap distances) { this.distances = distances; } public ArrayList excute(PathPlan.Place start ){ return excute(start,null); } /** * 执行算法 * @param start 起点 * @param end */ public ArrayList excute(PathPlan.Place start, PathPlan.Place end){ PathPlan.Distance startDis = distances.get(start); PathPlan.Distance endDis = end == null ? null:distances.get(end); deletePlace(start); if(end != null){//如果有终点则去除 deletePlace(end); } ArrayList places = new ArrayList<>(); places.add(start); while (distances.size()>0){//循环遍历 PathPlan.Place nearWay = findNearWay(startDis);//获取与其他点的最短个那一个 startDis = distances.get(nearWay);//距离信息 deletePlace(nearWay);//从集合中删除,避免下次循环再次出现该地点 places.add(nearWay);//添加到线路集合记录中 } if(end != null){//如果有终点则最后追加 end.distance = endDis.distanceMap.get(places.get(places.size()-1)); places.add(end); } return places;//返回规划的路线集合 } /** * 清除位置 * @param place */ private void deletePlace(PathPlan.Place place){ distances.remove(place); for(PathPlan.Place p : distances.keySet()){//将与之相关的距离也清除 distances.get(p).distanceMap.remove(place); } } /** * 寻找最近的位置 * @return */ public PathPlan.Place findNearWay(PathPlan.Distance distance){ PathPlan.Place place = null; double dist = -1; for(PathPlan.Place temp : distance.distanceMap.keySet()){//循环遍历 double placeDist = distance.distanceMap.get(temp);//对应位置距离; placeDist = placeDist - placeDist*temp.priority/100;//计算权重 if(dist == -1){ dist = placeDist; temp.distance = dist; place = temp; }else if( dist > placeDist){//若小于之前对比的数据 dist = placeDist; temp.distance = dist; place = temp; } } return place; } public static void main(String[] args) { ArrayList places = new ArrayList<>(); places.add(new PathPlan.Place("A",random(),0)); places.add(new PathPlan.Place("B",random(),0)); places.add(new PathPlan.Place("C",random(),0)); places.add(new PathPlan.Place("D",random(),0)); places.add(new PathPlan.Place("E",random(),0)); places.add(new PathPlan.Place("F",random(),0)); Map map = new HashMap(); map.put(places.get(2),"hehe"); System.out.println("2"+map.get(places.get(2))); ArrayList excute = new DijkstraUtils(PathPlan.intPoints(places)).excute(places.get(2)); for(int i = 0 ; i < excute.size() ; i ++){ System.out.println(excute.get(i)+" 距离:"+(i == excute.size() -1?"":TriangleUtils.getLengthOfSide(excute.get(i).point,excute.get(i+1).point)) +" "+excute.get(i).distance); } } ArrayList> arrayLists = new ArrayList<>();//路线记录 /** * 自定义规划路线算法 * @param start 起始地点 * @param end 末尾地点 */ public ArrayList> initCustomPathPlan( PathPlan.Place start,PathPlan.Place end){ arrayLists.clear();//清空记录 ArrayList places = new ArrayList<>(distances.keySet());//所有地点集合 for(int i=1;i<=places.size();i++){ sortPlace(places,new ArrayList(),i,start,end); } return arrayLists; } //最短距离 double dist = -1; /** * 组合 * @param datas 地点数据 * @param target 整理的新路线 * @param num 循环的下标位置,即路线规划的地点数量 * @param start 起始地点 * @param end 末尾地点 */ private void sortPlace(ArrayList datas, ArrayList target,int num,PathPlan.Place start,PathPlan.Place end) { if (target.size() == num) { ArrayList newDatas = new ArrayList( ); ArrayList places = new ArrayList<>(distances.keySet());//所有地点集合 //数量不够,起始和末尾不对应,则不再执行 if(places.size()> num || start!=null && !target.get(0).equals(start) || end!=null && !target.get(target.size()-1).equals(end)){ return; } double tempDist = 0 ; for (PathPlan.Place obj : target) { //复制对象 PathPlan.Place place = new PathPlan.Place(obj); //距离 place.distance = newDatas.size() == 0 ?0: distances.get(obj).distanceMap.get(newDatas.get(newDatas.size() - 1)); tempDist+=place.distance; newDatas.add(place); } //记录最短距离 if(dist == -1 || dist >= tempDist){ if(dist > tempDist){ arrayLists.clear();//清除之前的数据 } dist = tempDist; arrayLists.add(newDatas); }else if(dist < tempDist){ //当前距离不是最短 return; } return; } for (int i = 0; i < datas.size(); i++) { ArrayList newDatas = new ArrayList(datas); ArrayList newTarget = new ArrayList(target); newTarget.add(newDatas.get(i)); newDatas.remove(i); sortPlace(newDatas, newTarget,num,start,end); } } /** * 创建一个随机位置 坐标在0-100内 * @return */ public static Point random(){ Point point = new Point(); point.x = (int) (Math.random()*100); point.y = (int) (Math.random()*100); return point; } }