软件设计师备考 | 第八章 算法设计与分析

大纲

考法:上午题目主要包含题目所用算法和算法复杂度。下午试题的算法题不仅考核算法设计和分析技术,还同时考核算法的C程序设计语言实现

8.1 算法设计与分析基本概念

程序 = 数据结构 + 算法

算法

算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作。简单的说算法就是某个问题的解题思路

算法的五个重要特性如下;

  1. 有穷性。一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都可在有穷时间内完成。
  2. 确定性。算法中的每一条指令必须有确切的含义,理解时不会产生二义性。在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。
  3. 可行性。一个算法是可行的,即算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
  4. 输入。一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合,
  5. 输出。一个算法有一个或多个输出,这些输出是同输入有着某些特定关系的量。

算法的表示

常用的表示算法的方法有自然语言、流程图)程序设让语言和伪代心等。

  1. 自然语言。容易理解,但容易出现二义性,并且算法通常很冗长。
  2. 流程图。直观易懂,但严密性不如程序设计语言,灵活性不如自然语言。
  3. 程序设计语言。可用计算机直接执行,但抽象性差,使算法设计者拘泥于描述算法的具体细节,忽略了“好”算法和正确逻辑的重要性。此外,还要求算法设计者掌握程序设计语言及编程技巧。
  4. 伪代码。介于自然语言和程序设计语言之间的方法,它采用某一程序设计语言的基本语法同时结合自然语言来表达。计算机科学家从来没有对伪代码的书写形式达成过共识。在伪代码中可以采用最具表达力的、最简明扼要的方法来表达一个给定的算法。

例题

1. 从基本概念上看,算法分析是指对一个算法所需要的资源进行估算,这些资源包括内存、通信宽带、计算机硬件和时间等,所需要的资源越多,该算法的复杂度就越高。

A. 正确       B. 错误

解析:A。参考《软件设计师教程》(第5版),p417原文。

2. 在进行算法选择时,应优先选择哪些算法?

A 时间复杂度和空间复杂度较低的算法

B. 简单易理解、正确可靠的算法

C. 计算机语言和程序设计语言较为熟悉的算法

D. 花费较高但更加精确的算法

解析:B。求解一个问题可能会有多种算法可以选择,选择的主要标准首先是算法的正确性、可靠性、简单性和易理解性,其次是算法的时间复杂度和空间复杂度要低。这是算法分析技术的主要内容。

8.2 算法分析基础

算法复杂度

  • 时间复杂度:程序运行从开始待结束所需要的时间。
  • 空间复杂度::一个算法在运行过程中临时占用存储空间大小的度量。一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小

常见的对算法执行所需时间的度量:O(1)<O(log_2^n)<O(n)<O(nlog_2^n)<O(n²)<O(n^3)<O(2^n)<O(n!)
时间复杂度是一个大概的规模表示,一般以循环次数表示,O(n)元说明执行时间是n的正比,另外,log对数的时间复杂度一般在査找二叉树的算法中出现。渐进符号O表示一个渐进变化程度,实际变化必须小于等于O括号内的渐进变化程度。

8.3 分治法与回溯法

分治法

分治法:对于一个规模为n的问题,若可以容易地解决则直接解决;否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解决这些子问题,然后将各子问题的解合并得到原问题的解。

递归:子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己。凡涉及到分组解决的都是分治法(二分查找、归并排序、求阶乘、斐波那契数列等)。

递归两因素

  • 边界条件:确定递归到何时终止。
  • 递归模式:大问题是如何被分解为小问题的。

例子:阶乘定义

代码实现:

(Python)

def fact(n):
      if n == 0:
            return 1
      elif n > 0:
            return n*fact(n-1)	
      

(C) 

int fact(int num){
     if (num == 0)
         return 1;
     if (num > 0 )
         return num*fact(num - 1)

8.4 动态规划

动态规划法(Dynamic Programming): 在求解问题中,对于每一步决策,列出各种可能的局部解通过决策保留那些有可能达到最优的局部解,丢弃其他局部解,以每一步都是最优解来保证全局是最优解。

与分治法区别:每个子问题不是相互独立的,并且不全部相同。

与贪心法区别:动态规划不仅每一步最优,全局也最优。

三个特点:

  1. 把原问题分解成几个相似的子问题
  2. 所有的子问题只需要解决一次
  3. 存储子问题的解,会增加空间复杂度。

以斐波那契数列举例。左下图是使用递归来求解,代码为:

def fib(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)

这种方法比较低效,因为有大量的重复计算,不满足动态规划的第二个特点。可以通过动态规划的第三个特点解决,把每次结果存储起来结果,在其他地方碰到时,可以直接从存储中获得结果。如下图的中间和右边,蓝色表示需要计算的,白色表示可以直接从存储种去的结果的。

def fibDyn(n):
    if n == 0 or n == 1:
        return 1
    elif n > 1:
        dp = [0] * n
        dp[0] = dp[1] = 1
        for i in range(2, n + 1):
            dp[n] = dp[n-1] + dp[n-2]
        return dp[n]

8.5 贪心法

贪心法:只针对当前的步骤取最优,非整体考虑。不必为了寻找最优解而穷尽所有可能姐,因此其耗费时间少,可以快速得到满意的解,但得不到最优解。

具体可以看在我之前在代码随想录训练营中关于贪心算法的打卡,如:代码随想录算法训练营第三十四天(贪心算法篇)|10.2 分发饼干,376. 摆动序列,53. 最大子序和-CSDN博客

 8.6 回溯法

回溯法(Backtracking)是一种优选的暴力搜寻法。时间复杂度较高,为O(n^2)。按优选条件向前选择,以达到目标,当到了某一步时,发现原先选择并不优或达不到目标,就退回再走。

回溯法一般用于解决迷宫、数独类的问题。具体可见:

代码随想录算法训练营第三十三天(回溯算法篇)| LeetCode 51. N皇后,37. 解数独-CSDN博客

主要算法总结及真题

特征总结

算法特点经典问题
分治法把一个问题拆分成多个小规模的相同子问题,一般可用递归解决斐波那契数列、归并排序、快速排序、矩阵乘法、二分搜索、大整数乘法
回溯法系统的搜索一个问题的所有解或任一解,即找出所有子问题的最优解。N皇后问题、迷宫
动态规划法划分子问题,并把子问题结果使用数组/散列表存储斐波那契数列、矩阵乘法、背包问题、LCS最长公共子序列
贪心法局部最优,但整体不见得最优。背包问题、多机调度、找零钱问题

注意一种问题可以通过不同算法实现。

真题

【2016】 考虑一个背包,共有n = 5个物体,背包容量为W = 10。物品的重量和价值分别为w = \{2, 2, 6, 5, 4\}v = \{6, 3, 5, 4, 6\},求背包为题的最大装包价值。若此为0-1背包问题,分析该问题具有最有子结构,定义递归为:

其中c(i, j)表示i个物品、容量为j的0-1背包问题的最大装包价值,最终要求c(n, W), 采用自底向上的动态规划问题求解,得到最大装包价值为(62), 算法的时间复杂度为(63)。

若此为部分背包问题,首先采用归并排序算法,根据物品的单位价值从大到小排序,然后一次将物品放入背包直至所有物品放入背包或者背包再无容量,则得到的最大装包价值为(64),算法的复杂度为(65)。

(62) A. 11     B. 14     C. 15    D. 16.67

(63)A. O(nW)     B. O(nlogn)    C. O(n^2)    D. O(nlognW)

(64)A. 11     B. 14     C. 15    D. 16.67

(65)A. O(nW)     B. O(nlogn)    C. O(n^2)    D. O(nlognW)

解析

完全背包和部分背包定义:

0-1 完全背包:每件物品都不可再分,要么整个装入背包,要么不放。

部分背包问题:每件物品可再分的,即允许将某件物品的一部分(例如 1/3)放入背包。

(62)Ⅰ. 可以先看最大价值的物品,价值都为6,重量分别为2 和4, 放入背包后还剩的容量为4, 那么能选的最大价值的物品组合是第二个物品,价值为3, 则最大价值为6 + 6 + 3 = 15。Ⅱ. 算每个物品的单位价值,分别为\{3, \frac{3}{2}, \frac{5}{6}, \frac{4}{5} , \frac{3}{2}\},根据总容量,选择单位价值最大的几个。Ⅲ 直接使用穷举法。选C。

(63)完全背包的时间复杂度为O(nm)。选A.

(64)  Ⅰ将物品的单位价值最大的几个装进背包,甚于容量为2, 将剩下物体中单位价值最大的那个下“切”出容量为2的部分放进背包,那么最大价值为:15+2\times\frac{6}{5} \approx 16.67。Ⅱ.对于这道题,用完全背包后还有多余的容量,所以部分背包能装的最大价值肯定比完全背包要大, 所以直接选D。

(65) 为归并排序的时间复杂度, 选B。

【2012】63-64、某货车运输公司有一个中央仓库和n个运输目的地,每天要从中央仓库将货物运输到所有运输目的地,到达每个运输目的地一次且仅一次,最后回到中央仓库。在两个地点i和j之间运输货物存在费用C_{ij}。为求解旅行费用总和最小的运输路径,设计如下算法:首先选择离中央仓库最近的运输目的地1,然后选择离运输目的地1最近的运输目的地2,...,每次在来访问过的运输目的地中选择离当前运输目的地最近的运输目的地,最后回到中央仓库。该算法采用了(63)算法设计策略,其时间复杂度为(64)。
(63).    A.分治     B.动态规划     C.贪心     D.回溯     
(64).    A.O(n²)     B.O(n)     C.0(nlogn)     D.O(1)

解析

(63)这个策略每次只考虑当下最优的路线,为贪心算法,选C。

(64)每一次都要搜索其他剩余位置到当前的位置,所以应该为n+(n-1)+(n-2) +...1但没有这个选项。答案为A,每一次都考虑最坏的情况,有n个,每次都要考虑n个位置,所以为n^2

【2018】在一条笔直公路的一边有许多房子,现要安装消防栓,每个消防栓的覆盖范围远大于房子的面积,如下图所示。现求解能覆盖所有房子的最少消防栓数和安装方案(问题求解过程中,可将房子和消防栓均视为直线上的点).


该问题求解算法的基本思路为:从左端的第一栋房子开始,在其右侧m米处安装一个消防栓,去掉被该消防栓覆盖的所有房子。在剩余的房子中重复上述操作,直到所有房子被覆盖。算法采用的设计策略为(1);对应的时间复杂度为( 2)。
假设公路起点A的坐标为0,消防栓的覆盖范围(半径)为20米,10栋房子的坐标为(10,20,30,35,60,80160,210,260,300),单位为米。根据上述算法,共需要安装(3)个消防栓。以下关于该求解算法的叙述中,正确的是(4)
(1)  A. 分治     B. 动态规划     C. 贪心     D. 回溯     
(2)  A. O(Ign)     B. O(n)     C. O(nlgn)     D. O(n2)     
(3)  A.4     B. 5     C. 6     D. 7     
(4) (A)肯定可以求得问题的一个最优解     (B)可以求得问题的所有最优解     
(C)对有些实例,可能得不到最优解     (D)只能得到近似最优解。

解析

(1)每次只单独考虑一个房子,不考虑整体,为贪心算法,选C。

(2)对每一个房子,都要考虑一次覆盖, 有n个房子,所以时间复杂度为O(n), 选B。

(3)选B。

(4)贪心算法局部求最优解,不求整体最优解。选C。 A选项对应动态规划,B选项对应回溯。  

8.7 分支限界法

分支限界法:与回溯法类似,同样是在问题的解空间树上搜索问题解的一种算法,它常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。

举例:假设你要去旅行,需要选择一些物品装进行李箱。你希望选择的物品总价值最大,但行李箱的容量有限。你可以使用分支限定法来解决这个问题。

首先,确定每个物品的价值和重量。然后,可以创建一个分支限界法的搜索树,每个节点代表一种可能的物品选择方案。在搜索树中,每个节点都有两种可能的分支:选择或不选择该物品。
接下来,你可以计算每个节点的价值和重量,并选择价值最大的分支进行扩展。这个过程会一直持续,直到找到一个可行的物品选择方案,或者搜索树中的所有分支都被扩展完毕。

在这个例子中,分支限界法通过优先考虑价值最大的物品来快速找到最优的物品选择方案。这种方法可以避免盲目搜索解空间树,从而提高算法的效率。

常见的两种分支界限法

  • 队列式(FIFO) 分支界限法(广度优先):按照队列先进先出原则选取下一个结点为扩展结点。
  • 优先队列式分支限界法(最小损耗优先):按照优先队列规定的优先级选取优先级最高的结点成为当前扩展结点。

回溯法和分支界限法的区别

1. 求解目标:回溯法的求解目标是找出解空间中满足约束条件的一个解或所有解。分支限界法的目标一般是在满足约束条件的解中找出在某种意义下的最优解,也有找出满足约束条件的一个解。

2. 搜索法:回溯法的搜索方式为深度优先,搜索整个解空间,当不满条件时,丢弃,继续搜索下一个儿子结点,如果所有儿子结点都不满足,向上回溯到它的父节点。分支限界法以广度优先或以最小损耗优先的方式搜索解空间。

8.8 概率算法

概率算法允许算法在每一步的执行过程中都可以随机选择下一个计算步骤,在最后不一定能得到解。重要特征:对所求解的同一实例使用同一个算法求解多次,其结果可能不同。

使用场景:对精度要求不高,对时间要求高的场景。

四类概率算法

  • 数值概率算法(牛顿法、割线法、...)
  • 蒙特卡洛算法(求问题的精确解)
  • 拉斯维加斯算法(不会得到不正确的解)
  • 舍伍德算法(总能求得问题的一个正确解)

8.9 近似算法

近似算法是一种通过牺牲精确性来换取计算效率的算法。

目标:在合理的时间内找到一个接近最优解的可行解。

通常无法找到问题的精确最优解。它以可接受的近似度作为衡量标准,即在满足一定条件下,给出一个与最优解相差不大的近似解。虽然它可能找不到一个最优解,但它总会给待求解的问题提供一个解。为了具有实用性,近似算法必须能够给出算法所产生的解与最优解之间的差别或者比例的一个界限,它保证任意一个实例的近似最优解与最优解之间的相差成都。显然,这个差别越小,近似算法越具有实用性。

衡量近似算法性能两个标准

  • 算法的时间复杂度必须是多项式阶的。
  • 解的近似程度。近似程度与近似算法本身、问题规模,乃至不同的输入实例有关。

8.10 数据挖掘算法与机器学习

数据挖掘(Data Mining)是从大量的数据中,提取隐藏在其中的,事先不知道的、但潜在有用的信息的过程。数据挖掘是一门交叉学科,它涉及了数据库(一般为非关系型数据库),人工智能,统计学,可视化等不同的学科和领域。

目标:建立一个决策模型,根据过去的行动数据来预测未来的行为。

比如分析一家公司的不同用户对公司产品的购买情况,破解消费者的行为模式,进而分析出哪一类客户会对公司的产品有兴趣。

机器学习:一类算法的总称,这些算法企图从大量历史数据中挖掘出其中隐含的规律,并用于预测或者分类。它可以看作是寻找一个函数,输入是样本数据,输出是期望的结果,只是这个函数过于复杂,以至于不太方便形式化表达。

举例:假设要构建一个识别猫的程序。传统上如果我们想让计算机进行识别,需要输入一串指令,例如猫长着毛茸茸的毛、顶着一对三角形的的耳朵等,然后计算机根据这些指令执行下去。通过传统方式要制定全部所需的规则,会涉及到一些困难的概念,比如对毛茸茸的定义。因此,更好的方式是让机器自学。我们可以为计算机提供大量的猫的照片,系统将以自己特有的方式查看这些照片。随着实验的反复进行,系统会不断学习更新,最终能够准确地判断出哪些是猫,哪些不是猫。

机器学习算法分类

  1. 有监督学习:从有标记的训练数据中推导出预测函数。
  2. 无监督学习:从无标记的训练数据中推断结论。给定数据,寻找隐藏的结构。
  3. 强化学习:描述和解决智能体在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。即给定数据选择一系列行动,以最大化长期收益。如机器人学下象棋通过多次训练,以赢得比赛。

数据建模过程

1. 定义挖掘目标

2. 数据获取

3. 数据预处理:数据清洗、转换、集成、规约。

4. 挖掘建模:分类、回归、聚类、关联规则、文本分析

5. 模型评估

6. 数据展现:模型结果可视化。


8.11 智能优化算法

优化技术是一种以数学为基础,用于求解各种工程问题优化解的应用技术。通过模拟生物进化、群体行为或其他自然现象的过程,搜索和优化问题的最佳解或接近最佳解。它们具有自学习和自适应的能力,能够在搜索空间中找到较好的解决方案

在实际应用中,智能优化算法可以用来解决各种各样的问题,比如如何最大化收益、如何最小化成本、如何提高效率等等。它通过不断地尝试和改进,找到最佳的解决方案。

总之,智能优化算法是一种模拟自然现象或人类智能的优化方法可以帮助我们优化解决各种实际问题。它们可以在复杂的搜索空间中找到最佳解或接近最佳解,为我们提供更好的决策和解决方案。

常见的智能优化算法:人工神经网络(ANN)、遗传算法、模拟退火算法(SA)、禁息搜索算法(TS)、蚁群关、粒子群优化算法(PSO)

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值