TSP之動態規劃找最優解

動態規劃解決TSP問題
    假設p0,p1,p2...pn-1是從p0到pn-1的最短路徑,則p1,p2...pn-1也是最短路徑。
    pi:點i
    d(i,v):從i經過點集合v所有點的最短路徑長度
    c(i,j):從i到j的距離花費
    目的:求d(0,v)最短路徑和長度
    v=空集, d(0,v)=0
    v不等於空集,d(0,v)=min{c(0,i)+d(i,v-{i})} i屬於v

 

#include <windows.h>
#include <iostream>
#include <set>
#include "config.h"

using namespace std;
/*
    動態規劃解決TSP問題
    假設p0,p1,p2...pn-1是從p0到pn-1的最短路徑,則p1,p2...pn-1也是最短路徑。
    pi:點i
	d(i,v):從i經過點集合v所有點的最短路徑長度
	c(i,j):從i到j的距離花費
	目的:求d(0,v)最短路徑和長度
	v=空集, d(0,v)=0
	v不等於空集,d(0,v)=min{c(0,i)+d(i,v-{i})} i屬於v


*/
typedef struct _MyPoint
{
	double GetDistance(const _MyPoint& point)
	{
		int delta_x = abs(this->x-point.x);
		int delta_y = abs(this->y - point.y);
		return sqrt(delta_x*delta_x + delta_y*delta_y);
	}
	int x;
	int y;
	
}*LPMYPOINT;
std::vector<LPMYPOINT> points;
double cost[100][100];

double CalcShortestDis(int i, const std::set<int>& VPoints,std::vector<int>& path)  // d(i,v)
{
	if (VPoints.size() == 0)
	{
		return 0;
	}
	std::set<int>::iterator it = VPoints.begin();
	double tempmin = 9999999999.0;
	for (; it != VPoints.end(); ++it)
	{
		int nextpoint = *it;
		std::set<int> nextVPoints;
		nextVPoints.insert(VPoints.begin(), VPoints.end());
		nextVPoints.erase(nextpoint);
		std::vector<int> temppath;
		double dis = cost[i][nextpoint] + CalcShortestDis(nextpoint, nextVPoints, temppath);
		if (dis < tempmin)
		{
			path.clear();
			path.push_back(nextpoint);
			for (std::vector<int>::iterator tempIt = temppath.begin(); tempIt != temppath.end(); ++tempIt)
			{
				path.push_back(*tempIt);
			}
			tempmin = dis;
		}
	}
	return tempmin;
}
int main()
{
	int nStartTime = GetTickCount();
	memset(cost, 0x00, 100 * 100);
	int num = 0,i=0,j=0;
	num = atoi(getConfig("config", "num").c_str());
	
	char szTemp[10];
	while (i<num)
	{
		memset(szTemp,0x00,10);
		sprintf(szTemp,"p%d",i);
		std::vector<std::string> vec;
		Split(getConfig("points", szTemp), ",", vec);
		LPMYPOINT point = new _MyPoint();
		point->x = atoi(vec[0].c_str());
		point->y = atoi(vec[1].c_str());
		points.push_back(point);
		i++;
	}
	min = 0;
	for (i = 0; i < num; i++)
	{
		for (j = 0; j < num; j++)
		{
			cost[i][j] = points[i]->GetDistance(*points[j]);;
		}
	}
	
	/*for (i = 0; i < num-1; i++)
	{
		min += cost[i][i+1];
	}*/
	std::set<int> VPoints;
	for (i = 1; i < num; i++)
	{
		VPoints.insert(i);
	}
	std::vector<int> path;
	double dis = CalcShortestDis(0, VPoints, path);
	cout << "最短路徑長度:" << dis << endl;
	cout <<"最短路徑:" << endl;
	for (i = 0; i < path.size(); i++)
	{
		cout <<"p"<< path[i] << ",";
	}
	cout << endl;
	int nEndTime = GetTickCount();
	cout << "耗時:" << nEndTime - nStartTime << "ms"<< endl;

	for (i = 0; i < points.size(); i++)
	{
		delete points[i];
	}
	system("pause");
	return 0;
}

 

config配置文件中輸入點數和點的x、y位置,截圖如下:

 

工程代碼下載:鏈接:https://pan.baidu.com/s/1O3nVpn_Z-3gQIljsNdXx-g 
提取碼:6agh

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章