exact algorithm 精确算法

本文解释了精确算法的概念,重点讨论了其在最优化问题中的应用,特别是对于NP-hard问题,以及与近似算法的区别。文章还举例说明了在定点覆盖问题中精确算法与近似算法的不同表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:
The phrase exact algorithm is used when talking about an algorithm that always finds the optimal solution to an optimization problem. (As opposed to heuristics that may sometimes produce worse solutions. A subset of these are the approximation algorithms – those are the ones where we can prove a guaranteed bound on the ratio between the optimal solution and the solution produced by the algorithm.)

For hard optimization problems (especially NP-hard ones) it is often the case that there are some polynomial-time approximation algorithms, but the best known exact algorithms require exponential time.

For example, there is a simple polynomial-time 2-approximation algorithm for Vertex Cover, but if you need an exact algorithm, the best one we know runs in, IIRC, O(1.1889 n ) . (Vertex Cover is also fixed-parameter tractable, but that’s a topic for another day.)

精确算法是指在最优化问题中,一个算法总是能找到最优解,(是相对于启发式算法来说的,启发式算法往往找到的不是最优解,启发式算法的一个子集是近似算法,近似算法的结果与最优解的比例有一个约束值,相当于误差范围,这个约束值是可以被证明的。)

NP hard问题往往有很多时间复杂度为多项式的近似算法,但是对应的精确算法的时间复杂度往往是指数级别的。

例如在定点覆盖问题中,有近似度为2的多项式复杂度近似算法,但是精确算法的时间复杂度为 O(1.1889n)

原地址:http://www.quora.com/What-is-the-definition-of-exact-algorithm-in-Computer-Science

### 精确算法的定义与实现 精确算法Exact Algorithm)是指能够在有限时间内找到全局最优解的一类算法。这类算法的特点在于其解决方案总是满足问题的所有约束条件并达到最佳目标值,尽管可能需要较高的时间和空间复杂度[^1]。 #### 分支定界法(Branch and Bound) 分支定界法是一种典型的精确算法,广泛应用于组合优化问题中。该方法通过构建一棵搜索树,在每一步选择最有希望的部分继续探索,并利用界限剪枝来减少不必要的计算量。其实现的关键点包括: - **节点的选择策略**:可以选择最小下界的节点优先扩展。 - **边界设置**:合理设定上下界以尽早排除不可能成为最优解的情况。 以下是基于 Python 的简单分支定界框架示例: ```python class Node: def __init__(self, level, profit, weight, bound): self.level = level self.profit = profit self.weight = weight self.bound = bound def knapsack_branch_and_bound(capacity, weights, profits): n = len(weights) q = [] u = Node(-1, 0, 0, calculate_bound(0, capacity, weights, profits)) best_node = u while True: if not q: break u = q.pop() if u.level >= (n - 1): continue v = Node(u.level + 1, u.profit + profits[u.level + 1], u.weight + weights[u.level + 1], 0) if v.weight <= capacity and v.profit > best_node.profit: best_node = v v.bound = calculate_bound(v.level + 1, capacity - v.weight, weights, profits) if v.bound > best_node.profit: q.append(v) w = Node(u.level + 1, u.profit, u.weight, 0) if w.weight <= capacity: w.bound = calculate_bound(w.level + 1, capacity - w.weight, weights, profits) if w.bound > best_node.profit: q.append(w) return best_node.profit def calculate_bound(level, remaining_capacity, weights, profits): total_profit = 0 j = level totweight = 0 while j < len(weights) and totweight + weights[j] <= remaining_capacity: totweight += weights[j] total_profit += profits[j] j += 1 k = j if k < len(weights): total_profit += (remaining_capacity - totweight) * (profits[k] / weights[k]) return total_profit ``` 此代码展示了如何使用分支定界法求解背包问题,其中 `calculate_bound` 函数用于估算当前路径的最大潜在收益以便决定是否进一步深入搜索。 #### 动态规划(Dynamic Programming) 动态规划也是一种重要的精确算法形式,尤其适合于具有重叠子问题特性的优化问题。它通过存储中间状态的结果避免重复计算,从而显著提高效率。例如经典的最长公共子序列(Longest Common Subsequence, LCS)问题可以通过如下方式解决: ```python def lcs_length(X, Y): m = len(X) n = len(Y) L = [[None]*(n+1) for i in range(m+1)] for i in range(m+1): for j in range(n+1): if i == 0 or j == 0 : L[i][j] = 0 elif X[i-1] == Y[j-1]: L[i][j] = L[i-1][j-1]+1 else: L[i][j] = max(L[i-1][j], L[i][j-1]) return L[m][n] X = "AGGTAB" Y = "GXTXAYB" print(f"The length of LCS is {lcs_length(X,Y)}") ``` 这段程序实现了两个字符串之间的最长公共子序列长度计算功能[^2]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值