ᕼᑎ:49291268145 pts89 commentsProgrammingworth reading
NP-Overrated
Claude brief
HN 热门故事「NP-Overrated」进入今日前列,值得先打开原文和讨论串判断它真正有价值的部分。
模型分析没有产出可用结构化结果;页面保留了 HN 热度、原文入口和讨论信号,避免用空泛总结替代一手材料。
它在 HN 上获得约 145 分和 89 条评论,说明这个话题至少触发了社区讨论;真正的判断仍要回到原文证据和评论区的分歧点。
这是一条降级分析:它不冒充完整解读,只把可验证的元数据、原始链接和 HN 讨论保留下来,方便稍后重新生成或人工阅读。
HN rank: 5
HN score: 145
comments: 89
original url: https://gruhn.me/blog/2026-08-13/
评论区已经提供了一些读者反应,但这里还没有形成完整综合。
它进入 HN 前列本身就是一个社区信号,但这还不是结论;更可靠的判断来自原文细节和评论区反例。
deep insight
这条记录目前缺少模型生成的深层解读。更好的阅读方式是先问:它的热度来自真正的新信息、可迁移的方法,还是只来自标题与时机。
可以先读原文第一屏和 HN 最高赞评论,再决定是否值得重新生成完整分析。
top comments
1. The study of complexity classes isn't intended to dissuade people from writing certain programs. It's intended to understand the nature and theoretical limits of computation. As far as practice goes, it can be used to show where heuristics are needed. Saying it's overrated is like saying calculus is overrated because most people don't need to use it every day. And BTW, many important problems are in classes believed to be way harder than NP (i.e. NP-complete is the easiest of the hard famous complexity classes). E.g., I've seen some people brag about some configuration language being easy to mechanically analyse because it's not Turing-complete, while in fact it's at least PSPACE-hard to analyse.2. When there's some large set of instances of some NP-hard problem that are tractably solvable in practice (like SAT), the importance of that is that there's some non-NP-hard subset here. Indeed, SAT is FPT (fixed parameter tractable [1]), an "easier" type of NP, for which decomposition can help. In contrast, graph colouring is thought to not be FPT.[1]: https://en.wikipedia.org/wiki/Parameterized_complexity reply:...
I feel like the write up doesn't really engage with the number one solution usedDon't allow the hard onesDependency managers tend to just block a huge category of situations that effectively eliminate the entire NP hard spaceType systems similarly are explicitly cordoned offThe trick isn't "do it anyway" beyond you kind of definitionly need to, it is to acknowledge the general problem is "impossible" so either do your best or start eliminating the impossible reply: A variant:> Don't encounter the hard onesFor example, with the simplex method for linear programming, we don't do anything about disallowing the hard instances. We just solve the problems as they come in and none of the ones we get asked to solve ever turn out to be hard. (Generalizing, of course.)
Very true! What makes NP-hard problems difficult is almost always the combinatorial explosion related to specific problem configurations -- you can construct instances given an approximate heuristic or branch-and-bound solver that will cause it to have an exponential blow up. But for most practical problems you don't reach those explosive configurations.There's probably a quantification of this in some sense for specific classes of NP-hard problems.What's interesting is that many algorithms (especially in cryptography) are explicitly designed to create those combinatorial edge cases. A SAT solver looking at normal problems that occur in life and programming will do an amazing job. A SAT solver looking at SHA256, not so much. In fact, arguable the science of developing cryptographic systems is the science of finding these exponential explosions that are resistant to heuristic approximations.
>For (1) and (2), the worst-case just doesn't occur. I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.NP-hard problems are hard to solve exactly, but it's usually possible to get a pretty good approximate solution efficiently. But some search problems are just very hard, even approximately. If you've held an old Debian install through major upgrades with aptitude, you'll have had to see it get lost deep in outer search space pretty regularly.Sometimes aptitude needs to downgrade a package, uninstall a package, or not install a recommended package to arrive at the right solution. There are many possible packages it could try to downgrade, and each of these creates a brand new mess with new possibilities. This is not something you get with other package managers, and its search strategy is genuinely intractable if you don't help it along by trying to manually figure out the small set of packages that create all the difficulty. reply: The description you've given for apt just sounds almost exactly like SAT, a problem that's very efficiently approximated....
I'm fond of this brain-expander, in spirit of TFA: "Did you know travelling salesperson is O(N) on a large class of graphs?"Another insight: I regularly find that clever O(logn) solutions are just obliterated by a few mostly-branch-free O(N) pre-passes followed by a problem that computers enjoy, like contiguous memory access and vector operations. reply: Yeah why is "the algorithm" the thing we do in our head to mimick a 1970s computer and not what really happens on hardware.
> I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.Last time I had a galactic blow-up of apt solver (the final part of 64-bit time transition in Debian Testing) it was mere 2 GiB of memory per minute.
Sometimes you don't need an _exact_ solution. approximation of the traveling salesman problem exists for the metric version, it's O(n^3), and produces a result that's not worse than 50% of the optimal result, and for the general case O(n^2) algorithm exists that produces a result that costs at most twice the optimal result. reply: For traveling salesman that's more than good enough. But in many cases an O(n^3) algorithm can't be used because n is in the billions. I remember interviewing a candidate who asserted that register retiming in digital circuits was a non-problem, so they were surprised that we were still working on improvements, because they had learned that the Leiserson-Saxe algorithm gives an optimal solution in O(n^3) time. But because real circuits are so large that that approach can't be used. Polynomial time often isn't good enough; even quadratic time often isn't tolerable.
I spent my career in electronic design automation, where practically every interesting problem is NP-hard, but we have to solve them, or approximately solve them at least, and because real-life problems often have structure, with the right approach very large problems can be solved exactly despite the theoretical complexity, and when exact solutions can't be found a decent bound can often be found that is an acceptable solution.Sales people still have to plan their trips even though finding the optimal solution is NP-hard (to give one example). No matter; there are decent heuristic methods.
> The theory is not wrong, but in practice it's often irrelevant. Sure, any algorithm you can come up with will blow up on some inputs. But you might get a fast solution on 99.9% of inputs.A lot of simulation we only have exponential-time algorithms for. Motion planning, protein folding, etc. For a lot of these today, the SOTA is to use an NN model to learn the heuristics from data. OP's claim only rings true if one can only think of just the algorithms that undergrad CS now studies.
Perfect example is the simplex algorithm.We do have a polynomial algorithm for linear programming yet simplex (with exponential worst case performance) is our tool of choice.
> A few prominent NP-hard problems:> Type checking (not all type systems)> I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.Swift was infamous of having exponential time type inference that made expressions like `"foo" + "bar" + "baz" + "qux" + 123` take literal minutes to fail with a compiler error.
> I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.I have, it's called conda.
> For (1) and (2), the worst-case just doesn't occur. I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.Hehe, clearly the author hasn't written any SwiftUI.
The author justifiably attacks the notion that "NP-hard" == "too hard to solve in practice", but then makes the opposite error:> Everyone knows you can tackle those with heuristics, but you don't have to sacrifice optimality.Unless you're using some weird definition of optimality, or happen to have a proof of N=NP in your back pocket: yes, yes you do.You don't have to sacrifice "good enough". You don't have to let it run for an insane amount of time. Just about all interesting problems that I know of have either (1) good heuristics that in practice get close enough to optimal that nobody needs to care about the gap, or (2) constraints or restrictions that are totally fine to apply in practice.But those are both ways of sacrificing optimality. You have to sacrifice optimality. It just turns out that optimality isn't usually very important, especially when 99% of optimality is achievable.> We absolutely have tools that can find provably optimal solutions in reasonable time. There's no magic. No quantum computers. Just thinking harder and coming up with better algorithms.No, we absolutely do not. Again, not unless someone has secretly come up with a constructive proof of P=NP....
One example is Sudoku. It's NP-hard, but in practice, it takes no time at all to solve your newspaper puzzle.
The general version of a problem being NP-complete doesn't mean that cases of practical interest are all necessarily intractable. In the case of SAT, for instance, there are also ways for the humans to give the solver an easier problem to solve in many cases, like adding extra clauses to guide the solver away from useless parts of the search space.
A well known NP-hard problem is matching some flavors of regex (ex: PCRE). You can turn a 3-SAT problem into such a regex.In normal situations, it is not a problem, I have written thousands of regex without ever hitting a galactic case (at least not one I am aware of).But it can still be a problem because if the regex engine is too powerful and accepts user input, a specially crafted regex can be used as a denial of service attack.
Ever since I first saw a binary integer program with millions of variables solved in less time than it took me to hit enter I realized that the fact that I had made it through graduate school for computer science, and never encountered the sorts of optimization algorithms happening in the field of operation operations research is a sad one.
This dovetails into one of my favorite CS sub-fields: approximation algorithms. In many cases NP-Hard problems may be approximated with a guaranteed lower bound of accuracy. For example, solving the euclidean version of the travelling salesman problem using a minimum spanning tree finds solutions that are no worse than 1.5 times the true minimum length, and there are heuristics with weaker guarantees that consistently perform better in practice.
A good deal of the field of Operations Research (OR) is about getting a good solution to NP-hard problems anyway. It is fun!
This is kind of why P vs NP is such an interesting problem. It seems that a big family of NP-hard problems in fact _can_ be solved efficiently if we allow relaxing some constraints, like optimality (eg TSP), or generality of our algorithm (eg type checking).I feel that is similar to how adding randomness to cryptography [1] opened a bunch of new systems like zero knowledge proofs[2]. By allowing us to be wrong in a very small number of instances (arbitrarily small by adjusting things like key size), we can build practical systems with really impressive properties.[1]: Goldwasser and Micali - Probabilistic Encryption, 1983 https://web.archive.org/web/20090319000035/http://groups.csa... [2]: Goldwasser, Micali and Rackoff - The knowledge complexity of interactive proof-systems, 1985 https://courses.csail.mit.edu/6.857/2008/handouts/1989-siamj...
> I mean, installing packages and type checking can surely be slow. But, at least in my career, I've never seen a galactic blow-up.Have you ever tried building an iOS app? The compiler gives up after a sufficient time because typechecking can be so slow
> NP-hard problems are solvable in theory but it's hopelessly expensive in practice. It's basically proven that no good algorithms exist. At least that's what I took away.You took away the wrong thing. The theory tells you that no good algorithm exists for _all_ possible inputs. This means you have to try to limit yourself to a subset of the problem space, and use heuristics to move all the remaining pathological cases (if any) to a corner you then monitor and ensure doesn't occur in practice too often.Package managers are designed the way they are _because_ of the inherent NP-hardness, not _despite_ it as this article conveys.In the formal models of dependency resolution, the three core conditions are: 1) Root package is included, 2) Dependency closure (everything required is present) 3) Version uniqueness (at most one version per package name)NPM, yarn etc drop 3) which makes it not NP hard.Go limits itself to minimum version selection which admits a linear time solution.Cargo allows multiple major versions, thus reducing most cases of 3), and then relies on heuristics to prune and reduce the pathological cases to be relatively rare....
Did you know: general purpose computers are completely pointless, because programs can run forever without producing a result.
And if the problem is really really hard, you can throw an AI at it and hopefully get a probabilistic solution.(not necessarily an LLM, AI is a huge field)
I've made comments on HN on this point a number of times e.g. https://news.ycombinator.com/item?id=44284083I had some tedious debate on HN once where I asked if anyone had any pointers to good parallel SMT solvers, only to fall victim to someone dedicated to dying on the hill of "parallelization can never make this kind of search faster" due to (often inapplicable) complexity theory fixation.
How come most package managers suck then? Why did I waste hours of my life debugging portage and yum?
Once you admit approximations the theoretical problem trades places with a more interesting one: what is the Pareto frontier of loss vs complexity?