Answers:
有许多经过深入研究的策略;哪种情况最适合您,取决于具体情况。
改善最坏情况的运行时间
使用特定于问题的见解,您通常可以改善朴素的算法。例如,对于 c < 1.3 [1],有用于Vertex Cover的算法。与天真的 Ω (2 n)相比,这是一个巨大的改进,并且可能使与您相关的实例大小易于处理。
改善预期的运行时间
使用启发式方法,您通常可以设计在许多实例上快速运行的算法。如果这些内容包括您在实践中遇到的大多数内容,那么您就是黄金。例如SAT(存在相当多的求解器)和Simplex算法(它可以解决多项式问题)。一种经常有用的基本技术是分支和绑定。
限制问题
如果您可以对输入进行更多假设,则问题可能会变得容易。
削弱结果
这意味着您可以容忍错误或不完整的结果。主要有两种口味:
请参阅Hromkovič的《关于难题的算法》,以进行全面处理。
其他答案从更理论的角度解决了这个问题。这是一种更实用的方法。
对于“典型的” NP完全决策问题(“是否有满足所有这些约束的问题?”),这是我始终会首先尝试的方法:
首先尝试使用较小的实例,以了解可能需要花费多长时间。
经常令人惊讶的是,这种方法比尝试专门针对当前问题实现自己的求解器要好得多:
SAT求解器非常聪明且经过优化。它们很容易胜过您自己的回溯搜索实现(无论您浪费了多少时间来优化代码)。它们还很容易胜过许多现有的替代方案,例如整数线性规划求解器。
这需要很少的编程。步骤1相对简单,对性能也不重要。您可以使用脚本语言,例如Python。其他人已经负责实现步骤2所需的一切。
对于典型的NP-hard 优化问题(“找到满足所有这些约束的最小问题”),此方法可能有效或无效。
如果您可以轻松地将其变成决策问题( “是否存在满足所有这些约束的4号大小的东西?”,“ 3号大小呢?”),那么,对上述决策问题采取与上述相同的方法即可。
否则,您可能希望借助启发式求解器尝试找到一个小的解决方案(不一定是最小的解决方案)。例如:
攻击难处理性的一种方法是在参数化的复杂性上下文中考虑问题。
只是一些可计算函数。FPT有许多NP难题,但是,NP中有许多问题被认为不是固定参数可处理的。
这些是W层次结构不同类别中的一些示例:
这些是复杂度的另一个级别,可以更精确地对NP问题进行分类,如果需要更多,可以查看Downey等人(1998年)的“ 参数化电路复杂度”和“ W层次结构”。
如果您想了解更多信息,那么可以阅读Flum和Grohe的参数化复杂性理论。
最后:
众所周知,如果问题具有FPTAS(完全多项式时间逼近方案),那么它也是FPT(这很明显),但是没有反向的众所周知的东西,也有一些关于PTAS和XP的关系的著作,但是PTAS和W层次结构之间的关系不是很紧密(至少目前我还不知道)。
同样在某些情况下,我们可能会修复一些不同的参数,例如:图中最长路径的长度是有界的,而解决方案的大小是有界的(例如,在反馈顶点集中),...
可能有些人认为参数化的复杂性在实践中是没有用的。但这是错误的。当您可以修复一些参数时,在实际应用中会发现许多参数化算法,下面是一个示例:
用于TSP的最快,最准确的启发式算法之一是:巡回合并和分支分解,它使用问题的参数化(不是直接进行,而是基于一些良好的假设而使用的分支分解和动态规划方法)。
尽管在某些答案中进行了简要介绍,但让我强调,在实践中,NP完全问题一直都得到解决(或近似)。在实践中可以解决NP完全问题的主要原因是:
在实践中遇到的实例不是“最坏情况”。
出现差异的另一个原因是:
正式地分析启发式算法是困难的。
在实践中,您使用启发式算法来解决NP完全问题,并希望达到最佳效果。结果通常是惊人的。
其他答案中涉及的另一个问题是:
有时指数算法足够快。
那当然取决于问题。当涉及大数据时,我们有相反的准则:
有时,唯一可行的算法是拟线性的。
恐怕这里的人群理论上比较偏心。您可能会在主要的stackexchange网站上获得更好的答案。