问题和问题求解
实际问题千变万化,我们考虑一种抽象的统一说法:一个问题就是从一个实例描述集合到解集合的映射,
。如果I是有穷集,T 就是有穷问题,否则T 是无穷问题。
或
称为问题 T 的实例,o=T(i) 称为问题T对应i的解。
计算机只会做一件事,就是自动执行程序。用计算机解决一个问题,就要写出一个解决这个问题的有穷程序(无穷长的程序写不完)。如果针对问题T写了程序P,把T的任意实例i作为P的输入,P的输出总是o=T(i),我们就可以说P解决了问题T。
针对问题写出程序是计算机领域最重要的工作。要完成这种工作,首先要确定一种技术路线(一种方法),确定需要从问题中挖掘出什么信息(知识),怎样利用得到的知识构造程序。参考几十年的研究和实践,本文总结出三类方法。是否还有第四类?请读者考虑。
基于算法的系统(Algorithm-Based Systems, ABS)
这个太显然。但是,采用这一方法有什么前提条件?在什么情况下有可能得到解决问题的算法,并实际写出能解决问题的程序?我们可以提出下面一些条件。
首先,该问题必须是“可计算的”,这是理论要求。证明问题是否可计算常常很不容易,但做出算法就是正面的证明。其次,要做出算法,要求我们对问题及其求解完全理解,知道如何处理问题的任意实例,能处理求解过程中可能遇到的任何情况。
算法的优点是直接针对具体问题,是专用的,因此效率高。另一方面,我们比较容易把算法转换为解决问题的程序,也比较容易判断一个程序是否确实解决了问题。
注意:任何有穷问题都有算法。由于情况(输入)有穷,理论上总是可以对其做穷尽分析,分情况给出解。求解程序如下(假定问题只有n个实例,x是输入):
无穷问题也可能写出有穷算法,例如求最大公约数问题。
现在看看用计算机下围棋的问题。围棋要求对弈双方在19×19的棋盘上交替落子,目标是占据最大的地盘。下围棋程序只需要解决一个问题:对任何棋局,确定下一个棋子的最佳位置。由于局面有穷,本问题为有穷问题。按前面的说法,存在确定最佳位置的算法。基于这一算法的围棋程序绝不会犯错,其棋力不会弱于(昨天、今天或未来的)任何棋手,或任何下围棋的程序,包括AlphaGo和AlphaZero。