旅行售货商问题 -- 回溯法

/*旅行售货员问题回溯法*/
#include<stdio.h>
#define N 4
int cc,//当前路径费用
	bestc;//当前最优解费用
int a[N+1][N+1];//邻接矩阵,存放图的信息
int bestx[N+1];//当前最优解
int x[N+1];//当前解
void inputAjac()
{
	int i,j;
	printf("输入大于0的值表示有边,小于0表示无边:\n");
	for(i=1;i<=N;i++)
	{
		for(j=i+1;j<=N;j++)
		{
			printf("请输入第%d个城市到第%d个城市所需路费为:",i,j);
			scanf("%d",&a[i][j]);
			a[j][i]=a[i][j];
		}
	}
}
void backtrack(int i)
{
	if(i==N)
	{
		if(a[x[N-1]][x[N]]>0&&a[x[N]][x[1]]>0)
		{
			if(bestc<0||bestc>cc+a[x[N-1]][x[N]]+a[x[N]][x[1]])
			{
				int j;
				for(j=1;j<=N;j++)
				{
					bestx[j]=x[j];
					bestc=cc+a[x[N-1]][x[N]]+a[x[N]][x[1]];
				}
			}
		}
	}
	else
	{
		int j;
		for(j=i;j<=N;j++)
		{
			if(a[x[i-1]][x[j]]>0)
			{
				if(bestc<0||bestc>cc+a[x[i-1]][x[j]]+a[x[j]][x[1]])
				{
					int temp;
					cc+=a[x[i-1]][x[j]];
					temp=x[i];
					x[i]=x[j];
					x[j]=temp;
					backtrack(i+1);
					temp=x[i];
					x[i]=x[j];
					x[j]=temp;
					cc-=a[x[i-1]][x[j]];
				}
			}
		}
	}
}
int tsp()
{
	//初始化
	int i;
	for(i=1;i<=N;i++)
	{
		x[i]=i;
	}
	cc=0,bestc=-1;
	inputAjac();
	backtrack(2);
	return bestc;
}
void output()
{
	int i;
	for(i=1;i<=N;i++)
	{
		printf("%4d",bestx[i]);
	}
	printf("%4d",bestx[1]);
	printf("\n");
}
void main()
{
	printf("走%d个城市最少路费为:%d",N,tsp());
	printf("\n");
	printf("走法为:");
	output();
}

  

原文地址:https://www.cnblogs.com/zili/p/9906422.html

时间: 2024-10-30 07:13:25

旅行售货商问题 -- 回溯法的相关文章

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

回溯法小实例

1.图的m着色问题: 1 /* 2 *问题描述:给定无向连通图G和m种不同的颜色.用这些颜色为图G的各个顶点着色,每个顶点着一种颜色.是否有一种着色法使G中每条边的两个顶点着不同的颜色. 3 * 这个问题是图的m可着色判定问题.若一个图最少需要m中颜色才能使图中每条边连接的2个顶点着不同的颜色,则称这个数m为该图的色数. 4 *算法分析:给定图G=(V,E)和m中颜色,如果这个图不是m可着色,给出否定回答:如果这个图是m可着色的,找出所有不同的着色法. 5 * 回溯法+子集树 6 * 问题的解空

回溯法与分支限界

回溯法 1.有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法. 2.回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法.这种方法适用于解一些组合数相当大的问题. 3.回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含(剪枝过程),则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯:否则,进入该子树,继续按深度优先策略搜索. 问

回溯法 子集树和排序树

当所给问题是从n个元素的集合S中找出满足某种性质的子集时,解空间为子集树.例如:0-1背包问题 当所给问题是从n个元素的集合S中找出满足某种性质的排列时,解空间为排列树.例如:旅行售货员问题 回溯法搜索子集树算法描述为: void backtrack(int  t) { if(t>n) output(x); else for(int i=0; i<=1; i++) { x[t] = i; if(constraint(t) && bound(t)) backtrack(t+1);

回溯法的解空间表示方法

回溯法解题时通常包含3个步骤: 1. 针对所给问题,定义问题的解空间: 2. 确定易于搜索的解空间结构: 3. 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索. 对于问题的解空间结构通常以树或图的形式表示,常用的两类典型的解空间树是子集树和排列树.当所给的问题是从n个元素的集合S中找到S满足某种性质的子集时,相应的解空间树称为子集树.例如,n个物品的0-1背包问题所对应的解空间树是一棵子集树,这类子集树通常有2**n个叶结点,遍历子集树的算法需要O(2**n)计算时间.当所给问题

回溯法理解

回溯法 基本思想: 构建问题的解空间树,在其解空间树中,从根节点出发,进行深度优先搜索.在搜索过程中,对解空间 树的每个结点进行判断,判断该结点是否包含问题的解,若肯定不包含,则跳过对以该结点为根的子树的 搜索,逐层向其祖先结点回溯.否则,则进入该子树,继续按深度优先策略搜索. 步骤: 1.针对所给问题,定义其解空间 2.确定易于搜索的解空间结构 3.深度优先搜索其解空间,并在搜索过程中用剪枝函数避免无效搜索 剪枝: 回溯法搜索空间树时,常用限界函数和约束函数避免无效搜索,其中约束函数将不满足约

算法设计与分析——回溯法算法模板

以深度优先方式系统搜索问题解的算法称为回溯法.在回溯法中,解空间树主要分为了四种子集树.排列树.n叉树和不确定树. 在<算法设计与分析课本>中介绍了11个回溯法的问题样例,这里根据解空间树的类型做一个分类. 子集树 装载问题 符号三角形问题 0-1背包问题 最大团问题 算法模板: void backtrack(int t) { if(搜索到叶子结点) { return; } for(i=0; i<=1; i++) //01二叉树 { if(满足约束函数和限界函数)//剪枝 { backt

张三木教你理解回溯法

回溯法 回溯法(搜索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标.但当搜索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择.这种走不通就退回再走的技术为回溯法.而满足回溯条件的某个状态的点称为"回溯点". 回溯法问题的框架 问题的解空间 复杂问题常常有很多的可能解,这些可能的解构成了问题的解空间.解空间就是进行穷举的搜索空间,所以解空间中应该包含所有的可能解,且至少应该包含问题的一个最优解.例如:对于有n个物品的0/1背包问题,当n=3时,其解

五大常用算法之四:回溯法

(转自:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html) 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 许