「转载」算法的个人认知分享

一提到算法,或许很多人觉得高大上,觉得很复杂。其实算法就是能利用特定方法使得现实问题更加简便的去解决的方法。同一问题的解决,可以有不同的算法完成,算法本身可简便,也可复杂。算法在大部分程序中有着举足轻重的作用。数据结构用来存储实际业务的运算结果,算法用来解决实际应用场景的数据处理过程,实际上编码的本质就是数据结构和算法的搭配。

正如Pascal之父所言,如果说有一个人因为一句话而得到了图灵奖,那么这个人应该就是NicklausWirth,这句话就是他提出的著名公式“算法+数据结构=程序”。

我个人工作这7年多所接触的算法,大都来自于金融量化、策略交易、通信、图像处理和模式识别领域,其他的没有接触过,不敢多做评价。做算法前,首当其冲的是先要做算法准备:举个例子,在做视频的算法时,肯定免不了视频的解码,拿到一幅图像,甚至到了拿到一个像素,才是开始算法本身的工作。而这些工作,对于专注于某个算法的人来说,应该是透明的。而且我相信能独立的编写出从读取视频到获取像素的全部程序的人也不是很多。

国内很多院校研究所,科研机构,喜欢使用matlab。因为matlab提供了强大的函数库,使得复杂的数学运算(尤其是矩阵运算(奇异值分解、插值等等))、图像处理、模式识别等基本算法能够通过函数调用来完成,使得自己能够专注于问题,提出改进的思路。而且对于图像、视频,提供的读写函数自动完成了编解码操作,让我们可以专注于算法本身。但是缺点就是速度慢,对于实时性验证的场合不太适合。也有很多用C写算法的。算法无非就是一个解决问题的办法,输入、输出,使用函数来描述刚刚好。而且,一般对于算法的描述,也是按步骤进行的,与面向过程的思想是相符的。加上C语言较高的执行效率,的确是一种不错的选择。而且,现在有很多库也可以供大家使用,能让程序员专注于解决问题。但是,算法本身也有一些特点,比如参数很多,导致函数的声明非常长。有时我不得不将一些参数、数据结构设为全局变量,要不然难以完成递归的操作。而全局变量使用太多也不是什么好事。

那么什么样的算法算是好的算法呢?

就我个人愚见,大概可以总结为下面几条:

1、算法的正确性

即对于任意的一组输入,包括合理的输入与不合理的输入,总能得到预期的输出。如果一个算法只是对合理的输入才能得到预期的输出,而在异常情况下却无法预料输出的结果,那么它就不是正确的,算法至少应该具有输入、输出和加工处理无歧义性、 能正确反映问题的需求、能够得到问题的正确答案。具体可以体现在以下两个方面:

(1).算法程序没有语法错误,算法程序对于合法的输入数据能够产生满足要求的输出结果。

(2).算法程序对于非法的输入数据能够得出满足规格说明的结果。

2、算法的可读性和确定性

算法必须是由一系列具体步骤组成的,并且每一步都能够被计算机所理解和执行,而不是抽象和模糊的概念。可读性是算法好坏一个重要的判断标准,当然有可能两种算法都可以完成一种功能,一个可能十几行代码可以巧妙的实现,另外一个则可能需要几百行代码,那么哪个更好呢?还需要看可读性,巧妙简洁实现的,可能很难读懂,但是另外一个虽然代码长了点,但是便于理解阅读。那么很可能大家更倾向于接受第二种算法。

3、算法的健壮性

这一点非常重要,一个好的算法还应该能对输入数据不合法的情况做合适的处理。比如输入的时间或者距离不应该是负数等。当实际输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果。

4、高效性

在实际工程项目中,算法高效性是非常重要的,高效的算法能给客户更好的体验度,这一点非常重要,例如,我们做量化交易,1秒几百万,几亿的交易那是再正常不过了,时间就是金钱,0.1ms的延迟,可能导致很大的损失,甚至交易失败。不同的软件在这方面的差异性还是蛮大的。

那么,使用C++来写算法有什么好处呢?

其实C++本来就是C语言衍生过来的,基本上继承了C的所有良好特性,快速高效,但是又比C语言功能强大太多,可以认为C++由面向过程的C语言,面向对象的继承、封装、多态、STL库、泛型编程、C11的智能指针、自动类型推导、正则表达式等新属性。虽然掌握起来本身就不是很容易,用它写算法似乎更难。但是我觉得算法本质上是基于过程的、有具体步骤的,所以我不太倾向于在具体的算法之间使用继承派生关系,更多的时候,只是将算法与算法所操作的数据进行封装,这更像是一种基于对象的思路(带类的C语言)。而泛型编程在算法中的使用可能也不是很广泛吧,特定算法要处理的数据类型往往是确定的,不太可能出现“泛型”问题。而STL库更是大大降低了算法实现的复杂度,对于需要依赖于一些数据结构的算法,STL提供了这些结构的模板;对于算法中的查找、排序等操作,STL库提供了高效的函数可以调用。最主要的是,STL提供了统一的泛型接口,是得他掌握起来非常容易。根据面向对象的思想,我们可以把同类算法抽象合并,极大的减少了编写代码的工作量,而且使得代码更加容易维护。比如我编写过一个在视频中检测运动目标的程序,我是将控制视频的操作,比如起始帧、结束帧,依次读取每一幅图像等封装成了一个类,而将算法本身需要的数据结构、阈值等封装成了另一个类,甚至,对于每个像素需要的数据结构,进行了封装。这样当我们需要对算法进行修改时就非常方便了。而且由于STL库的存在,是得一些简单的问题,比如链表、队列、排序等等可以通过函数来完成而又不失高效。

国内的企业,除了一些大型的企业外,一般很少有的算法团队,大部分科研院所都是使用matlab进行仿真。但是真正使用算法到实际应用中。C++应该是个不错的选择!

「转载」算法的个人认知分享

相关推荐