算法分析与设计

引论

(1)理解算法和程序的差别
(2)理解判断问题和优化问题这两类计算问题
1、理解指数增长的规模
2、理解渐进表达式
掌握渐进符号Ο、Θ、Ω的含义,能判断一个函数属于哪个渐近增长阶;
3、理解贪心算法的思想
掌握工作安排问题(Interval scheduling)的贪心算法;能对简单贪心算法进行证明;
4、理解分治算法的思想
掌握Master method(主方法)来求解递归关系式
5、理解动态规划算法的思想
对动态规划类型的问题能建立起基本的递归关系式,并能用从底至上的方法求解,在求解过程知道建立数据储存的表格、
理解背包问题动态规划算法的运行时间是伪多项式时间。
6、网络流
(1)了解并掌握网络最大流问题和最小割问题及算法,给出一个图能求出其对应的最大流或者最小割。
解题说明:要求体现增广链添加的过程。
7、归约与复杂度的NP问题
理解NP完备性理论
(1)理解什么是多项式归约(polynomial-time reduction)
(2)知道怎样从一个问题多项式归约到另一个问题,需要熟悉的归约包括:从点覆盖问题到独立集问题,从3-SAT问题到独立集问题等基本归约。
(3)要求掌握同一个问题的最优问题如何多项时间归约到该问题的判断问题(自身归约);
(4)熟悉NP和NPC的概念
(5)记住证明一个问题属于NPC的基本步骤
(6)能证明一个问题是NP-hard
8、近似算法
(1)理解什么是近似算法;
(2)熟悉load balancing 问题的近似算法;
(3)理解点覆盖问题的定价算法(Pricing method),证明该方法能得到一个2倍近似解;
(4)理解点覆盖问题的整数规划模型如何建立,理解松弛求解方法;
(5)要求会对一个图问题建立整数规划模型(以点覆盖问题为例)

引论

0.1 两个关键问题

(1)理解算法和程序的差别

算法,定义在一定资源(空间、运行时间等)限制下,解决问题的方法。
使用计算机解决问题的过程/方法;算法是有输入和输出的;一个问题可以有许多算法来解。

程序:计算机程序是某种编程语言中算法的实例或具体表示。

区别:1)程序是由电脑读取;
2)算法是由人类来设计
3)算法表示形式更多样,可以是伪码或者简单易懂的步骤表示。

(2)理解判断问题和优化问题这两类计算问题


简单说,判别问题就是0-1问题,优化问题是优化解的解法。

0.2 核心思想,研究算法就是对算法进行分类,逐一击破,常见的分类方式如下:

1)P:一个解可以在多项式时间内求解。

2)NP:一个解可以在多项式内被检验。
典型问题:
团问题(clique problem): 想象一张点和边组成的图,例如Facebook上用户为点,朋友关系为点之间的连边所组成的图。团(clique)是指节点全连接的子图。 人们也许会问:存在包含20个人的团吗?50个呢?100个呢?找到这样的团是一个“NP完全 (NP-complete) ”的问题,意为该问题在NP问题中具有最高的复杂度。但是给定一个20个人组成的子图,很容易检验该子图是否是正确答案。 这就是NP问题的特点,很难找到正确的解,但是判断一个解是否正确十分容易;
旅行商问题 (The traveling salesman problem): 给定一些相互远离的城市,是否存在一条穿过所有城市的路径,路径长度小于给定值?例如,是否有一条路径能经过美国所有的州府,总距离却不超过11,000英里?

研究者们关心的核心问题:

P和NP是一回事吗?如果P=NP,那么计算机会被颠覆,大多数密码技术会在一夜之间失效。(几乎没人认为这是成立的。)

3)NPC:问题没有多项式时间内的算法。

0.3.1 相关问题

活动安排问题(Interval scheduling):在有限时间长度里,安排尽可能最多的不重叠课程。

变式:
(1)Weighted Interval Scheduling:在有限时间长度里,找到权重尽可能最大的子类。

(2)Bipartite Matching(二部图匹配):找到最大基数匹配。

(3)Independent Set独立集:找到最多的结点,这些结点是不共线的。

(4)Competitive Facility Location:交替选择最大的权重结点,要求选择的点,临近点是不可以选的。

0.3.2小结

PSAPCE:多项式空间。
简述:PSPACE包含了所有可以通过合理内存来解决的问题。
精确描述:
在PSAPCE类的问题中,你不在乎时间,只关心一个算法所需的内存空间。计算机科学家已经证明PSPACE包含PH类,而PH类包含NP,同时NP还包含P类。

第一章 算法的基础概念

解决三个问题:
(1)如何区别算法消耗的指数时间和多项式时间?
(2)如何评价不同算法的时间消耗和空间大小?
(3)如何表示时间和空间资源使用大小?

1.1 评价


通常会考虑暴力算法,所以最坏情况的时间是被使用的。

1.1.1 为什么要划分成多项式时间和指数时间?

直观解释

问题(1)如何区别/评价算法消耗的指数时间和多项式时间?

1.2.1 理解渐进表达式

掌握渐进符号Ο、Θ、Ω的含义,能判断一个函数属于哪个渐近增长阶

问题(2)如何评价不同算法的时间消耗和空间大小?

问题(3)如何表示时间和空间资源使用大小?
符号定义



1.2.2 小结

第二章 理解贪心算法的思想

掌握活动安排问题(Interval scheduling)的贪心算法;能对简单贪心算法进行证明;

2.1 能对简单贪心算法进行证明

原理:局部最优解,当前最好的选择
特征:自顶向下,整体=一系列局部最优选择
求解过程:
1)建立数学模型来描述问题;
2)把求解的问题分成若干个子问题;
3)对每一个子问题求解,得到子问题的局部最优解;
4)把子问题的局部最优解,合成原来解问题的一个解。
证明贪婪算法是能找到最优解(反正法)

证明贪心算法正确性需要三步,1.原问题与子问题具有相同子结构。2.贪心解是可行解。3.其他解不比当前选择更好。

2.2 活动安排问题(Interval Scheduling)

2.2.1 为什么活动安排问题用贪心可求解

贪心策略应该是每次选取结束时间最早的活动。

2.2.2 伪码

2.3其他贪心问题

Other greedy algorithms. 贪心算法有很多经典的应用,比如霍夫曼编码(Huffman Coding)、Prim 和 Kruskal 最小生成树算法、还有 Dijkstra 单源最短路径算法。最小生成树算法和最短路径算法,

2.3.1 硬币兑换(coin changing)

问题描述:给定一个value,用最少的硬币数凑出这个value。
下面证明某一类硬币兑换问题是贪心问题
证明贪心算法正确性需要三步,1.原问题与子问题具有相同子结构。2.贪心解是可行解。3.其他解不比当前选择更好。
具体到面值搭配上说,
1.贪心解会选择当前可选最大元素,且由于元素1的存在,性质二得证。
2.定义问题为f(n)表示对于n的组合,则子问题为f(n-k),其中k为所选币值,可选币值不改变,故与原问题拥有相同子结构,性质1得证。
3.选择其他任何比当前贪心选择小的元素,不会比当前方案更优,即f(n-k greedy)<=f(n-k),性质3
得证。综上,贪心解三条件同时成立,算法正确性得证。

原因是:有倍数关系,70与140,不符合第3条性质,因此贪心算法失效。

2.3.2 过桥问题(一个手电筒)


两种方案的差异,只与最快的人、次快的人和次满的人的单独过桥时间有关,而与其他人的快慢无关。

2.3.3 雷达问题

2.3.4 背包

本题是动态规划的背包问题的特例,即给定100kg和物品数值,有最优子结构和原结构一致。
有一个可以容纳 100kg 物品的背包,可以装各种物品。有 5 种豆子,每种豆子的总量和总价值都各不相同。为了让背包中所装物品的总价值最大,如何选择在背包中装哪些豆子?每种豆子又该装多少?
先算一算每个物品的单价,按照单价由高到低依次来装就好了。单价(元 / kg)从高到低排列,依次是:黑豆(4)、绿豆(3)、红豆(2)、青豆(1.5)、黄豆(1),所以,我们可以往背包里装 20kg 黑豆、30kg 绿豆、50kg 红豆。它本质上借助的就是贪心算法。
贪心算法解决问题的步骤:
第一步,看到这类问题的时候,首先要联想到贪心算法:针对一组数据,定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大。
  类比到刚刚的例子,限制值就是重量不能超过 100kg,期望值就是物品的总价值。这组数据就是 5 种豆子。我们从中选出一部分,满足重量不超过 100kg,并且总价值最大。
第二步,尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据。
  类比到刚刚的例子,每次都从剩下的豆子里面,选择单价最高的,也就是重量相同的情况下,对价值贡献最大的豆子。
第三步,举几个例子看下贪心算法产生的结果是否是最优的。
大部分情况下,举几个例子验证一下就可以。严格地证明贪心算法的正确性,需要涉及比较多的数学推理。且从实践的角度,大部分能用贪心算法解决的问题,贪心算法的正确性都是显而易见的,也不需要严格的数学推导证明。

2.3.5 分糖果

有 m 个糖果和 n 个孩子。要把糖果分给孩子吃,但是糖果少,孩子多(m < n),所以糖果只能分配给一部分孩子。
每个糖果的大小不等,这 m 个糖果的大小分别是 s1,s2,s3,……,sm。除此之外,每个孩子对糖果大小的需求也是不一样的,只有糖果的大小大于等于孩子的对糖果大小的需求时,孩子才得到满足。假设这 n 个孩子对糖果大小的需求分别是 g1,g2,g3,……,gn。

如何分配糖果,能尽可能满足最多数量的孩子?
可把这个问题抽象成,从 n 个孩子中,抽取一部分孩子分配糖果,让满足的孩子的个数(期望值)是最大的。这个问题的限制值就是糖果个数 m。
利用贪心算法,对于一个孩子来说,如果小的糖果可以满足,就没必要用更大的糖果,这样更大的就可以留给其他对糖果大小需求更大的孩子。
       另一方面,对糖果大小需求小的孩子更容易被满足,所以,可以从需求小的孩子开始分配糖果。因为满足一个需求大的孩子跟满足一个需求小的孩子,对我们期望值的贡献是一样的。
每次从剩下的孩子中,找出对糖果大小需求最小的,然后发给他剩下的糖果中能满足他的最小的糖果,这样得到的分配方案,也就是满足孩子个数最多的方案。

2.3.6 区间覆盖(Interval Scheduling)

2.3.7 霍夫曼编码

有一个包含 1000 个字符的文件,每个字符占 1 个 byte(1byte=8bits),存储这 1000 个字符就一共需要 8000bits,那有没有更加节省空间的存储方式呢?

通过统计分析发现,这 1000 个字符中只包含 6 种不同字符,假设它们分别是 a、b、c、d、e、f。而 3 个二进制位(bit)就可以表示 8 个不同的字符,所以,为了尽量减少存储空间,每个字符我们用 3 个二进制位来表示。那存储这 1000 个字符只需要 3000bits 就可以了,比原来的存储方式节省了很多空间。不过,还有没有更加节省空间的存储方式呢?

a(000)、b(001)、c(010)、d(011)、e(100)、f(101)

霍夫曼编码不仅会考察文本中有多少个不同字符,还会考察每个字符出现的频率,根据频率的不同,选择不同长度的编码。霍夫曼编码试图用这种不等长的编码方法,来进一步增加压缩的效率。如何给不同频率的字符选择不同长度的编码呢?根据贪心的思想,我们可以把出现频率比较多的字符,用稍微短一些的编码;出现频率比较少的字符,用稍微长一些的编码。
霍夫曼编码就要登场了。霍夫曼编码是一种十分有效的编码方法,广泛用于数据压缩中,其压缩率通常在 20%~90% 之间。

对于等长的编码来说,我们解压缩起来很简单。比如刚才那个例子中,我们用 3 个 bit 表示一个字符。在解压缩的时候,我们每次从文本中读取 3 位二进制码,然后翻译成对应的字符。但是,霍夫曼编码是不等长的,每次应该读取 1 位还是 2 位、3 位等等来解压缩呢?这个问题就导致霍夫曼编码解压缩起来比较复杂。为了避免解压缩过程中的歧义,霍夫曼编码要求各个字符的编码之间,不会出现某个编码是另一个编码前缀的情况。

假设这 6 个字符出现的频率从高到低依次是 a、b、c、d、e、f。我们把它们编码下面这个样子,任何一个字符的编码都不是另一个的前缀,在解压缩的时候,我们每次会读取尽可能长的可解压的二进制串,所以在解压缩的时候也不会歧义。经过这种编码压缩之后,这 1000 个字符只需要 2100bits 就可以了。

参考:2.3.4-2.3.7

2.4 贪心算法与动态规划和DFS/BFS的关系

dfs,bfs,dp和贪心都是解搜索问题,dfs和bfs的时间复杂度最高,dp本质是引入了记忆化搜索的dfs或者bfs,所以如果dp数组解法写不溜的话,可以当dfs先写着,写完以后加一个hashmap做记忆化搜索,时间复杂度和数组解法相同,空间复杂度某些情况下可能会有常数上的优化,代价是函数调用进出栈的时间消耗。greedy的时间复杂度一般优于dp,但greedy的条件很强,最重要的就是这条子问题与原问题拥有相同子结构。对于搜索问题的求解,可以想看看有没有相同子结构,有的话,考虑上greedy,没有就先上dfs或者bfs,写完以后看有没有什么地方能上记忆化搜索,上了就是dp,没上就是dfs或者bfs。

算法设计与分析(电子科技大学)(中)分治算法、动态规划以及最大流问题和最小分割问题
算法设计与分析(电子科技大学)(下)归约与复杂度的NP问题以及近似算法

算法设计与分析(电子科技大学)(上)算法基础和贪心算法相关推荐

  1. 算法设计与分析-电子工业出版社

    第一章 算法概述 第二章 递归与分治 递归 概念:直接或间接调用自身的算法 范例: 阶乘 Fibonacci数列 Ackerman函数 排列问题 整数划分问题 Hanoi塔问题 分治 概念:将一个规模 ...

  2. 算法设计与分析 4 估计递归函数复杂度所提及算法

    按分治法框架实现二分搜索 int BinarySearch(int A[],int n,int x) {int mid,t;if(n<=0)return -1;else{mid=n/2;if(A ...

  3. 【算法设计与分析】最长公共子序列问题 动态规划算法 超详细

    最长公共子序列问题描述 注意:最长公共子序列不一定是连续序列. 例如:"ASAFAGAHAJAK"与"AAAAAAA"的最长公共子序列为:AAAAAA 公共子序 ...

  4. 算法设计与分析复习笔记(上)

    简介:本文是博主在复习算法设计与分析的笔记,参考了北大算法设计与分析以及王晓东编著的<计算机算法设计与分析>第四版相关内容,如有错误,欢迎指正. 文章目录 设计技术 分治 动态规划 设计技 ...

  5. 程振波 算法设计与分析_算法设计与分析

    本书按照教育部*制定的计算机科学与技术专业规范的教学大纲编写,努力与国际计算机学科的教学要求接轨.强调 算法 与 数据结构 之间密不可分的联系,因而强调融数据类型与定义在该类型上的运算于一体的抽象数据 ...

  6. 0x08算法设计与分析复习(二):算法设计策略-回溯法2

    参考书籍:算法设计与分析--C++语言描述(第二版) 算法设计策略-回溯法 子集和数 问题描述 已知n个不同的正数wi(0≤i≤n−1)的集合,求该集合的所有满足条件的子集,使得每个子集中的正数之和等 ...

  7. 计算机算法设计与分析教学大纲,《算法设计与分析》教学大纲

    <<算法设计与分析>教学大纲>由会员分享,可在线阅读,更多相关<<算法设计与分析>教学大纲(3页珍藏版)>请在人人文库网上搜索. 1.课程编号:&quo ...

  8. 计算机算法设计与分析(第4版) 王晓东 著 2012.2 笔记(这本书还不错,偏实用、有难度)

    计算机算法设计与分析(第4版) 目录 1 算法概述 2 递归与分治策略 3 动态规划 4 贪心算法 5 回溯法 6 分支限界法 7 随机化算法 8 线性规划与网络流 算法概述 复杂性分析 NP-完全性 ...

  9. 算法设计与分析项目-有容量设施选址问题

    算法设计与分析项目-有容量设施选址问题 Capacitated Facility Location Problem(CFLP) 文章目录 算法设计与分析项目-有容量设施选址问题 Capacitated ...

最新文章

  1. javascript网络_没有JavaScript的网络外观
  2. Java ArrayList的不同排序方法
  3. LPTHW 笨方法学习python 16章
  4. 用python查找指定格式或名称的文件及修改指定文件夹名称
  5. Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参
  6. python文件运行哪一个_如何使一个python文件运行另一个?
  7. 【人脸识别】Center Loss详解
  8. Linux负载均衡软件LVS(概念篇)
  9. oracle数据恢复
  10. 一起来当网管(一)——Windows Server上的DHCP配置
  11. c语言里编译错误c131,C语言题库2.doc
  12. 2021 王道考研 计算机组成原理+习题讲解
  13. SpringBoot_Vue实现电影院售票系统
  14. Android Studio 写个单元测试用例,就是这么方便
  15. 音视频开发系列(6)视频码率,帧率和分辨率
  16. uniapp上传华为应用市场,您的应用提示获取手机存储敏感权限,用户不同意时强制退出应用
  17. Python3——斐波那契数列
  18. Linux whoami和who am i命令用法和区别
  19. 对话线性资本郑灿:新一代AI公司的魅力与使命
  20. Android lunch分析以及产品分支构建

热门文章

  1. 基于Linux的即时通信软件
  2. 2019暑假杭电多校第6场签到题-1008-TDL
  3. 阿里三面:说一说你在上家公司都用过哪些限流方案?
  4. MySQL之数据库设计三范式
  5. java设置xmlns xsi,JAXB - 如何添加xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance
  6. IP组播----组播基础 组播服务模型、组播地址
  7. Datawhale六月学习数据分析打卡task2
  8. Windows2012的服务器搭建
  9. 如何去实现GM8775 MIPI转LVDS屛的设计
  10. 牛客网之SQL必知必会(2)-限定时间、日期的查询