[转] Strategy: Solve Only 80 Percent of the Problem

本文探讨了解决80%问题的策略,指出解决全部问题往往成本高昂且不必要。通过聚焦于大部分用户的需求,可以更高效地设计出实用的解决方案。以Twitter实时搜索为例,说明了简化设计如何实现快速响应并保持相关性。

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

Strategy: Solve Only 80 Percent of the Problem

Todd Hoff's picture

 

Solve only 80% of a problem. That's usually good enough and you'll not only get done faster, you'll actually have a chance of getting done at all.

This strategy is given by Amix in HOW TWITTER (AND FACEBOOK) SOLVE PROBLEMS PARTIALLY. The idea is solving 100% of a complex problem can be so hard and so expensive that you'll end up wasting all your bullets on a problem that could have been satisfactoraly solved in a much simpler way.

The example given is for Twitter's real-time search. Real-time search almost by definition is focussed on recent events. So in the design should you be able to search historically back from the beginning of time or should you just be able to search for recent time periods? A complete historical search is the 100% solution. The recent data only search is the 80% solution. Which should you choose?

The 100% solution is dramatically more difficult to solve. It requires searching disk in real-time which is a killer. So it makes more sense to work on the 80% problem because it will satisfy most of your users and is much more doable.

By reducing the amount of data you need to search it's possible to make some simplifying design choices, like using fixed sized buffers that reside completely in memory. With that architecture your streaming searches can be blisteringly fast while returning the most relevant data. Users are happy and you are happy.

It's not a 100% solution, but it's a good enough solution that works. Sometimes as programmers we are blinded by the glory of the challenge of solving the 100% solution when there's a more reasonable, rational alternative that's almost as good. Something to keep in mind when you are wondering how you'll possibly get it all done. Don't even try.

Amix has a very good discussion of Twitter and this strategy on his blog.

 

Worse is Better

 

A Hacker News post discussing this article brought up that this strategy is the same as Richard Gabriel's famous Worse-is-Better paradox which holds: The right thing is frequently a monolithic piece of software, but for no reason other than that the right thing is often designed monolithically. That is, this characteristic is a happenstance. The lesson to be learned from this is that it is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing.

Unix, C, C++, Twitter and almost every product that has experienced wide adoption has followed this philosophy.

Worse-is-Better solutions have the following characteristics:

  • Simplicity - The design must be simple, both in implementation and interface. It is more important for the implementation to be simpler than the interface. Simplicity is the most important consideration in a design.
  • Correctness - The design must be correct in all observable aspects. It is slightly better to be simple than correct.
  • Consistency - The design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either implementational complexity or inconsistency.
  • Completeness - The design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favor of any other quality. In fact, completeness must be sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.

     

    In my gut I think Worse-is-Better is different than "Solve Only 80 Percent of the Problem" primarily because Worse-is-Better is more about product adoption curves and 80% is more a design heuristic. After some cogitating this seems a false distinction so I have to concluded I'm wrong and have added Worse-is-Better to this post.

     

    Related Articles

  • Worse Is Better Richard P. Gabriel
  • Lisp: Good News, Bad News, How to Win Big
  • Interesting Hacker News Thread
  • In Praise of Evolvable Systems by Clay Shirky
  • Big Ball of Mud by Brian Foote and Joseph Yoder

 

<think>好的,我现在需要回答用户关于OpenCV中cv::solve和fisheye::solve的原理区别和应用场景的问题。首先,我得回忆一下这两个函数的基本信息,然后深入它们的实现原理。首先,cv::solve是OpenCV中的通用线性系统求解函数,用于解决形如Ax =B的方程。用户可能知道,它支持多种分解方法,比如LU分解、QR分解等。而fisheye::solve属于fisheye模块,专门用于鱼眼相机的标定,可能涉及非线性优化问题,因为鱼眼镜头通常有较大的畸变,标定过程需要更复杂的模型,比如多项式畸变模型。接下来,我需要明确两者的原理差异。cv::solve处理的是线性问题,可能使用数值线性代数中的标准方法。而fisheye::solve可能针对鱼眼相机的非线性畸变参数进行优化,比如使用Levenberg-Marquardt算法这样的非线性最小二乘法。这里需要确认OpenCV文档中fisheye::solve的具体实现,是否确实如此。然后,应用场景方面,cv::solve适用于一般的线性系统求解,比如计算单应性矩阵、相机姿态估计中的PnP问题等。而fisheye::solve则专用于鱼眼相机的标定过程,估计相机内参和畸变系数。这里需要区分普通相机标定和鱼眼标定的不同,鱼眼通常需要更高阶的畸变模型,比如使用4个畸变参数而不是普通的径向切向模型。 可能还需要考虑两者的输入参数和输出结果的不同。比如,cv::solve的输入是矩阵A和B,输出是解向量x,而fisheye::solve可能需要输入的是多个标定图像的点对应,输出相机矩阵和畸变参数。 另外,需要注意OpenCV中普通相机标定和鱼眼标定的模块不同,普通标定可能使用calib3d模块,而鱼眼标定在fisheye模块中。两者的标定函数可能分别是calibrateCamera和fisheye::calibrate,而solve函数可能是在标定过程中被调用的优化方法。 还要思考用户可能的深层需求,比如他们可能在处理鱼眼相机的标定问题,遇到精度或速度上的挑战,想知道该选择哪个函数,或者如何优化标定结果。因此,在回答中需要明确两者的适用场景,帮助用户做出正确选择。最后,生成相关问题时,需要考虑用户可能进一步想知道如何选择这两个函数,或者鱼眼标定的具体步骤,以及如何处理标定中的常见问题。比如,标定板的选择、参数初始化的方法,或者如何评估标定结果的准确性。总结一下,回答的结构应该先分点说明原理差异,包括问题类型、算法、参数模型,然后讨论应用场景,最后给出示例代码(如果有的话)和相关问题。需要确保使用正确的中文术语,并且LaTeX公式符合要求,比如变量用$符号包裹,独立公式用$$。</think>### OpenCV中cv::solve与fisheye::solve的原理差异 #### 1. **数学问题类型** - **cv::solve**: 用于求解线性方程组$Ax = B$,支持LU、QR、Cholesky等矩阵分解方法[^1]。例如: $$ A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix},\quad B = \begin{bmatrix} 5 \\ 6 \end{bmatrix} $$ - **fisheye::solve**: 针对鱼眼相机标定的**非线性优化问题**,需最小化重投影误差,通常使用Levenberg-Marquardt算法[^2]。目标函数为: $$ \min_{\theta} \sum_{i} \| \pi(K, D, X_i) - x_i \|^2 $$ 其中$K$为内参,$D$为畸变系数,$\pi$为鱼眼投影模型。 #### 2. **参数模型差异** - **cv::solve**: 输入为矩阵$A$和向量$B$,输出直接解$x$。 - **fisheye::solve**: 输入为标定板的3D-2D点对应关系,输出包含: - 内参矩阵$K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}$ - 畸变系数$D = [k_1, k_2, k_3, k_4]$ #### 3. **算法实现** - **cv::solve**: 基于数值线性代数库(如LAPACK),直接调用`cv::decompose`函数。 - **fisheye::solve**: 通过迭代优化更新参数,每次迭代计算雅可比矩阵$J$并求解增量$\Delta \theta$: $$ (J^T J + \lambda I) \Delta \theta = J^T e $$ ### 应用场景对比 | **场景** | **cv::solve** | **fisheye::solve** | |------------------------|---------------|--------------------------| | 普通相机标定 | ✓ (PnP问题) | ✗ | | 鱼眼相机标定 | ✗ | ✓ (支持大畸变模型) | | 实时姿态估计 | ✓ (低延迟) | ✗ | | 广角镜头标定 | ✗ | ✓ (需4阶畸变参数补偿) | ### 代码示例 ```cpp // 使用cv::solve求解线性系统 cv::Mat A, B, x; cv::solve(A, B, x, cv::DECOMP_QR); // 使用fisheye::solve进行标定 std::vector<cv::Mat> objectPoints, imagePoints; cv::Mat K, D; cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, K, D); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值