前三直中多少钱学习算法,

想了解机器学习?这 3 种算法你必须要知道想了解机器学习?这 3 种算法你必须要知道CSDN百家号 点击上方“ CSDN ”,选择“置顶公众号” 关键时刻,第一时间送达! 假设有一些数据相关的问题亟待你解决。在此之前你听说过机器学习算法可以帮助解决这些问题,于是你想借此机会尝试一番,却苦于在此领域没有任何经验或知识。 你开始谷歌一些术语,如“机器学习模型”和“机器学习方法论”,但一段时间后,你发现自己完全迷失在了不同算法之间,于是你准备放弃。 朋友,请坚持下去! 幸运的是,在这篇文章中我将介绍三大类的机器学习算法,针对大范围的数据科学问题,相信你都能满怀自信去解决。 在接下来的文章中,我们将讨论决策树、聚类算法和回归,指出它们之间的差异,并找出如何为你的案例选择最合适的模型。 有监督的学习 vs. 无监督的学习 理解机器学习的基础,就是要学会对有监督的学习和无监督的学习进行分类,因为机器学习中的任何一个问题,都属于这两大类的范畴。 在有监督学习的情况下,我们有一个数据集,它们将作为输入提供给一些算法。但前提是,我们已经知道正确输出的格式应该是什么样子(假设输入和输出之间存在一些关系)。 我们随后将看到的回归和分类问题都属于这个类别。 另一方面,在我们不知道输出应该是什么样子的情况下,就应该使用无监督学习。事实上,我们需要从输入变量的影响未知的数据中推导出正确的结构。聚类问题是这个类别的主要代表。 为了使上面的分类更清晰,我会列举一些实际的问题,并试着对它们进行相应的分类。 示例一 假设你在经营一家房地产公司。考虑到新房子的特性,你要根据你以前记录的其他房屋的销售量来预测它的售价是多少。你输入的数据集包括多个房子的特性,比如卫生间的数量和大小等,而你想预测的变量(通常称为“目标变量”)就是价格。预测房屋的售价是一个有监督学习问题,更确切地说,是回归问题。 示例二 假设一个医学实验的目的是预测一个人是否会因为一些体质测量和遗传导致近视程度加深。在这种情况下,输入的数据集是这个人的体质特征,而目标变量有两种: 1 表示可能加深近视,而 0 表示不太可能。预测一个人是否会加深近视也是一个有监督学习问题,更确切地说,是分类问题。 示例三 假设你的公司拥有很多客户。根据他们最近与贵公司的互动情况、他们近期购买的产品以及他们的人口统计数据,你想要形成相似顾客的群体,以便以不同的方式应对他们 - 例如向他们中的一些人提供独家折扣券。在这种情况下,你将使用上述提及的特征作为算法的输入,而算法将决定应该形成的组的数量或类别。这显然是一个无监督学习的例子,因为我们没有任何关于输出会如何的线索,完全不知道结果会怎样。 接下来,我将介绍一些更具体的算法...... 回归 首先,回归不是一个单一的监督学习技术,而是一个很多技术所属的完整类别。 回归的主要思想是给定一些输入变量,我们要预测目标值。在回归的情况下,目标变量是连续的 - 这意味着它可以在指定的范围内取任何值。另一方面,输入变量可以是离散的也可以是连续的。 在回归技术中,最流行的是线性回归和逻辑回归。让我们仔细研究一下。 线性回归 在线性回归中,我们尝试在输入变量和目标变量之间构建一段关系,并将这种关系用条直线表示,我们通常将其称为回归线。 例如,假设我们有两个输入变量 X1 和 X2,还有一个目标变量 Y,它们的关系可以用数学公式表示如下: Y = a * X1 + b*X2 +c 假设 X1 和 X2 的值已知,我们需要将 a,b 和 c 进行调整,从而使 Y 能尽可能的接近真实值。 举个例子! 假设我们拥有著名的 Iris 数据集,它提供了一些方法,能通过花朵的花萼大小以及花瓣大小判断花朵的类别,如:Setosa,Versicolor 和 Virginica。 使用 R 软件,假设花瓣的宽度和长度已给定,我们将实施线性回归来预测萼片的长度。 在数学上,我们会通过以下公式来获取 a、b 值: SepalLength = a * PetalWidth + b* PetalLength +c 相应的代码如下所示: 线性回归的结果显示在下列图表中,其中黑点表示初始数据点,蓝线表示拟合回归直线,由此得出估算值:a= -0.31955,b = 0.54178 和 c = 4.19058,这个结果可能最接近实际值,即花萼的真实长度。 接下来,只要将花瓣长度和花瓣宽度的值应用到定义的线性关系中,就可以对花萼长度进行预测了。 逻辑回归 主要思想与线性回归完全相同。不同点是逻辑回归的回归线不再是直的。 我们要建立的数学关系是以下形式的: Y=g(a*X1+b*X2) g() 是一个对数函数。 根据该逻辑函数的性质,Y 是连续的,范围是 [0,1],可以被解释为一个事件发生的概率。 再举个例子! 这一次我们研究 mtcars 数据集,包含
年间 32 种汽车制造的汽车设计、十个性能指标以及油耗。 使用 R,我们将在测量 V/S 和每英里油耗的基础上预测汽车的变速器是自动(AM = 0)还是手动(AM = 1)的概率。 am = g(a * mpg + b* vs +c): 如下图所示,其中黑点代表数据集的初始点,蓝线代表闭合的对数回归线。估计 a = 0.5359,b = -2.7957,c = - 9.9183 我们可以观察到,和线性回归一样,对数回归的输出值回归线也在区间 [0,1] 内。 对于任何新汽车的测量 V/S 和每英里油耗,我们可以预测这辆汽车将使用自动变速器。这是不是准确得吓人? 决策树 决策树是我们要研究的第二种机器学习算法。它们被分成回归树和分类树,因此可以用于监督式学习问题。 无可否认,决策树是最直观的算法之一,因为它们模仿人们在多数情况下的决策方式。他们基本上做的是在每种情况下绘制所有可能路径的“地图”,并给出相应的结果。 图形表示有助于更好地理解我们正在探讨的内容。 基于像上面这样的树,该算法可以根据相应标准中的值来决定在每个步骤要采用的路径。算法所选择的划分标准以及每个级别的相应阈值的策略,取决于候选变量对于目标变量的信息量多少,以及哪个设置可以最小化所产生的预测误差。 再举一个例子! 这次测验的数据集是 readingSkills。它包含学生的考试信息及考试分数。 我们将基于多重指标把学生分为两类,说母语者(nativeSpeaker = 1)或外国人(nativeSpeaker= 0),他们的考试分数、鞋码以及年龄都在指标范围内。 对于 R 中的实现,我们首先要安装 party 包: 我们可以看到,它使用的第一个分类标准是分数,因为它对于目标变量的预测非常重要,鞋码则不在考虑的范围内,因为它没有提供任何与语言相关的有用的信息。 现在,如果我们多了一群新生,并且知道他们的年龄和考试分数,我们就可以预测他们是不是说母语的人。 聚类算法
到目前为止,我们都在讨论有监督学习的有关问题。现在,我们要继续研究聚类算法,它是无监督学习方法的子集。 因此,只做了一点改动...... 说到聚类,如果我们有一些初始数据需要支配,我们会想建立一个组,这样一来,其中一些组的数据点就是相同的,并且能与其他组的数据点区分开来。 我们将要学习的算法叫做 K-均值聚类(K-Means Clustering),也可以叫 K-Means 聚类,其中 k 表示产生的聚类的数量,这是最流行的聚类算法之一。 还记得我们前面用到的 Iris 数据集吗?这里我们将再次用到。 为了更好地研究,我们使用花瓣测量方法绘制出数据集的所有数据点,如图所示: 仅仅基于花瓣的度量值,我们使用 3-均值聚类将数据点聚集成三组。 那么3-均值,或更普遍来说,k-聚类算法是怎样工作的呢?整个过程可以概括为几个简单的步骤: 初始化步骤:例如 K = 3 簇,这个算法为每个聚类中心随机选择三个数据点。 群集分配步骤:该算法通过其余的数据点,并将其中的每一个分配给最近的群集。 重心移动步骤:在集群分配后,每个簇的质心移动到属于组的所有点的平均值。 步骤 2 和 3 重复多次,直到没有对集群分配作出更改为止。用 R 实现 k-聚类算法很简单,可以用下面的代码完成: 从结果中,我们可以看到,该算法将数据分成三个组,由三种不同的颜色表示。我们也可以观察到这三个组是根据花瓣的大小分的。更具体地说,红点代表小花瓣的花,绿点代表大花瓣的花,蓝点代表中等大小的花瓣的花。 在这一点上需要注意的是,在任何聚类中,对分组的解释都需要在领域中的一些专业知识。在上一个例子中,如果你不是一个植物学家,你可能不会知道,k-均值做的是用花瓣大小给花分组,与 Setosa、 Versicolo r和 Virginica 的区别无关! 因此,如果我们再次绘制数据,这一次由它们的物种着色,我们将看到集群中的相似性。 总结 我们从一开始就走了很长的路。我们已经谈到回归(线性和逻辑)、决策树,以及最后的 K-均值聚类。我们还在R中为其中的每一个方法建立了一些简单而强大的实现。 那么,每种算法的优势是什么呢? 在处理现实生活中的问题时你该选择哪一个呢? 首先,这里所提出的方法都是在实际操作中被验证为行之有效的算法 - 它们在世界各地的产品系统中被广泛使用,所以根据任务情况选用,能发挥十分强大的作用。 其次,为了回答上述问题,你必须明确你所说的优势究竟意味着什么,因为每个方法的相对优势在不同情况下的呈现不同,比如可解释性、鲁棒性、计算时间等等。 在目前只考虑方法的适当性和预测性能情况下,对每种方法的优缺点进行简简单的总结: 现在,我们终于有信心将这些知识落实到一些现实问题中了!本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。CSDN百家号最近更新:简介:CSDN精彩内容推荐作者最新文章相关文章Posts - 36,
Articles - 0,
Comments - 190
What hurts more, the pain of hard work, or the pain of regret
17:00 by curer, ... 阅读,
不得不说,有时候无知是福,看到一点有趣而深刻的东东,就能感觉到神奇。越是我们熟悉的东西,往往却是我们进一步理解深刻的障碍,而之所以是障碍是我们并不知道这个是我们理解问题的障碍。困惑中的每一次豁然开朗往往是从一点一滴的我们已经成为惯性思维中开始。越是深刻的原理,往往越是简单强大。就像爱因斯坦打破牛顿给我们原有的世界观一样。对于一个打破常规,让你重新理解问题的最简单的方法就是把你整个思考的前提否定。而带来的结果就是我们看问题的角度,层面有了更大的扩展。所以,有时候知道的太多反而不美,做一个白痴也很幸福。
哎,又无病呻吟了半天。之所以有上述感想。还得感谢自己的同学。由于我没有看过MIT的经典课程《算法导论》而被鄙视,而且更无语的是,我的理由是&听不懂,如果有老师的课堂发音的记录&,而事实上。这个MIT早就提供了,为了照顾想我这样的听力不好的家伙。好吧,我是个白痴,不过就像上面讲的,白痴也有白痴的幸福。这个假期,无聊的时候,不仅可以看《爱情公寓2》也可以屡屡自己的数学常识了。:)
《算法导论》是一名研究算法设计的课程。设计算法,我们关心的主要是2个方面,一个是性能,另一个是资源花费。当然,我们重点的是性能,我们总是希望我们的程序跑的更快。那么学习算法到底有什么用呢?这是一个经典的问题。Charles Leiserson 是这样给我们解答的。首先,列举了一大堆在实际编程中比性能更重要的东西:可维护性,模块化,功能,用户体验等等。特别是用户体验,那么既然有这么多的东东比算法重要,那么为什么我们还要学习算法呢?
算法决定了可行还是不可行。
在一些实时的情况下,比如机器人等嵌入式设备,我们不够快,那么就没有意义,如果我们用了太多的内存,同样不行。所以,算法这个东东,总是在我们计算机领域的最前沿部分,如人工智能,搜索引擎,数据挖掘。如果我们是在做10年前就已经实现了的东西,那么性能的确在一些情况下已经不重要了。但是,如果想做一些别人没有做过的东西,真正的实现从无到有的过程。那么其中遇到的绝大多数问题都是,数据太复杂了。没有能力在有限的资源下找到答案。这也就是为什么叫计算机科学,而不是计算机工程。(当然科学这个和名字是无关的,比如物理,从来没有那个学校叫个什么物理科学什么的。:))。不得不说,MIT的目标是为世界培养leader,而我们那破学校是为了培养farmer(这里并没有不敬在里面,而且事实上,做一个farmer挺好的,每年坐在家里,收个房租,年末村里再分个几十万,比那些城里白领好多了在物质上)。其实也不那么绝对,非要改变世界,只要是之前没有做过的程序,我们在实现之前,首先思考的一定是算法。其次,则是对他不断的优化,完善。
对绝大多数的刚刚参加工作的同学,往往不能体会到整个产品的创建过程。参与的仅仅是完善,算法的设计或是大体设计已经完成,所以感觉不到算法的存在。而匆匆下了学校白学的定论。而随着工作时间变长,总会遇到没有或是不能直接利用原有设计的东东,那么算法也就体现出价值了。
算法是一种描述程序行为的通用语言。
我们可以通过算法去描述程序的运行流程,在任何地方。他不仅能在实践中得到体现,也能在理论中得到证明。而且能够得到大家一致的看法。而这是别的永远无法做到的,比如用户体验,每个人都有自己的想法,我们不可能让所有人都满意我们的设计,而算法却可以做到,因为快就是快。放到计算机上一跑结果自知。别人无法击败你,即便是再挑剔的对手,只要你足够出色。而能够满足这样条件的前提就是,算法是一个如此一般化,基础的东西。就像Charles Leiserson 所讲,算法就像钱,你可以用钱去买吃的,喝的。而衡量这些花费的就是钱的数目。在计算机上,则是,选择一个这样的策略,需要花费多少。选择另一个策略,需要花费多少。而衡量这2个选择谁的花费多呢?是算法。
算法在计算机中的地位,就和数学在所有理科学科中的地位一样。我曾经问过我的数学老师一个问题,他的回答让我直到现在还记忆犹新。&老师,数学在您眼中是什么呢?&&数学是所有理科中是最奇妙的一个。因为他可以独立于其他任何学科存在而其他学科离开不了数学。&是的。能够想象物理化学离开数学之后是什么样子么?但是数学为什么能够独立存在?是因为他构建了一门语言,一门伟大的语言。使用这门语言可以让知识在任何领域中环绕,学好数学就好像有了一张无限透支的通用支票,可以在任何地方花费(黄金?)。作为一个可以让这么多地方都通用的原因中最重要的就是,他是超级稳定的。是一个说一不二的世界。一个公平的世界,绝对的世界(当然,现在数学这个概念也不准确了,这个充分体现了哲学思想,有正必有反啊:P)。他所确定的东西的结果是肯定的。没有歧义,而且不随时间变化而流动。比如,我们真实世界中交流的语言,比如&忽悠&,&猥琐&。等等。很多词义,随着时间的变化而改变了。使得很多年纪大的人,和我们这年轻人在交流上就产生了隔阂。而我们最熟悉另一个例子就是文言文,特别是其中的一些扭曲的字。但数学这种基础类学科是不会的。至少在一个可以预见的范围是稳定的,没有地域限制的。所以,数学才能站在人类科学发展的最前沿,他的每一次前进的一小步,都能改变世界。这就是数学之美。同样也是自己能够让绝大多数人接受的最大障碍。由于他改变的太慢,而且枯燥。绝大多数人无法深入的理解。当用世俗,腐烂,充满铜臭,功利的眼光看待纯净的数学世界,必然发现数学无用。而且,这的确是事实,因为大部分人,都不可能成为改变世界的家伙(这里的确不准确,因为改变世界话题太大,修理地球同样也是改变世界。)。
算法,同样为我们计算机构建了一个纯净的世界。一个说一不二的世界,他所确定的,没有能够反驳的。当然,就和学习数学一样,我们不是去成为数学家,学习物理,不是去成为物理学家,然后去做哪些能够改变世界的东西。学习这些基础类学科的重要在于,他提供了一个让我们和那些站在人类史上最顶尖的家伙们交流的语言,从我的角度来看。如果没学好数学,能够和牛顿,爱因斯坦交流么?没有学好算法,能够和高爷爷交流么?作为一个普通人,我们只要学习到他们身上的一点点,也就足够了。当然,这不是对所有家伙都有效,有些人总是想,和那些老家伙有什么好交流的,给我一个周杰伦的签名吧。:)
学习算法还有一个原因,是的,就是兴趣。这个传说中最牛X的老师。
喜欢算法,没有别的原因,是的。我就是喜欢比别人快速的感觉。喜欢数学,是的。因为大部分人数学不好。所以我就喜欢数学。迎难而上,哥就是喜欢做别人做不了的东西。是的,虽然听上去很牵强,而且比较扭曲。比较符合印象中90后的想法。不知道90后是不是能产生更多的数学家呢?
让我们回到我们的算法上,既然我们这么关注性能,那么什么是影响性能的因素呢?
对于一个计算机外行来说,首先就是计算机硬件本身的运算能力。多一个超级牛的CPU,超大的内存,固态硬盘。肯定运算快。的确,如果你拿一个超级计算机和地摊上买的一个小的计算器比运算能力。这个实在是一个很显然的结果。是的,所以,我们有些情况下,需要思考在相同条件下,到底哪个算法的性能更高。这比较的是相对速度。但是我们却不能忘了这一点。有时,我们想使用一些很一般的计算机,通过优秀的算法,来打败那些拥有更高硬件的那些家伙们,而我们则必须关心算法性能的绝对速度。那么我们该如何描述这些看似互相矛盾的东西呢?不要忘记,算法可是基础啊,我们要的是一个确切的答案。我们如何给出一个确切的答案,而这个答案不管是超级计算机,还是普通PC都能够支持呢?这就是算法中最重要的一个概念,甚至是一切分析的大前提,一个可以把这些复杂的因素都考虑在内(或是都不考虑在内)的东东转换为可以用数学分析的对象。这就是渐进分析。
渐进分析的基本思想是
忽略硬件结构
不使用真实世界的运行时间,而是关心运行时间的增长速度为对象
渐进分析是一个非常庞大的概念,我们最熟悉的,也是大多数本科院校教我们的就是&T,O,&O等等类似的这些符号。这里只从&T开始。
对一个初学者,&T-notation是比较容易接受的。对一个多项式,我们只需要删除掉所有的低次幂项,忽略掉常数,系数这些次要因素。就和Charles Leiserson 所讲的。这个描述,是工程方向的描述,并不是严格的数学上的定义。而对像我这样的小白来说,最大的误解就是把他当成了数学上的严格定义而产生了极大的困惑。
这个是一个相当经典的图,当n趋于无穷大时,&T(n3)总能干掉&T(n2)。不管是同样的硬件设备,还是不同的硬件设备。只是在不同的设备下,不同的算法下,我们有了一个不同的系数,低次幂项,和常数。但是,我们关心的是他随着数据输入长度的变大而产生的增速。当n超过n0时,任何的次要因素都是浮云了。我们就可以说&T(n3)被&T(n2)干掉了,即使&T(n3)的硬件要比&T(n2)好很多,在一开始的时候效率有多高。
这是一个伟大,cool的概念。是的,他完美的既满足了我们追求的绝对速度,也能满足我们追求的相对速度。可以说,这给了我们继续学习算法的动力。但是,事实上,在实际开发中,我们有时候却使用那些在学校中认为是效率低的算法。难道这个理论错了?当然不是,错的是我们,我们忽略了一个很大的前提,n0。在我们多数开发过程中,很少接触那些海量数据的运算。我们的运算多数是在一个较少的数据上下浮动,这个也可以说我们的硬件,资金,产品,根本不需要我们整那么大的数据。也就是n0,我们根本达不到。事实上,只要是有脑子的,看到这个图,在小于n0的前提下,都会做成正确的判断。但对于刚刚步入IT的广大学生,却总是犯下屁股决定脑袋这样愚蠢的选择。而这其实,就是做科学和做工程师的最大区别。理论和实践相互掰手腕的结果。
这几天,挖老赵的&坟&,找出了这么一篇。里面有一段十分搞笑的代码,之所以这样说,是因为我自己也写过这样的代码。想想真是dt啊。回想事发现场,我记得是我看了个什么类似《面试宝典》东东,有一些题考察交换元素,事实上,你可以找到一大堆的,而且是更精妙的去交换2个元素。看到之后,如获至宝。只要是2个元素要换位置,就用。站在做科学的角度上看,这无可厚非。但是如果站在工程的角度来看。这就是明显的画蛇添足。往往花费80%的精力在提高%20的性能上,而不是去花费20%的精力提高80%的性能。这同样是刚刚步入IT的广大同学的问题。做科学需要严谨,但是在工程方面,考虑的事情非常复杂,多。我们必须要关注在核心,关键的部分。这样才能在有限的资源下,最大的做出东东来。实践中,没有任何项目的资源是足够的。MS,Google都会有资源不足的时候。我们需要学会抓住重点。当然这里并没有鄙视这些面试问题,事实上,这些问题的背后往往是考察数学思维的基本功,而不是鼓励大家这么做。就像那个经典的问题,12个小球一架天平。没有仔细,严谨的思考,能够想到这个东东能和排序问题扯上勾么?神啊,万恶的功利,给完美的数学模型批了一层邪恶的外套,使我们在追求本质的过程中迷失。
有关n0的问题,不仅在算法设计上,也出现在我们的设计模式之中。《设计模式》这本神书,我是没看过,也不敢看。但也隐隐感觉到类似&设计过度&的言论。这同样都是在理论和实践结合上出了问题。当然,不少理论支持者,肯定会说,那是因为你没做过那么大的项目。但事实却是,不管设计多么复杂的,还是多么简单的,实践和理论永远不可能都得到满足。windows操作系统可以说是一个我们可见的最大的项目之一了。但是windows也并不是一个微内核,在内核中也绑定了非常多的&多余&的部分从理论上看。那无疑会降低系统稳定性,提高维护难度。但是我们却不能不说windows是最成功的一套软件之一(这个之一甚至都可以去掉)。
当然,要想在做学问和实践找到平衡点。这个无疑是极大的挑战。只是分析理论,而不实践,那么永远不可能成为一个出色的工程师。除非你的目标是成为理论科学家。反过来,如果不理论而只是实践,不同的是,这个是可以成为一个出色的工程师。所以,这里有一句经典的话。
If you want to be a good programmer, you just program ever day for two years, you will be an excellent programmer. If you want to be a world-class programmer, you can program every day for ten years, or you can program every day for two years and take an algorithms class.
既然算法是如此的重要,那么我们该如何学呢?其实,这是一个很纠结的问题。甚至是一个鸡生蛋,蛋生鸡的问题。不学算法,你不会了解他,也不会认识到算法重要,反而。认为算法不重要,那么也就不会下功夫去学。这就又回到一开始的那个unknown unknown上了。所以,如果准备学习算法,也就意味着选择了一条坎坷的路。一开始特别迷茫,但是没有别的选择。唯有坚持,放下浮躁,功利的心态,沉浸在数学的世界中才能体会到数学的价值,数学的乐趣。也只有这样,才能坚持到最后。
当然,能做到这一点的,敢说体会到数学之美的家伙,全世界也没有几个人。那么作为一个普通人,我们怎么才能最大的去提高自己,更好的掌握实践和科学的平衡点呢?这个问题,我自己也没有答案。因为我既没经验又没理论。这里只是扯下我自己的理解,可能很偏激。
首先应该研究下的很多博客内容,特别是。对我这样的新手来说,武器真的太少了。所以当捡到一个武器往往过于兴奋而忽视了这个武器的使用前提,往往杀鸡用牛刀,而且还达不到积极的效果。就是因为我们拿到锤子之后,所有东西看上去都像钉子。所以,我们唯有摆正心态,深入了解拥有的武器,并增加更多的武器,见更多的市面,才能坐怀不乱,达到手中有锤,心中无锤的最终境界。
一个稍微实际的例子。对像我这样的菜鸟来讲,大部分都会遇到这样一个问题。而且困惑很久很久。&堆排序为什么比快速排序在大多数时要慢呢?&事实上,造成这个问题的主要原因(对我)就是,没有理解明白&T-notation。那些被忽略掉的次要因素,当然还有更重要的是数学上对概率的薄弱理解。然后我们会再映射出一大堆的数学基础知识,然后大部分人死在沙滩上(真的,这是我从小以来最大的遗憾,就是没有学好概率,而造成这个的原因居然是,这些题目初学时往往是用日常用语出题,而由于本人语文太差,总不能理解清楚题意,而对这类题目产生了极大的抵触,可见小朋友们千万不要偏科:P)。从科学的角度去,完全可以证明这个问题,但是付出的代价就是没有硕士以上的数学能力的玩家,没有机会理解到那个层次。那么,其实我们可以从另一个角度看,直接放到计算机上跑一下就可以了么。是的,我不是科学家,我只需要知道结果就OK了。是啊,好在我们处在一个和谐的世界。让我们从这个庞然大物中得以解脱,所以,有时,我们需要根据自身情况,放弃一些东西,特别是那些比较能够通过实验来证明的东西。
好吧,总不能啥也放弃吧,都放弃了那到底也简单了。这里,我只能说,我推荐SGI STL。在我看来,这是一个结合了设计模式,理论算法与实践最好的一个实例。他不仅是开源的,代码量也不多,命名也算规范,而且还有一本侯捷大师的著作来诠释,帮助我们理解,而且还能帮助我们具体实践过程中规避一些错误。我们每一个在学校学习的算法,我们都可以在这里找到答案(至少可以用来做作业拿高分对某些特别的女生),而且都会比一般大学讲的深刻,事实上,我认为,大学现在的教育为什么觉得无用,不是太难太理论,而是教的太简单了,简单到已经没有用的地步了,从而根本没有实际意义。(大学联合培训机构,是我所见过的,比大学扩招还要搞笑的事情)比如快速排序,SGI STL做了非常多的优化来保证无论在什么时候,都不会退化到n2,在分的过程总是分不好时,采用堆排序。在快速排序到做最后几步,为了减少开销而采用插入排序去做哪些马上就要排好序的部分。而这些策略,并不是凭空想象,都可以在高爷爷的著作中找到理论证明,以及网上的各种论文,前提是你的数学功底足够(当然这里实践在前还是理论在前这个实在是没有讨论的意义)。所以,理论不是没有用,只是自己学的太肤浅。实践也不是没有用,只是自己没有考虑那么多的情况,想的太简单而已。
当然,这个可能又会引起另一个庞大的问题,&不要重复制作轮子&,不过这个已经大大超出这篇文章的范围了。我自己的看法是,STL是为了实现最基本的最通用的东东的,而实际过程中,我们往往有自己的特殊性。而这些特殊性是STL不可能设计时都给我们考虑周全的。也就是我们很可能需要扩展,重写部分以适合我们的需要。当然,现在离这些目标还很远很远很远。

我要回帖

 

随机推荐