⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 回溯法解旅行售货员问题.cpp

📁 算法分析中
💻 CPP
字号:
/*
旅行售货员问题
1.算法描述
旅行售货员问题的解空间是一棵排列树。对于排列树的回溯搜索与生成1,2,。。。,n
的所有排列的递归算法Perm类似。设开始时x=[1,2,...n],则相应的排列树由x[1:n]的所有
排列构成
如果每个活动接点有m种选择的一个排列就叫作完全m叉树
如果是一个全排列,就叫做排列树
在递归函数Backtrack中,当i==n,当前扩展结点是排列树的叶结点的父结点。此时
算法检测图G是否存在一条从顶点x[n-1]到顶点x[n]的边和一条从顶点x[n]到顶点1的
边。如果这两条边都存在,则找到一条旅行售货员回路。此时算法还需要判断这条回路
的费用是否优于已经找到的当前最优回路的费用bestc。如果是,则必须更新当前最优值bestc
和当前最优解bestx。
当i<n时,当前扩展结点位于排列树的第i-1层。图G中存在从顶点x[i-1]到顶点x[i]的边时,
x[1:i]构成图G的一条路径,且当x[1:i]的费用小于当前最优值时算法进入排列树的第i层
,否则将剪去相应的子树。算法中用变量cc记录当前路径x[1:i]的费用。
*/
template<class Type>
class Traveling
{
	friend Type TSP(int **,int [],int,Type);
	private:
		void Backtrack(int i);
		int n;
		//图G的顶点数
		int *x;
		//当前解
		int *bestx;
		//当前最优解
		Type **a;
		//图G的邻接矩阵
		int cc;
		//当前费用
		int bestc;
		//当前最优值
		int NoEdge;
		//无边标记
};

template<class Type>
void Traveling<Type>::Backtrack(int i)
{
	if ( i == n )
	{
		if ( a[x[n-1]][x[n]] != NoEdge
			&& a[x[n]][1] != NoEdge
			&& ( cc + a[x[n-1]][x[n]] + a[x[n]][1] < bestc
			|| bestc == NoEdge ) )
		{
			for( int j = 1; j <= n; ++j )
			{
				bestx[j] = x[j];
			}
			bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1];
		}
	}
	else
	{
		for( int j = i; j <= n; ++j )
		{
			if ( a[x[i-1]][x[j]] != NoEdge
				&& (cc + a[x[i-1]][x[i]] < bestc 
				|| bestc == NoEdge ) )
			{
				//搜索子树
				int t;
				t = x[i];
				x[i] = x[j];
				x[j] = t;
				cc += a[x[i-1]][x[i]];
				Backtrack(i+1);
				cc -= a[x[i-1]][x[i]];
				t = x[i];
				x[i] = x[j];
				x[j] = t;
				//回到上层的时候恢复原来的值

			}
		}
	}
}

template<class Type>
Type TSP(Type **a,int v[],int n,Type NoEdge)
{
	Traveling<Type> Y;
	//初始化Y
	Y.x = new int[n+1];
	for( int i = 1; i <= n; ++i )
	{
		Y.x[i] = i;
	}
	Y.a = a;
	Y.n = n;
	Y.bestc = NoEdge;
	Y.bestx = v;
	Y.NoEdge = NoEdge;
	//
	Y.Backtrack(2);
	//搜索从2开始的全排列
	delete[] Y.x;
	return Y.bestc;
}
/*
不考虑bestx所需要的计算时间,则Backtrack需要O((n-1)!)计算时间。由于
算法Backtrack在最坏情况下可能需要更新O((n-1)!)次当前最优解bestx,每次更新
bestx需O(n)计算时间,从而整个算法的计算时间复杂性为O(n!)
*/
int main()
{
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -