算法设计 -- 初步感想

算法设计:

1.对于一个给定的问题,分析问题的构成要素,限制因素,目标

2.对于问题进行分析,分出相应的步骤,然后实现各个步骤

 (:(1)先排序,(2)然后才能用二分查找)


算法的理解


     数据结构的重要性就暂时不在这里讨论了,我们这里需要讨论的是算法
     算法的本质是指令序列,同时其应该是可以终止的(图灵机)。为什么是需要可以终止的?这是因为我们将 可终止性作为算法的一个本质特征,定义在算法中的,这是来源于实际意义的,如果不能终止,那么该算法将失去意义,意味着算法将无法得到确定的答案,这就违背了设计算法的目的。


算法的设计的流程
  • 确定目标(解决什么样的问题?)
  • 确定约束条件(都有哪些约束条件?已知条件?)
  • 确定解决方案(核心部分)
  • 验证解决方法正确性

附:
这里我们采用数学的思维来理解这些问题,方程给了我们理解问题的一种框架(当然还会有其他的框架)。


1.确定目标

     确定目标,将我们的问题聚焦,从而找出所有与目标相关联的成分,所有对于目标有影响的成分。进而引入约束的部分。(之所以强调这一点,是因为如果目标一开始就定错了,那么你后面的一系列工作,约束的选取都会带入大量无关的成分,同时损失一部分有价值的信息,进而会影响到结果)
     确定目标是十分关键的一点。
     当我们进行网上的算法练习的时候,你会发现这些题目明确给了你目标,并且他所提供的约束中也都是围绕此目标的限制,因为我们不需要有太多的顾虑。(如,下面的题目1)
题目1(选自leetcode)
  • 【目标】求二进制数组中,最大的连续1的数目。
  • 【已知】输入的形式,输出的形式。
  • 【没有干扰】这个题目中是只含有与题目相关的内容的。(事实上,很多这种练习题目都是没有干扰的)
算法设计 -- 初步感想_第1张图片

     但是,在实际中,事物往往是十分复杂的。这个确定目标的工作会由你来完成,这就需要你具有能够抓住关键问题的能力,抓住主要脉络,剔除不相关的成分。(简化问题,简化模型
     

2.确定约束条件

      目标一旦确定,确定约束条件的时候,我们有时候仅仅需要顺藤摸瓜即可,与目标关联的保留,无关的剔除,这样一种朴素的方式可能就会将我们关注的约束给保留了下来。(类似于某种可达性的方式)
     举一个简单的例子,仍然是上面提到的题目1.我们之前已经知道了目标是求 二进制数组中连续1的最大的数目。接下来让我们来看看,这些目标和哪些东西有关呢?首先,目标的求解是依赖于一个二进制数组的。其次,目标的求解对于数组中的内容也是有一定限制的,比如说连续的1,并且统计其最大的数目。等等,通过一系列与目标相关的追踪,我们提取出与此问题相关的限制。
     当然,并不是所有的约束的追踪都是可以用这种方式得到的,比如说一些约束是隐性的,一些约束是常识性的。这些都不在这种朴素追踪约束的范围内,这里希望能够起到抛砖引玉的作用,希望能给人以启发。

3.确定解决方案

     当我们真正弄清了问题的模型的时候,(这里我们说是问题的模型,是因为我们对于问题进行了抽取,简化,补充等等,使得我们可以更加清楚的认识问题。模型是认识问题的工具),接下来我们想要做的是,寻找问题的解决方案。
     【朴素的做法】我们寻找问题的解决方案的时候,通常我们首先会想到的是非常朴素的做法,然后一般朴素的做法都是非常代价大的,这其中还会涉及到很多细节。有时候我们采用朴素的做法去做的时候,会发现一些问题要考虑的情况实在是太多了,需要的代码数量太多,并且我们能明显感觉到有简化的空间。
    【优化】发现朴素的做法是存在很多问题的时候,我们就应该反思自己的认识了,很多时候是因为我们不同层面的认识导致了不同的解决方案。对于问题的认识是什么样子的?如果在你的认识中,问题是复杂的,那么你所提出来的解决方案一般也是十分复杂的。反之。
     举个简单的例子,你看到了一个数字5,如果你认为是1+1+1+1+1 = 5,那么这个问题被你分成了5份来考虑。如果你认为2+3 = 5,那么这个问题被简化成了两份。第一种情况,你将会使用加法5次,第二种情况,你将会使用加法一次。
     总之一句话,你能否用简单的规则理解事物,决定了你能否提出简单的解决方案。
     
附:
     事实上,那些关键的算法思想,都是人们智慧积累的结晶。算法思想包括,贪心算法,分治法,动态规划,回溯法等等,这些东西都给予了我们一种理解问题,解决问题的框架。(即,用这些思想问题将会被简洁的描述,进而解决方案也会变得十分优雅高效)

4.验证解决办法的重要性

     检验一个算法的正确性,是有很多途径的。比如说测试,定理证明等等。

     目前使用最多的是测试,但是测试应该算是一种估计上的验证,通过验证部分数据,来得出结论,结论是可能的,而非必然的。(这方面的内容可以参看软件测试方面的一些文章)

     至于算法的正确性的证明,则是从逻辑的角度来论证这个问题。更具体一点,将你的算法转化为数学问题,然后利用反证法,数学归纳法等方法来论证该算法的重要性。(参看算法正确性方面的文章)


你可能感兴趣的:(基本算法)