人们为什么会想到设计算法?或者设计“更好”的算法?
首先,这位算法工作者一定是看到求解某个数学模型的算法存在的弊端,实际当中有些数学模型的求解直接用的是最暴力的枚举,这是“零算法”思想的粗鲁的问题求解方式。
怎么去评估别人的算法的好坏?
每个算法都有自己的核心设计思路,例如:贪心思想,动态规划思想,启发式思想,连续松弛思想,近似算法(因为原有算法在时间复杂度和空间复杂度不能达到实际应用需求,那就要在原有算法各个关键的实现环节做“近似”,目的是牺牲最少的解的精度来换取原有算法在时间复杂度和空间复杂度的最大的改善。)
那么,当你看一篇算法文章时。你一定是按以下思路去看和思考的。
一、这篇算法要求解什么模型
二、原来求解这个模型的现有算法,比较受学术界认可的(在同领域Introduction被反复提及的算法)有哪些?
三、作者对原有算法的优缺点分析(注意,这只是作者的观点,你可以本着“怀疑”的眼光,用自己的经验,知识和一些别的作者的看法来检验)
四、作者所设计的算法的核心思路是什么?(这个算法主要是贪心思想,动态规划思想,启发式思想,连续松弛思想,近似算法中的哪一类?)
五、你自己要先思考,如果是你,面对这样一个待求解的模型,用某个算法思想,比如:贪心思想或者动态规划思想,大概是怎么做的?
备注:首先你要尝试在这个算法框架中找到最完美的解决思路,比如你找到了一个你觉得最好的动态规划算法来解决这个问题。但是呢,如果这么做,算法的时间复杂度仍旧无法让人满意。那么你将把这个动态规划算法拆解成一些算法关键细节,看看哪些细节是可以用某种近似思路去做一个好的逼近的,这样既很大程度上完成了原来的工作,且算法时间复杂度大大降低了。思考这些问题,可能会产生更多的问题,没关系,读文章问题越多越好,然后觉得差不多了,就可以暂时把这个问题放放,进入下一个阶段。
六、去看看作者在一个主体思路中(比如说是近似动态规划)中的一些关键的细节上都是怎么实现的。
他分析别人算法的优缺点后,他自己的算法有没有继承别人算法的优点,克服别人算法的缺点,他在算法的各个关键细节上具体都是怎么做的?对于作者的这些做法,你是否赞同,你应该去尝试问自己一个问题:这样做是最好的吗?如果不是,怎么做会更好?或者怎么做,可能会更好?(为什么加“可能”,因为根据以往的经验,我们都会积累下一些好的“直觉”,这些“直觉”根据各人学术功底的强大与否而不同,学术功底强大的人,“直觉”一般都很准。怎么回答一定会更好呢?这个问题必须用严格的数学证明完成,这部分工作早晚都要做,因为一旦“直觉”经实验论证后是对了,还是需要通过数学理论来证明确实是对的,这部分理论也是你将来投到一个好的期刊的关键。)
七、如果经过分析后,发现作者在算法设计上和理论上确实都很不错的点子,可以找个“好本子”(终生携带),记下来。
八、去查看作者的模拟实验结果,看看这些结果有没有把作者口中的他这个算法的“好”、“贡献”全部展现出来,除此之外,如果认真查看实验结果,往往也会有额外的收获。
比如:对比的算法往往非常多,你不但可以比较作者的算法和其他算法之间的优劣,还可以借助作者的实验,大致了解现有的其他算法之间的优劣。但是,模拟实验并不就是真相。就算这个作者没有提供假的实验数据和实验结果,也还存在一些问题。例如:
a、不同的实例,数据分布特点不同,所以并不是这个算法真的比其他算法好,只是他在他提供的实验案例集合里“看着最好”。
b、每个算法都有很多“超参数”,参数调得好,直接影响算法的效果。作者一般都会针对现有的实例数据,把自己的算法经过非常仔细的调 参后,使得自己的算法的这组参数跟自己文章中的实例数据最匹配。但是,很有可能他不会去给他要对比的“竞争对手”的算法做这个辛苦的调参。所以多多少少存在一些不公平,他实验所展示的他的算法性能的优点也要打点折扣。面对这些,我们应该以辩证的态度更加客观地去审视作者提供的这份报告。如果把作者的算法比作一个产品,最后的实验报告就是他这个产品的小广告,我们都知道广告中产品的效果实际当中都是打折扣的。所以,这个算法真的咋样,需要时间去考验。比如,有很多跟随者,相信作者的结果,并将作者算法应用于别的场景,这时算法所要面对的数据实例就改变了。如果有很多人在不同的场景都验证了这个算法确实不错,那么我们应该加强对他的信心,但是还是不能全信,没准哪一天有一个作者的刺头(敌人)专门构造一个反例数据,使得这个算法在这个反例数据上效果极差。谈到这里,算法的理论就显得格外重要了。我怎么保证我的算法有效性覆盖面足够广,怎么避免受到敌人的攻击呢?——其实只要提供一个保证算法效果的理论就行了,而且这个理论的假设条件要尽量少,尽量比较弱(这样算法的覆盖面才会广),结果要尽量强。这一点说说容易,做起来非常难。目前绝大多数算法都是缺少一个真正能够说服别人的理论体系,使得很多人对其结果都半信半疑。
九、做到前面八点,你基本是一个合格的算法工程师了。第九点就是从算法工程师上升为算法学者的关键。算法整个思路都明确了,并且实验也验证了算法确实不错。也推出了一些零零散散的理论结果,现在就是整理这些理论结果来完成以下理论体系的构建。
a、算法是否收敛?
b、算法收敛到哪里?(是一个不动点?还是一个局部最小?还是全局最小?是否收敛到子问题或者近似问题的最小点还是原问题的最小点?如果不是原问题的最小点,那么你最后到达的这个点离原问题最优点多远?是否满足一定条件后,这个收敛点会成为原问题的最优点?比如:当样本量无限大时,有些统计模型的算法就可以以概率1找到原问题最优解。)
c、算法的时间复杂度?算法的空间复杂的?(目前绝大多数文章只分析时间复杂度?分为离散优化时间复杂度和连续优化时间复杂度两种。我个人暂时没理清两种复杂度是否可以统一归结为同一种。我们看连续优化文章时,看到一个算法的复杂度是1/e时,表示这个算法要达到前后两个迭代步对应的目标函数差为e时,需要迭代1/e步。我们看到这种复杂度不涉及问题的规模,它将算法中核心的矩阵数值计算打包作为一个“基本迭代步”,所以它是一个不完善的复杂度估计。如果要将它完善化,还要乘以算法中设计到矩阵数值计算的“基本迭代步”相对于问题规模(n)的一个复杂度函数。离散优化算法复杂度则是一个完善化的复杂度估计,通过它是问题规模的函数f(n),主要分为多项式时间复杂度和非多项式时间复杂度,其中多项式时间复杂度中比较特殊的是线性时间复杂度。我们做算法的核心工作就是找到一些求解NP难问题的近似比高的多项式时间近似算法,甚至是找到近似比比较满意的线性时间近似算法。能够正确理解算法复杂度,也为已经能够跑出不错结果的程序的“提速”方案设计提供了理论支持。首先,一个好的初始解带来的好处是使得复杂度函数f(n)最大阶的系数变小了,这在解决超大规模问题时,也是改进相当明显的。其次,我们注意到学好数值优化/计算数学的必要性,他可以让你连续优化算法的内核——矩阵数值优化这个“基本迭代步”计算效率更高,内核复杂度变化一点点,整个算法的运行效率一下子就上去了。再离散优化算法设计时,我们也会把更多的精力放到子问题的高效求解上。总的来说,要想写出的代码速度快。搞定初始解,搞定计算“内核”/子问题求解,搞定并行计算,只要这三项都做得很不错,算法速度也就基本被提升到极致了。)
理论证明框架都是大同小异,但是阐述手法有区别。
数学功底深的行家会站在巨人的肩膀上思考,引用一些既有的好结论,几句话就证明 完一个定理了。当你读这种文章时,如果你也是理论功底深厚的行家,那读着会有美感,会觉得这个定理的结论和证明手段都散发着绅士的优美。对于数学功底不好的优化界散兵,比如说我这种,将会是非常痛苦。要读懂他一个证明,我还得先去了解那些我没见过的引理,有些引理波及的知识压根没学过,不怪任何人,只怪自己太渣。
还有一种是偏工程的学者写的,这种人数学功底一般,不会很熟练地就找到一个非常恰当的引理作为证明路上的垫脚石,他的路子比较
平,从最基本的条件出发一步一个脚印去证明,这种证明一般比较长。看这种理论结果,不需要强大的数学功底,数学界的散兵也是可以
的,跟踪作者的逻辑一步一步推导直到最终的结论。
算法推导中会有很多“估计”,就数学的角度去看就是一些不等式。所以,学优化的人想要理论过关,必须要熟练线性代数、矩阵分析、数学分析、还有不等式。有专门的不等式方面的书,收集了各个领域出现的常用不等式,例如由山东科学技术出版的匡继昌的《常用不等式》。不等式学好了,做算法理论都顺风顺水了。等式换算就是一步一步等过去就行了,只要基础扎实没有技术含量。不等式就不同了,在不等式放缩过程中,参杂着很多“构造性证明”的思想,非常丰富多彩,技巧性非常强,非常有意思。你的在不等式放缩的中间过程的功底和技术的好坏直接影响你最终算出来的估计界。如果不等式玩得好,还可以知道,加入哪些理论条件可以让估计更加“紧”,而这些额外添加的理论条件恰恰也可以作为算法进一步改进的思路。
以上就是我对如何看算法类文章的浅薄观点,勿喷,谢谢!
这里也不妨再谈谈如何去看统计学模型的文章。
1:首先搞清楚这个模型是在什么背景下抽象出来的,是为了解决什么问题?再加问一句:这样建模,达到目的了吗?是不是最好的模
型?有没有更好的建模思路?
2:其次直接看这个模型的理论是不是完善。就拿统计优化类文章举例:该模型在样本矩阵X列正交时,其估计是否具有稀疏性、无偏性、
连续性。(这是Fan给出的判定标准,也有很多学者认可这种标准)模型是否具有Oracle性质,即当样本量无限大时,模型的最优估计是否无限逼近真实的模型。
3:作者选了什么算法实现了他的模型?选算法时是有些想法的,还是胡乱选,把学术界鼓吹的最好的,且能够求解自己模型的所有算
法,挨个试一遍,选出一个最好的?或者作者直接根据自己的想法选了一两个适用算法,那他的选择是正确的吗?有没有更合适的算法?
4:很多统计学者不自己设计算法,直接调用现有算法求解自己模型。但是有时候自己模型跟现有算法的输入有点差异,需要一点点转
化,从而让自己模型可以通过调用现有的算法来求解。那这种转化是不是最好的呢?有没有更好的呢?
5:一个好模型如果找了一个不太好的算法,那么单从数值试验结果来看,该模型基本没有实际意义。这样一来,我们很难判断一个新的
模型是否真的有意义或者有价值。最好的做法就是提出了一个新的模型,并且用了一个最恰当的算法实现了它,再数值模拟实验中PK掉了
现有的所有其他方法,数值实验效果和理论体系能够很好地交相呼应。那么一旦这样的文章发出来,会更加容易得到更多的学者的认可,
也让大部分学者能够对作者所提的模型的意义能够更加容易地做出一个好的判定。