經過這段時間的使用和研究,我發現點和點之間的最短路線並不是最優的。針對所有點的組合可能,
得到的最短路線纔是最好的(也就是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運行測試。歡迎評論/私信