我需要解决一个 NP 难题。有希望吗?
Posted
技术标签:
【中文标题】我需要解决一个 NP 难题。有希望吗?【英文标题】:I need to solve an NP-hard problem. Is there hope? 【发布时间】:2015-02-11 20:51:31 【问题描述】:有很多现实世界的问题原来是NP-hard。如果我们假设 P ≠ NP,则没有任何多项式时间算法可以解决这些问题。
如果您必须解决其中一个问题,您是否有希望能够有效地解决问题?还是你运气不好?
【问题讨论】:
【参考方案1】:如果一个问题是 NP-hard,假设 P ≠ NP 没有算法是
确定性, 所有输入始终准确无误,并且 对所有可能的输入都有效。如果您绝对需要上述所有保证,那么您就很不走运了。但是,如果您愿意满足于解决问题以放松其中一些限制,那么很有可能仍然有希望!以下是一些可供考虑的选项。
选项一:逼近算法
如果一个问题是 NP-hard 并且 P ≠ NP,这意味着没有算法能够始终有效地产生精确的所有输入的正确答案。但是,如果您不需要确切的答案怎么办?如果您只需要接近的答案来纠正怎么办?在某些情况下,您可以通过使用近似算法来对抗 NP-hardness。
例如,NP 难题的典型示例是traveling salesman problem。在这个问题中,您将获得一个代表交通网络的完整图形作为输入。图中的每条边都有一个相关的权重。目标是找到一个循环,该循环恰好经过图中的每个节点一次,并且总权重最小。在边缘权重满足triangle inequality的情况下(即从A点到B点的最佳路线总是沿着从A到B的直接链接),那么你可以得到一个成本最多为的循环使用 Christofides algorithm 优化 3/2。
作为另一个例子,0/1 knapsack problem 已知是 NP-hard。在这个问题中,给你一个袋子和一组具有不同权重和值的对象。目标是在不超过袋子重量限制的情况下将最大价值的物品装入袋子。尽管在最坏的情况下计算精确答案需要指数时间,但可以在多项式时间内将正确答案逼近到任意精度。 (执行此操作的算法称为完全多项式时间逼近方案或FPTAS)。
不幸的是,我们对某些 NP 难题的近似性确实存在一些理论限制。前面提到的 Christofides 算法给出了 TSP 的 3/2 近似值,其中边服从三角形不等式,但有趣的是,它可以证明如果 P ≠ NP,则有没有任何 TSP 的多项式时间逼近算法可以在 any 常数因子的最优值范围内。通常,您需要进行一些研究以了解更多关于哪些问题可以很好地近似,哪些问题不能,因为许多 NP 难题可以很好地近似,而许多问题则不能。好像没有统一的主题。
选项二:启发式
在许多 NP 难题中,诸如贪心算法之类的标准方法并不总能产生正确的答案,但通常在“合理”输入上做得相当好。在许多情况下,使用 启发式 来解决 NP 难题是合理的。启发式的确切定义因上下文而异,但通常启发式是一种解决问题的方法,它“经常”以有时给出错误答案为代价给出好的答案,或者是一种有用的经验法则,有助于加快搜索速度,即使它可能并不总是以正确的方式引导搜索。
作为第一种启发式的示例,让我们看一下graph-coloring problem。这个 NP 难题要求给定一个图形,找出绘制图形中节点所需的最小颜色数,以使所有边的端点颜色都不相同。事实证明,这是一个用许多其他方法来解决的特别困难的问题(最著名的近似算法有可怕的界限,并且不怀疑它有一个参数化的有效算法)。但是,有许多用于图形着色的启发式方法在实践中做得很好。许多greedy coloring heuristics 用于以合理的顺序为节点分配颜色,这些启发式方法在实践中通常做得很好。不幸的是,有时这些启发式方法会给出糟糕的答案,但如果图表不是病态构造的,那么启发式方法通常可以正常工作。
作为第二种启发式的示例,看看 SAT 求解器会很有帮助。 SAT,布尔可满足性问题,是第一个被证明是 NP-hard 的问题。这个问题要求,给定一个命题公式(通常写在conjunctive normal form),以确定是否有一种方法可以为变量赋值,从而使整个公式的计算结果为真。 Modern SAT solvers 在很多情况下都非常擅长解决 SAT 问题,方法是使用启发式方法来指导他们搜索可能的变量分配。一种著名的 SAT 求解算法 DPLL 本质上是尝试所有可能的分配,以查看公式是否可满足,使用启发式加速搜索。例如,如果它发现一个变量要么总是真要么总是假,DPLL 将在尝试其他变量之前尝试为该变量分配其强制值。 DPLL 还查找单元子句(只有一个文字的子句)并在尝试其他变量之前设置这些变量的值。这些启发式的最终效果是 DPLL 在实践中最终会非常快,即使已知它具有指数级的最坏情况行为。
选项三:伪多项式时间算法
如果P ≠ NP,则没有NP-hard问题可以在多项式时间内解决。然而,在某些情况下,“多项式时间”的定义不一定符合多项式时间的标准直觉。正式地说,多项式时间是指指定输入所需的位数中的多项式,这并不总是与我们认为的输入同步。
以set partition problem 为例。在这个问题中,你得到了一组数字,需要确定是否有办法将这个集合分成两个较小的集合,每个集合的总和相同。这个问题的简单解决方案在 O(2n) 时间内运行,并且只通过蛮力测试所有子集来工作。但是,使用动态规划,可以在 O(nN) 时间内解决这个问题,其中 n 是集合中元素的数量,N 是集合中的最大值。从技术上讲,运行时间 O(nN) 不是多项式时间,因为数值 N 仅写入 log2 N 位,但假设 N 的数值不太大,这是一个完全合理的运行时。
这个算法被称为pseudopolynomial-time algorithm,因为运行时 O(nN)“看起来”像一个多项式,但从技术上讲,它是输入大小的指数。许多 NP 难题,尤其是涉及数值的问题,都承认伪多项式时间算法,因此在数值不太大的情况下很容易解决。
有关伪多项式时间的更多信息,请查看this earlier Stack Overflow question about pseudopolynomial time。
选项四:随机算法
如果一个问题是 NP-hard 并且 P ≠ NP,那么不存在 确定性 算法可以在最坏情况多项式时间内解决该问题。但是,如果我们允许引入随机性的算法会发生什么?如果我们愿意满足于一种能够在期望上给出良好答案的算法,那么我们通常可以在很短的时间内就 NP 难题获得相对较好的答案。
以maximum cut problem 为例。在这个问题中,给定一个无向图,并希望找到一种方法将图中的节点拆分为两个非空组 A 和 B,并在组之间运行最大数量的边。这在计算物理学中有一些有趣的应用(不幸的是,我根本不理解它们,但您可以仔细阅读this paper 了解有关此的一些细节)。众所周知,这个问题是 NP 难题,但有一个简单的随机近似算法可以解决这个问题。如果您只是将每个节点完全随机地扔到两组中的一组中,那么您最终会得到一个切割,预期在最佳解决方案的 50% 以内。
回到 SAT,许多现代 SAT 求解器使用某种程度的随机性来指导搜索令人满意的作业。例如,WalkSAT and GSAT 算法通过选择当前不满足的随机子句并尝试通过翻转某个变量的真值来满足它来工作。这通常会引导搜索找到令人满意的任务,从而使这些算法在实践中运行良好。
事实证明,关于使用随机算法解决 NP 难题的能力存在许多开放的理论问题。如果您好奇,请查看复杂性类 BPP 以及它与 NP 关系的未解决问题。
选项五:参数化算法
一些 NP 难题需要多个不同的输入。例如,long path problem 将一个图和一个长度 k 作为输入,然后询问图中是否存在长度为 k 的简单路径。 subset sum problem 将一组数字和一个目标数字 k 作为输入,然后询问是否有一个数字的子集与 k 相加。
有趣的是,在长路径问题的情况下,有一个算法(color-coding algorithm),其运行时间为 O((n3 log n) · bk),其中 n 是节点数,k 是请求路径的长度,b 是某个常数。这个运行时间在 k 中是指数的,但在节点数 n 中只是多项式。这意味着如果 k 是固定的并且事先已知,则算法的运行时间作为节点数的函数只有 O(n3 log n),这是一个非常好的多项式。类似地,在子集和问题的情况下,有一个动态规划算法,其运行时间为 O(nW),其中 n 是集合中元素的数量,W 是这些元素的最大权重。如果 W 预先固定为某个常数,则该算法将在 O(n) 时间内运行,这意味着可以在线性时间内精确求解子集和。
这两种算法都是 parameterized algorithms 的示例,用于解决 NP 的算法 - 将问题的难度分成两部分的困难问题 - 一个取决于某些输入参数的“困难”部分问题,以及一个“简单”的部分,可以随着输入的大小优雅地缩放。当所讨论的参数很小时,这些算法对于找到 NP 难题的精确解决方案很有用。例如,上面提到的颜色编码算法已被证明在计算生物学的实践中非常有用。
但是,有些问题被推测为没有任何好的参数化算法。例如,图着色被怀疑没有任何有效的参数化算法。在存在参数化算法的情况下,它们通常非常有效,但您不能依赖它们来解决所有问题。
有关参数化算法的更多信息,请查看this earlier Stack Overflow question。
选项六:快速指数时间算法
指数时间算法不能很好地扩展 - 对于小至 100 或 200 个元素的输入,它们的运行时间接近宇宙的生命周期。
如果您需要解决 NP 难题,但您知道输入相当小 - 比如说,它的大小可能在 50 到 70 之间。标准的指数时间算法可能是不会足够快来解决这些问题。如果您确实需要一个精确的解决方案而这里的其他方法无法解决问题怎么办?
在某些情况下,有针对 NP 难题的“优化”指数时间算法。这些算法的运行时间是指数型的,但不如简单的解决方案指数型那么糟糕。例如,一个简单的指数时间算法用于 3 着色问题(给定一个图形,确定您是否可以为节点着色为三种颜色中的一种,以便没有边缘的端点是相同的颜色)可能会检查每种可能的着色方式图中的节点,测试它们中的任何一个是否为 3 色。有 3n 种可能的方法来做到这一点,所以在最坏的情况下,对于一些小的多项式,该算法的运行时间将为 O(3n · poly(n))聚(n)。但是,使用更聪明的技巧和技术,可以开发出一种及时运行的 3 色算法O(1.3289n)。这仍然是一种指数时间算法,但它是一种更快的指数时间算法。例如,319 大约是 109,所以如果一台计算机每秒可以执行 10 亿次操作,它可以使用我们最初的蛮力算法(粗略地说)在一秒钟内解决多达 19 个节点的图形中的 3-colorability。使用 O((1.3289n) 时间指数算法,我们可以在大约 1 秒内解决多达约 73 个节点的实例。这是一个巨大的改进 - 我们已经扩大了我们可以处理的大小一秒超过三倍!
作为另一个著名的例子,考虑旅行商问题。 TSP 有一个明显的 O(n!·poly(n)) 时间解决方案,它通过枚举节点的所有排列并测试由这些排列产生的路径来工作。但是,通过使用类似于颜色编码算法的动态编程算法,可以将运行时间提高到“仅”O(n2 2n) .鉴于13!大约是 10 亿,简单的解决方案可以让您在大约一秒钟内解决 13 节点图的 TSP。相比之下,DP 解决方案可让您在大约 1 秒内解决 28 节点图上的 TSP。
这些快速指数时间算法通常可用于增加可在实践中精确求解的输入大小。当然,它们仍然在指数时间内运行,因此这些方法通常不适用于解决非常大的问题实例。
选项七:解决一个简单的特殊情况
NP 困难的许多问题通常都限制了已知可以有效解决的特殊情况。例如,虽然通常 NP-很难确定 whether a graph has a k-coloring,但在 k = 2 的特定情况下,这相当于检查一个图是否是二分图,即可以使用修改后的深度优先搜索在线性时间内检查。一般而言,布尔可满足性是 NP-hard,但如果您的输入公式每个子句最多包含两个文字,或者公式由使用 XOR 的子句形成,则它可以在多项式时间内求解在图中找到最大的独立集通常是 NP-hard,但如果图是二分图,由于 König 定理,这可以有效地完成。
因此,如果您发现自己需要解决最初看起来可能是 NP 难题的问题,请首先检查您实际需要解决该问题的输入是否有一些额外的限制结构体。如果是这样,您也许能够找到一种适用于您的特殊情况的算法,并且运行速度比完全通用的问题的求解器快得多。
结论
如果您需要解决 NP 难题,请不要绝望!有很多很好的选择可以让你的棘手问题更容易解决。上述技术中没有任何一种适用于所有情况,但通过结合使用这些方法,即使遇到 NP-硬度,通常也可以取得进展。
希望这会有所帮助!
【讨论】:
以上是关于我需要解决一个 NP 难题。有希望吗?的主要内容,如果未能解决你的问题,请参考以下文章