算法 基础

admin
admin 2019年08月07日
  • 在其它设备中阅读本文章

一、算法

算法 (Algorithm)是解决特定问题的一系列步骤,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。它满足五个特性:

  1. 有穷性 :一个算法必须总是在执行有穷步之后结束,且每一步都可在有穷时间内完成
  2. 确定性 :每一条指令必须有确切的含义,不会产生二义性
  3. 可行性 :每一步都可以被分解为基本的可执行的操作步骤,即每个计算步骤都可以在有限时间内完成
  4. 输入 :零个或多个的输入
  5. 输出 :一个或多个的输出
    通常设计一个“好”的算法应考虑达到以下目标:
  6. 正确性 :合法输入能够得到正确结果;非法输入能得到合理错误提示;对于边界数据和压力数据都能得到正确输出
  7. 可读性 :要方便阅读,理解和交流
  8. 健壮性 :当输入数据不合法时,算法也能做出相关处理,而不是产生异常或莫名其妙的结果
  9. 高效性 :利用最少的时间和资源得到满足要求的结果,可以通过( 时间复杂度 空间复杂度 来判定)
    时间复杂度
    在进行算法分析时,语句总的执行次数 T(n)是关于问题规模 n 的函数,进而分析 T(n)随 n 的变化情况并确定 T(n)的数量级。算法的时间复杂度,也就是算法的时间度量,记作:T(n) = O(f(n))。它表示随问题规模 n 的增大,算法执行时间的增长率和 f(n)的增长率相同,称作算法的渐进时间复杂度,称为时间复杂度。其中 f(n)是问题规模 n 的某个函数。
    空间复杂度
    算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数,与问题的规模没有关系。算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n) = O(f(n)), 其中,n 为问题的规模,f(n)为语句关于所占存储空间的函数
    除非特别指定时,算法复杂度都是指时间复杂度

二、分治法

1、定义

将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之 。对于一个规模为 n 的问题,若该问题可以容易地解决(比如说规模 n 较小)则直接解决,否则将其分解为 k 个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解

2、适用对象

  1. 该问题的规模缩小到一定的程度就可以容易地解决
  2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
  3. 利用该问题分解出的子问题的解可以合并为该问题的解;
  4. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题
    第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;
    第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;
    第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法;
    第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。

3、基本步骤:

  1. 分解 :将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题
  2. 解决 :若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
  3. 合并 :将各个子问题的解合并为原问题的解

三、动态规划

1、定义

每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划 。将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。

2、适用对象

  1. 最优化原理 :如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。
  2. 无后效性 :即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。
  3. 有重叠子问题 :即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)

3、基本步骤:

  1. 分析最优解的性质,并刻画其结构特征
  2. 递归的定义最优解
  3. 以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值
  4. 根据计算最优值时得到的信息,构造问题的最优解

四、贪心算法

1、定义

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。

 贪心策略适用的前提是:局部最优策略能导致产生全局最优解。

2、基本步骤

  1. 建立数学模型来描述问题
  2. 把求解的问题分成若干个子问题
  3. 对每一子问题求解,得到子问题的局部最优解
  4. 把子问题的解局部最优解合成原来解问题的一个解

五、回溯算法

1、定义

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径 。在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。 其实回溯法就是对隐式图的深度优先搜索算法
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。
而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

2、基本步骤

  1. 针对所给问题,确定问题的解空间:首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解
  2. 确定结点的扩展搜索规则
  3. 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索

六、分支限界算法

1、定义

类似于回溯法,也是一种在问题的解空间树 T 上搜索问题解的算法。但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出 T 中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。

2、基本步骤

在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展对点。为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。

回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。