我是如何解决问题的

start: 在写这篇文章前,我想到了一个问题: 我该如何写出一篇关于我是如何解决问题的的文章。

什么是问题

我们所熟知的世界充满了问题。 什么是问题,这个问题更像一个哲学问题。 我是这样理解问题的。 问题定义了最终状态;解决方案则是一条从初始状态到此最终状态的路径。 初始状态是我们已知的任何知识。 所以,解决问题带有强烈的目标导向的意味:从结果开始反推。

我能解决的问题,和我不能解决的问题

我能解决的问题是

  • 能对问题作出准确描述的
  • 可通过我所知道的问题解决方案推导得到的

事实上,准确描述相当难做到。 这也是为什么现在我在动手做事情前,在确认这些细节上花的时间越来越多了。

对于我能解决的问题,我是如何解决的

最弱前条件

最弱前条件是一种形式化证明的手段。 它希望从确定的初始状态启动,让系统刚好终止于希望达到的最终状态。 有关最弱前条件怎么解算法题目,前段时间有应用了一下,非常好用。

  • http://book.douban.com/annotation/36435586/

  • http://book.douban.com/annotation/36388590/

  • http://www.douban.com/note/524325568/

最弱前条件的性质:

  • 如果最终状态不存在,那么初始状态也不存在。换句话说:有时候无解。
  • 设定一个比最终状态更宽松的状态集,根据此状态集求解能得到更宽松的初始状态集。换句话说:可以简化问题。
  • 将最终状态分拆为两个状态集,那么初始状态将等价于根据两个最终子状态集分别求其初始子状态集后的合集。换句话说:可以分拆组合子问题

在拿到问题时,我会尽力去思考问题的各种可能终态,继而推导出能产生出正确结果的初始状态。这很大程度上改变了我最近的生活:

  • 拿到产品经理的需求后,我们可以无情地找到各种产品经理思考的漏洞(靠谱的产品经理产出的需求漏洞比较少);
  • 拿到算法题目后,一道题可以反推出非常多种可能的解法;
  • 生活中随时可能出现的难题,明确了问题后,列出可能的方案,选择一种性价比最高,副作用最小的方案。

(感谢 Dijkstra)

隔离复杂性

很多问题有着内在的复杂性,无法通过一次思考就能得到全部解。 这对如何分拆组合子问题提出了很高的要求。 我喜欢这两种两种维度:

  • 平行分拆,组合方式是:对子问题解求合集
  • 前后继分拆,组合方式是:子问题的解成为下一级子问题的初始状态。

(感谢 SICP)

进行下去

在冗长的任务面前,理清前后继关系,使用一个队列逐个消费任务;每个任务使用最弱前条件解决,解决好后组合起来。 问题就解决了。

怎么写这篇文章

回到最初的问题。当想到要写这样的文章,我的思路如下。

后条件

写出一篇内容为“我是如何解决问题的”的文章,

它能:

  • 阐明什么是问题
  • 阐明我能解决的问题域
  • 阐明解决问题域内的问题所遵循的方法论
  • 使用本文章介绍的方法解决如何写这篇文章的问题

前条件

goto start