• 哈工大算法设计与分析期末试题解析


    试题内容来自https://www.cnblogs.com/fyunaru/archive/2019/07/02/11123804.html

    本文基于该试题添加了解析,仅供参考

    一、判断题(10 * 2 分)

    1.A*算法一定可以得到最优解。正确

    A*算法定义:

    (1)使用最佳优先策略搜索

    (2)节点n的代价函数:f(n)=g(n)+h(n),g(n)是起点到节点n的最短路径代价,h(n)是节点n到目标节点的估计代价

    (3)h(n)<=h*(n),h(n)表示节点n到终点的估计代价,h*(n)表示节点n到终点的实际代价(保证A*算法一定得到最优解的条件)

    (4)当选择到的节点是目标节点时,算法停止,返回一个最优解

    A*算法代价函数估计公式:f(n)=g(n)+h(n)

    g(n)=0时,仅计算任意节点n到目标节点的启发函数,而不计算节点到节点n的最短距离,算法转化为使用贪心策略的最佳优先搜索,速度最快,但可能找不到最优解;

    h(n)<=h*(n)时,一定可以求出最优解,h(n)越小,需要计算的节点越多,算法效率越低,常见的启发函数有曼哈顿距离、欧几里得距离等

    h(n)=0时,仅计算起点到任意节点n的最短距离,而不计算任何启发函数h(n),转化为单源最短路径问题,即Dijkstra算法,需要计算最多的节点

    2.调试程序可以证明算法的正确性。错误

    算法的正确性定义:对于每一个输入都最终停止,而且产生正确的输出

    算法的正确性证明:(1)证明算法对所有输入都终止(2)证明对每个输入都产生正确结果

    程序调试!=程序正确性证明:程序调试只能证明程序有错,不能证明程序无错误

    循环不变量方法:证明主要结构是循环结构的算法的正确性

    3.dijkstra算法是贪心算法。

    算法维护两个顶点集合S和Q。集合S保留所有已知实际最短路径值的顶点,而集合Q则保留其他所有顶点。

    集合S初始状态为空,而后每一步都有一个顶点从Q移动到S。这个被选择的顶点是Q中拥有最小的d[u]值的顶点。

    当一个顶点u从Q中转移到了S中,算法对u的每条外接边w(u,v)进行松弛。

    4.如果一个基于比较的排序算法的时间复杂性是Ω(nlogn),那么他可能是基于比较算法中时间复杂性最低的算法。正确

    假设需要排序的数有N个,N个数有N!种不同的排序情况,即基于比较的排序算法的判定树有N!个叶子节点。

    比较次数最少为log(N!)=O(NlogN)

    5.一个关于堆排序的插入和删除操作的时间复杂性的问题。(具体怎么问忘了)

    原地堆排序:

    (1)创建一个堆H[0:n]

    (2)把堆首与堆尾互换

    (3)把堆的尺寸减1,并调用堆调整,将新的堆顶端元素调到合适位置

    (4)不断重复(2)(3)两个步骤,直到堆的尺寸为1

    堆的插入操作:将新元素插入堆尾,已知新元素的父节点到根节点是一个有序的序列,将新元素插入到该序列中,可以视为直接插入排序。(时间复杂度O(logn))

    堆的删除操作:将堆顶元素与堆尾元素调换位置;堆尺寸减1,对新堆进行堆调整。(时间复杂度O(logn))

    6.一个问KMP算法的时间复杂性的问题。

    KMP算法可在一个主文本字符串S内查找一个词W(或称模式串)的出现位置

    如果文本串的长度为 n,模式串的长度为 m,那么匹配过程的时间复杂度为 O(n),算上计算 next 的 O(m) 时间,KMP 的整体时间复杂度为 O(m + n)

    二、简答题(5 * 4分)

    1.一个master定理的题目(很类似于ppt上的一道例题)应该是T(n) = 3T(n/4) + n^(1/2) 

    https://zh.wikipedia.org/wiki/%E4%B8%BB%E5%AE%9A%E7%90%86

    a=3,b=4

    f(n)=n^(1/2) = O(n^(log_4(3-1))),符合情形一的情况

    T(n)=Theta(n^(log_4(3)))

    2.一个非常简单的复杂函数阶的证明,已知fx = O(g(x)), gx = o(hx),证明 fx = o(hx)

    证明:

    f(x)=O(g(x)) => 对于任意的c1,c2>0,x > x0时,c1*g(x) <= f(x) <= c2*g(x)

    g(x)=o(h(x)) => 对于任意的c>0,x > x1时,g(x) < c*h(x)

    当x>max(x0,x1)时,f(x) <= c2*g(x) => f(x) < c2*c*h(x) = C*h(x),其中C=c2*c

    因此f(x) = o(h(x))

    3.写出0-1背包问题的输入规模和时间复杂性

    输入:C>0, w_i>0, v_i>0, 1<=i<=n

    输出:(x_1,x_2,...,x_n), x_i in {0, 1},满足sum_{1=<i<=n}w_i*x_i<=C},

    输入规模:一个问题的输入规模是保存输入数据所需要的bit位数。

    输入规模:x = logC

    动态规划解法:设dp[i][j]代表从0-i中挑选一些整数,每个物品只能使用一次,是否能够恰好填满容量为j的背包

    for i = 1 to n:

      for j = 0 to C:

        dp[i][j] = dp[i - 1][j]  

        if nums[i] == j:

          dp[i][j]=True

          continue

        if nums[i] <  j:

          dp[i][j]=dp[i-1][j] or dp[i-1][j-nums[i]] 

    标准多项式时间复杂度:对于一个问题,在输入规模为x的情况下,如果一个算法能够在O(x^k)时间内解决此问题,则我们称此算法是多项式时间的,其中k为一常数。

    动态规划解法时间复杂度:O(nC) = O(n*(2^x))

    传统时间复杂度与标准时间复杂度对比

    相似:图论、链表、数组、树等问题

    不同:数论问题(例如素数判定算法,传统时间复杂度O(n),输入规模x=logn,标准时间复杂度O(2^x))

    若一个算法的传统时间复杂度为多项式的,但标准时间复杂度不是多项式的,则算法为伪多项式时间复杂度算法

    4.说明平摊分析的目的,以及任举一种平摊分析方法说明其大致思想,以及使用时需要注意的点

    三、(8分)

    一个最大流的问题,给了一个最大流的图‘

    第一问要求画出某一步之后的余图

    第二问要求找出一条可以使流量增加1的増广路径

    第三问要求给出一个最小割

    图(a)为一个流网络,图(b)展示了它的余图 

    符号定义:flow(a)代表边a的流量,c(a)代表边a的容量,s-t路径是指从起点s通往目标点t的任意一条路径

    余图:余图(residual graph)的顶点和原图一样,如上图右所示,它包含两类弧:(1)原图的未饱和弧;(2)原图flow(a)>0的弧的反向弧。

    增广路径:一条满足flow(a)<c(a)弧构成的s-t路径,上图(b)中s-v2-v3-t,容量为4的路径即为增广路径

    流网络的割:流网络G中的一个割(S, T)将结点集合V划分为S和T=V-S两个集合,满足s in S,t in T

    推论:流与割的弱对偶关系

    给定流网络 G=(V,E),s是源,t是汇. 设f是G上的一个流,S,T是G的任意一个割,则f(S,T)=|f|.

    给定流网络 G=(V,E). 设f是G上的一个流,(S,T)是G的任意一个割,则|f| <= c(S,T)

    最小割:任意流不大于任意割,最大流等于最小割。

    最大流算法(Ford-Fulkerson算法):

    (1)建立原图流为0的余图;

    (2)在余图中找出任意的s-t路径,并按该路径找出原图允许的最大流K:

    • 最大流K根据弧的容量减去已有的流;
    • 对余图的正向弧,原图的流加上K;
    • 对余图的反向弧,原图的流减去K。

    (3)更新余图,重复上述过程,直到余图不存在s-t路径。

    5分钟看懂Ford-Fulkerson算法:https://www.youtube.com/watch?v=Tl90tNtKvxs

    四、(7分)

    给出一个加权有向图,要求用A*算法把整个过程写一遍,并给出最后所得的最短路径。

    A*算法的通俗介绍(https://www.redblobgames.com/pathfinding/a-star/introduction.html

    将加权有向图转为解空间树,逐步写出当前节点的拓展节点的g(n)、h(n)、f(n)并标在图的节点旁边

     

     

     

     

     

     

     

     

     

     

    五、(20分)

    分治算法的题,是作业题上的一道原题。
    原题如下:

    第一问写出算法思想

    第二问写伪代码

    第三问分析时间复杂度

    算法思想:

    首先利用O(nlogn)的排序算法对S进行排序;

    然后循环遍历S的每一个元素S[i],利用二分查找判断S中是否包含x-S[i],该步二分查找复杂度为O(logn),因此循环复杂度为O(nlogn)

    综上算法的整体复杂度为O(nlogn)

    六、(15分)

    贪心算法的题。(这道题我真是无力吐槽,考场上没看懂怎么写,考完之后问了几个同学都说贪心思想和算法随便写的,且每个人写的都不一样,后来问老师那个题怎么写,老师说只要言之有理都算对,,,)

    题目大概写一下吧,反正我觉得这题出的真差,你们复习的时候可以自己找点别的贪心算法的题做。

    有一条环形公路,公路上有n个加油站,一辆油箱容量无限大的汽车在这条路上行驶,每个加油站所能给车加的最大油量为si,车在每两个加油站之间行驶耗得油为ci。要求写出一个贪心算法,让这个车选择一个加油站作为起始点,能够成功绕这个环形公路一圈并回到起始点,如果没有这样的加油站,则返回-1,有则返回所选择的起始加油站的编号。

    第一问写贪心思想

    第二问证明贪心思想

    第三问伪代码

    第四问时间复杂度

    贪心思想:

    贪心思想的证明:

    七、(10分)

    动态规划的题。比较简单,多做几道动态规划的题应该就可以做出来了。

    题目大致如下:

    给定如图所示的一个树状图,每个节点上都标有该点权值,该树共有5层,从第一层的节点进入,从第五层的节点出来,要求找出一条长为4(即通过了5个节点)的路径,使得该条路径所经过的5个节点和最小。

    图像大致如下:

     

  • 相关阅读:
    生命
    历史的分岔-中日产业发展史的对照和思考
    挑战自已
    丰台往事已成风,上下求索永不停
    VC6.0实现鼠标光标形状及大小的定制
    RelativeLayout
    16进制颜色代码
    html里的option错误
    Android用户界面设计:布局基础
    Activity详细介绍【官网】
  • 原文地址:https://www.cnblogs.com/haodingkui/p/13338564.html
Copyright © 2020-2023  润新知