高德地圖之路線規劃 多點路線規劃路線最短原則之二 TSP算法

經過這段時間的使用和研究,我發現點和點之間的最短路線並不是最優的。針對所有點的組合可能,
得到的最短路線纔是最好的(也就是TSP方法),然後再結合點對點之間的距離進行比較,得到的纔是相對最優方案。

舉例:A、B、C、D四個點。自由組合,得到最短路線方案。
所有的組合路線應該是(此處我們只需要四個點的組合)
ABCD
ABDC
ACBD
ACDB
ADCB
ADBC
BACD
BADC
BCAD
BCDA
BDCA
BDAC
CBAD
CBDA
CABD
CADB
CDAB
CDBA
DBCA
DBAC
DCBA
DCAB
DACB
DABC
得到的結果是這樣麼多(24條路線);
n!=(n-1)!*n

A、B、C、D四個點。設定一個點爲起點(我設置A爲起點),不設定終點,得到最短路線方案
BCD
BDC
CBD
CDB
DCB
DBC

A爲起點,BCD自由組合,則有6條路線;
現在對6個結果進行最短距離排序;根據高德的路線規劃,得到一個最短路線;

然後對着一條路線進行規劃,你會得到一個路線的所有途徑點的集合,然後對途徑地點之間的距離進行排序
,然後調整路線,進行顯示就可以了。

下面開始上代碼;

// 添加數據

if (start == null) {
                Toast.makeText(this, "請選擇起點", Toast.LENGTH_SHORT).show();
                return;
            }
            if (throughList.size() == 0) {
                Toast.makeText(this, "請添加途徑點", Toast.LENGTH_SHORT).show();
                return;
            }
            startTip = new LatLonPoint(new BigDecimal(start.getLat()).doubleValue(), new BigDecimal(start.getLon()).doubleValue());
            sortPoint(throughList, startTip);
  // 組合點,得到所有可能的路線
private void sortPoint(List<Bean> allList,LatLonPoint start) {
    String s = "";
    for (int i = 0; i < allList.size(); i++) {
        s += allList.get(i).getId();
    }
    char[] result = s.toCharArray();
    routes = TSPUtil.sortPoint(result, 0);
    for (int i = 0; i < routes.size(); i++) {
        plan(allList, routes.get(i),start);
    }
}
static List<String> list = new ArrayList<>();
public static List<String> sortPoint(char result[], int k){
    String s = "";
    if(k==result.length){
        for(int i=0;i<result.length;i++){
            s += result[i];
        }
        list.add(s);
        return list;
    }
    for(int i=k;i<result.length;i++){
        //交換
        {char t = result[k];result[k] = result[i];result[i] = t;}
        //遞歸,下一個數去排列
        sortPoint(result,k+1);
        //再歸位數據
        {char t = result[k];result[k] = result[i];result[i] = t;}
    }
    return list;
}

// 開始路線規劃

 private void plan(List<Bean> points,String s,LatLonPoint start) {
        char[] array = s.toCharArray();
        for (int i = 0; i < array.length; i++) {
            through1.clear();
            through2.clear();
            // 得到策略後所有點的集合
            for (int j = 0; j < points.size(); j++) {
                if (points.get(j).getId().equals(String.valueOf(array[i]))) {
                    through2.add(points.get(j));
                }
            }
            // 填充規劃集合
            for (int j = 0; j < through2.size(); j++) {
                through1.add(new LatLonPoint(new BigDecimal(through2.get(j).getLat()).doubleValue(),new BigDecimal(through2.get(j).getLon()).doubleValue()));
            }
        }
        AMapUtil.doRoutePlan(start,through1.get(through1.size()-1),through1,this,this);
    }
// 得到最短距離,根據最短距離得到最短路線,並展示地圖
 
 @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
        if (i == 1000) {
            if (driveRouteResult != null && driveRouteResult.getPaths() != null) {
                disList.add(Double.valueOf(driveRouteResult.getPaths().get(0).getTollDistance()));
                if (minDistance == 0) {
                    minDistance = driveRouteResult.getPaths().get(0).getTollDistance();
                }else {
                    if (minDistance > driveRouteResult.getPaths().get(0).getTollDistance()) {
                        minDistance = driveRouteResult.getPaths().get(0).getTollDistance();
                    }
                }

                if (disList.size() == routes.size()) {
                    for (int j = 0; j < disList.size(); j++) {
                        if (minDistance == disList.get(j)) {
                            if (throughList.size() > j && throughList.get(j) != null) {
                                minDisRoute = throughList.get(j);
                                Bundle bundle = new Bundle();
                                bundle.putString("start",GsonInstance.getInstance().toJson(start));
                                bundle.putString("end",GsonInstance.getInstance().toJson(throughList.get(0)));
                                bundle.putSerializable("list", (Serializable) throughList);
                                startActivity(ShowRouteActivity.class,bundle,true);
                                break;
                            }
                        }
                    }
                }
                Log.d(TAG, "onDriveRouteSearched: 規劃成果="+minDistance);
            }
        }
    }

下面就不說了,上一篇都已經講到。傳送陣

後面會有下載鏈接。完整demo,僅供參考。

完整demo

可下載demo運行測試。歡迎評論/私信

發佈了72 篇原創文章 · 獲贊 80 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章