【笔记】最短Hamilton路径 (图论,状压dp)

本文深入探讨了求解带权无向图中从起点到终点的最短Hamilton路径问题,采用动态规划方法,详细解释了状态转移方程及其实现细节。

最短Hamilton路径是指:

给定一张n (n<=20)个点的带权无向图,点从0~n-1标号,求起点0到终点n-1的最短Hanmilton路径

eg: Hamilton路径的定义是从0到n-1不重不漏地经过每个点恰好一次

 

ll w[N][N];
ll hamilton (int n)
{
	int dp[1<<n][n]; // dp[i][j] 表示 第i个状态 当前走到第j个点时的最短路径长度 
	memset (dp, 0x3f, sizeof(dp)); // 初始化dp为最大值 
	dp[1][0] = 0; //起点开始的路径长度为0 
	for (int i = 1; i < (1 << n); ++i)
		for (int j = 0; j < n; ++j)
			if (i >> j & 1) //我们要求现在走到第j个点 则i状态中第j位为1 
				for (int k = 0; k < n; ++k)
					if (i >> k & 1 && w[k][j] != 0) //如果是从第k个点走到j 那么状态中第k位肯定为1 并且判断是否存在这么一条边 
						dp[i][j] = min(dp[i][j], dp[i^(1<<j)][k] + w[k][j]); // dp[i][j]的上一个状态中j肯定不能被经过 即i状态中j位为0 
	return dp[(1<<n)-1][n-1];
}

 

### Hamilton 路径的算法与图论分析 Hamilton 路径问题在图论中是一个经典问题,其目标是在一个加权图中找到一条从起点到终点的路径,该路径恰好经过每个顶点一次,并且路径的总权重最小。该问题属于 NP-Hard 问题,因此对于大规模图,通常需要使用动态规划等优化策略来求解。 #### 缩动态规划方法 Hamilton 路径可以通过缩动态规划来高效求解。缩的核心思想是使用二进制数来表示已经访问过的顶点集合,从而减少态存储的空间和计算复杂度。 定义态 `dp[i][j]` 表示当前处于顶点 `j`,并且已经访问过的顶点集合由二进制数 `i` 表示时的路径长度。初始态为 `dp[1][0] = 0`,表示从起点 `0` 出发,仅访问了自己。 态转移方程为: ```python dp[i][j] = min(dp[i ^ (1 << j)][k] + weight[k][j]) for all k in i if k != j ``` 其中: - `i` 是一个二进制数,表示已访问的顶点集合。 - `j` 是当前所在的顶点。 - `weight[k][j]` 是顶点 `k` 到顶点 `j` 的边权值。 - `i ^ (1 << j)` 表示从集合 `i` 中移除顶点 `j`。 终答案是 `min(dp[(1 << n) - 1][j] + weight[j][n-1])`,其中 `n` 是图中顶点的数量,`j` 遍历所有可能的中间顶点。 #### 图论中的应用 在图论中, Hamilton 路径问题与旅行商问题(TSP)密切相关,但不同之处在于 TSP 要求路径形成一个回路,而 Hamilton 路径只需要从起点到终点。该问题在实际应用中广泛存在,例如电路设计、物流路径规划等领域。 #### 示例代码 以下是一个实现 Hamilton 路径的 Python 示例代码: ```python n = int(input()) weight = [list(map(int, input().split())) for _ in range(n)] # 初始化动态规划表 dp = [[float('inf')] * n for _ in range(1 << n)] dp[1][0] = 0 # 起点为顶点0 # 态转移 for i in range(1 << n): for j in range(n): if (i >> j) & 1: for k in range(n): if (i ^ (1 << j)) >> k & 1: dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + weight[k][j]) # 终结果 print(dp[(1 << n) - 1][n-1]) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值