一、介绍
算法按照复杂度划分可以分为3类,分别是:P、NP、NPC。
P:多项式时间内能够得到一个解。
NP:一个解能够在多项式时间内被验证。
NPC:问题可能没有多项式时间算法。
稳定匹配问题(Stable Matching):
给定n各男人和n个女人,要求找到一个“稳定”的匹配。
“稳定”匹配指,不存在这样一对男女,使得他们在匹配中没有配对,但是他们互相更加喜欢。
即不存在m-w,m‘-w’,但是m和w‘互相更加喜欢对方而不是目前的伴侣,这会导致m和w’私奔。
现假设把男人对女人的喜欢程度以及女人对男人的喜爱程度,按照降序排列成表格如下:
那么可以通过如下算法得到一个稳定匹配:
简单来说,算法会遍历每一个还没有配对的男人,并按照他对女人喜爱的顺序进行访问:
如果女人还没有配对,则和这个男人配对
如果女人配对了,但是更喜欢这个男人,那么女人抛弃原来的男人并和这个男人配对。原来的男人就会变为“未配对”的状态。
如果女人配对了,但是更喜欢配对的男人,则拒绝这个男人。
未配对的男人会一直重复这个访问过程,直到所有的男人均已配对。这样得到的配对结果就是稳定的。
观察1:男人会根据降序的顺序依次对女人进行访问
观察2:女人一旦匹配上了,那么一直会处于匹配状态,只不过可能会和别的男人私奔。
证明:算法一定会结束(即每个人都处于匹配状态)
假设某个男人A没有匹配上,那么一定也存在一个未匹配上的女人(因为男女人数相等)。但是由观察2可知,如果这个女人没有匹配上,那么她一定是没有被任何男人访问过。但是A在结束时一定会访问所有女人,因此这个假设不成立。所以算法最后一定会结束。
证明:算法得到的一定是稳定匹配
假设匹配中有A和Z这样一个不稳定匹配。即A和Z都更喜欢对方,而不是匹配中的人
(A-Y;B-Z)。
情况1:Z从来没有向A求过婚。由于求婚顺序是按照喜欢的顺序来的,所以Z更喜欢B,就不存在A和Z更加互相喜欢。
情况2:Z向A求过婚。但是A后来与Y私奔了,把Z抛弃了,这说明A更喜欢Y,而不是Z。就不存在A和Z更加互相喜欢。
这就说明算法最终一定会得到一个稳定匹配。
证明:在稳定匹配的前提下,匹配结果总是一样,并且男人会得到最佳的有效伴侣。
假设在一个匹配中,男人的匹配结果并不是最佳的有效伴侣。由于男人会按喜好度递减的顺序访问女人。所以有一些男人会被其目前合法匹配的伴侣给拒绝。
假设Y是第一个被拒绝的男人,A是拒绝Y的女人。令S为A和Y匹配时的一个稳定匹配。
当Y被拒绝的时候,A会和某个男的私奔,假设A和Z私奔了,这说明A更喜欢Z而不是Y。
再假设在S中原先与Z的匹配是B。在Y被拒绝之前没有别的男人被拒绝过的,因为Y是第一个被拒绝的男人。这就说明Z是更喜欢A的,并且A和Z私奔了,A也是更喜欢Z的,这样S中就存在了一个不稳定匹配。
证明:在稳定匹配的前提下,匹配结果总是一样,并且女人会得到最差的有效伴侣。
二、算法设计与分析
如果算法最坏的运行时间是W,那么一定至少存在一个运行时间为W的实例吗?
渐进表示:
渐进分析中的函数比较
f(n) = O(g(n)) ≈ a≤b; f(n) = Ω(g(n)) ≈ a≥b; f(n) = Θ(g(n)) ≈ a=b
f(n) = o(g(n)) ≈a<b; f(n) = w(g(n)) ≈ a>b;
渐进分析记号的若干性质:
(1)传递性
(2)反身性
(3)对称性
(4)互对称性
(5)算术运算
规则O(f(n))+O(g(n))=O(max{f(n),g(n)})的证明:
规则O(f(n)+g(n)) = O(max{f(n),g(n)})的证明:
三种常用算法:
贪心算法(局部最优):
在每次迭代中选择了最好的解决方案,但是这种方法不一定会产生全局最好的结果。
例:Inerval Scheduling问题:有一系列工作,Job j 开始于sj结束于fj。如果两个工作没有时间重叠则是不冲突的。要求找到这些工作的子集,使得子集大小最大,子集内的任意两工作不冲突。
比如对于这一系列工作而言,最优解应该是{b,e,h}
设计贪心算法求解:把问题按照结束时间递增的顺序进行排列。从前往后考虑每一份工作,如果当前考虑的工作,和之前已经选择的工作不冲突,那么选择当前工作。
贪心算法最优性证明:
假设贪心算法不是最优的,令i1,i2,.....,ik是贪心算法求出来的一个解集合。
令j1,j2,......,jm是其他算法求出来的更优的且与贪心算法所得集合最相似的解集合。假设这两个解集合的前r个决策相同。即i1=j1,i2=j2,......,ir=jr。
由贪心算法的定义,第i(r+1)个工作一定会在j(r+1) 工作之前,因此j (r+1)工作完全可以替换为i(r+1)。替换完成后就得到了一个与贪心算法所得解更相似的解。
这与前提,OPT算法所得解与贪心算法所得解最相似矛盾。因此可得贪心算法所得解就是最优解。
其他贪心算法:kruskal,prim,dijkstra,huffman等等
分治算法(时间复杂度计算):
分治算法的思想是,将问题分成几个部分,递归的解决每个部分,最后将子问题的解决方案合并为整体的解决方案。
关于递归式的时间复杂度计算有三种方法进行求解。
1、代入法,把变量用无穷大进行代入比较。
2、递归树计算复杂度。
3、主定理。
递归树计算复杂度:
使用主定理求解时间复杂度:
主定理(Master Theorem) - 知乎 (zhihu.com)
换硬币问题(动态规划):
问题:给定货币面额:1,5,10,25,100。设计一种使用最少的硬币向顾客支付金额的方法。比如:34=25+5+1+1+1+1
此问题不能使用贪心算法求解(每次选择不超过当前面额的最大价值硬币),返例:1,10,21,34,70,100,350,1225,1500。 当支付140时,贪心解:140=100+34+1+1+1+1+1+1,动态规划解:140=70+70.
动态规划求解问题三步骤:
1、定义子问题。2、写出递归关系式。3、给出最终解。
例1:带权重的排班问题。每个工作有开始时间和结束时间和权值。要找到一种互不冲突的排班方法让所选择的工作权值最大。
定义p(j) = 最大的下标i < j,使得与工作i不冲突的最大工作号为i。p(8)=5,p(7)=3。
定义子问题opt:OPT(j)=由1~j个工作组成的不冲突且权值最大的解决方案。
情况1:OPT考虑选择第j个工作。
·不能使用冲突工作p(j)+1,p(j)+1,....,j-1。
·包含OPT(p(j))
情况2:OPT不考虑选择第j个工作。
则必须包含由工作1~j组成的最优解。
由此得到递推关系式:
写出递推关系式的求解:
例2:背包问题。给定n个物品和一个背包。第i个物品重量为wi价值为vi。背包容量为W。目标:填充背包使得物品价值最大。
定义子问题:OPT(i,w) = 当重量为w时背包能够装下的最大利润。
情况1:OPT没有选择第i个物品。
·OPT在物品{1,2,...,i-1}中,在重量为w的限制下能够得到的最大利润。
情况2:OPT选择了第i个物品。
·OPT在物品{1,2,...,i-1}在重量限制为w-wi的限制下,能够得到的最大利润加上vi。
写出递推关系式:
求解:
三、最大流问题(会画剩余图)
给定一个源点s和终点t。要找到s到t的最大的流量是多少。
有:最大流=最小割。
剩余图:
四、P、NP、NPC问题
多项式时间规约(Polynomial-Time Reductions):
问题x可以多项式时间规约到问题y,如果x的任何实例都可以通过以下的方法解决:多项式时间的计算步骤,加上多项式次调用问题y。
·如果x可以多项式时间规约到y,且y可以在多项式时间内求解,那么x也可以在多项式时间内求解。
·如果x可以在多项式时间归约到y,且x不能在多项式时间内求解,则y不能在多项式时间内求解。
·如果x能够在多项式时间规约到y,y也可以在多项式时间内规约到x,则称:
基本的规约策略:
·通过简单的等价进行规约
·从特殊情况规约到一般情况
·使用其他小工具进行规约
通过简单的等价进行规约:
独立集问题(Independent Set):给定一个图G=(V,E)和一个整数k,是否存在一个点集S是V的子集,使得|S|≥k,并且每一条边的端点在集合S中最多出现一次?
点覆盖问题(Vertex Cover):给定一个图G=(V,E)和一个整数k,是否存在一个点集S是V的子集,使得|S|≤k,并且每一条边至少有一个端点在S中出现?
从特例规约到一般情况:
集合覆盖问题:给定一个元素的集合U,S1,S2,...,Sm是U的子集,有一个整数k。存在选择小于k的子集个数,使得它们的并集等于U吗?
点覆盖问题规约到集合覆盖上:VERTEX-COVER ≤p SET-COVER
把边看成数字,点连上的边,会写入对应的集合当中。所以每一条边会出现在两个集合中。
Reductions via "Gadgets"使用其他小工具进行规约
3-SAT问题归约到独立集问题:
SAT问题:给定表达式,判断是否存在一组使表达式为真的幅值。
3-SAT问题:每个子语句中含有3个变量的SAT问题。
证明:给定一个3-SAT的实例,可以构造出一个独立集(G,k)的实例,使得当3-SAT实例值为真时,独立集有一个大小为k的子集。
构造:图G包含每个子句中的3个变量,并把这3个变量连成一个三角形,最后把每个变量和这个变量的逆相连接。
ps:3-SAT问题的解和独立集的部分解一一对应。
规约的传递性:
自规约(Self-Reducibility):
NP的定义
P的定义:多项式时间内能够找到问题的一个解。
EXP的定义:指数时间内能够找到问题的一个解。
NP的定义:多项式时间内能够验证问题的解是否正确,但是无法在多项式时间内找到具体的那个解。
证明一个问题是不是属于NP,即确定此问题能否在多项式时间内验证解的正确性。
哈密尔顿圈:给定一个无向图G=(V,E),是否存在一个简单回路访问图中所有的点?
哈密尔顿圈的NP证明:若给定了一个点的访问序列,就能在多项式时间内验证排列是否只包含图中每个点一次,并且相邻的点之间都有边相连。
NPC问题(NP-Completeness):
NPC的定义:一个问题是属于NP的,并且其他的NP问题都可以在多项式时间规约到这个问题。那么称这个问题是NPC问题。
如何证明一个问题属于NPC:
世界上第一个NPC问题:CIRCUIT-SAT问题。
Sequencing Problems(哈密尔顿圈,旅行商问题):
哈密尔顿圈:给定一个无向图G=(V,E),是否存在一个简单回路访问图中所有的点?
有向图中的哈密尔顿圈问题:
3-SAT问题到有向图哈密尔顿圈的规约:
证明:给定一个3-SAT的实例,就可以构造出一个有向图哈密尔顿圈的实例,使得3-SAT问题的解也是有向图哈密尔顿圈的解。
构造如下:每一行对应3-SAT问题中的一个变量。如果哈密尔顿圈从左向右访问这一行,则表明当前变量为真。如果方向是从右向左,则表明当前变量为假。 对于每一个子句中的三个变量,都会向对应行连接两条有向边表示选或不选。每行共3k+3个点
⇒:如果3-SAT问题有解,那么按照从左到右变量为真,从右到左变量为假的设定。图中一定存在一个哈密尔顿圈遍历所有点。
⇐:如果哈密尔顿圈存在,则一定会访问C1,C2点,就表明3-SAT子句中至少会存在一个值为真的变量。
旅行商问题(Traveling Salesperson Problem):
给定一组城市,n个点和一个两点间距离函数d(u,v),是否有一个长度≤d且访问了每个城市的旅行?
Partitioning Problems(分区问题)
3D-MATCHING(三维匹配问题):给定n个教师,n个课程,n个时间,和一个列表展示了教师愿意在哪个时间段上哪个课程,问是否有一种排班方式让所有课程会在不同的时间上课?
3-SAT问题规约到3D-MATCHING问题:
Graph Coloring(图着色问题):
3-COLOR问题:给定一个无向图G,问是否存在一种方式让图中的点着红、绿、蓝三色,且任意相邻两点颜色不相同。
3-SAT问题规约到3-COLOR问题:
Numerical Problems(数值问题):
五、近似算法(Approximation Algorithms)
NP问题没办法直接求解,因此使用近似算法来求解NP问题。
·要证明近似算法能在多项式时间内求解
·要能够解决问题的任意实例
·要能够证明近似解在正解的一个范围内
负载均衡Load Balancing: List Scheduling
问题输入:有m台机器,n个工作,工作j有处理时延tj,每个工作必须在一台机器上完成。一台机器同一时间只能开展一个任务。
定义:J(i)是分配给机器i的任务集。这台机器上的负载(load)就是J(i)中任务时间之和。
定义:makespan是各机器上的最大负载。
负载均衡就是要让各机器上的最大负载最小。
理论:贪心算法对于这个问题可以达到二倍近似解。
引理1:最优makespan一定大于等于各工作中最大的工作时间max(tj)
引理2:最优makespan一定大于等于各工作时间之和的平均值
证明:贪心算法是二倍近似算法
考虑负载Li是机器i的总耗时,令j是机器i上最后的一个工作。可知,当工作j被分配给任务i的时候,i有最小的工作负载(由贪心算法可知)。在分配工作j之前,机器i上的负载时Li-tj≤Lk,对于所有的k,1≤k≤m。
于是有:机器i去掉工作j后,其总负载小于等于所有机器的平均负载。由引理2得,也小于等于最优解。
≤ L*
于是有:Li=(Li-tj)+ tj ≤ 2L*。 (tj也一定小于等于最优解 引理1)。
中心选择Center Selection
问题输入:设置n个站点,一个整数k>0
中心选择问题:找到k个中心C,让各个集合到中心点的最大值最小。
定义:dist(x,y)=x和y之间的距离。dist(si,C) = 从点si到最近的一个中心点的距离。
r(C)=max dist(si,C) = 最小的覆盖半径
目标:找到一个集合C,最小化r(C),并且C的大小=k。
距离函数的特性:dist(x,x)=0; dist(x,y)=dist(y,x); dist(x,y)≤dist(x,z)+dist(z,y)
贪心算法求近似解:每次选择下一个中心点的时候,选择离现有的中心点最远的那个点。
于是观察到:算法结束时,C中任意两中心点的距离至少有r(C)远。
理论:令C*是最优的中心集合解,有r(C)≤2r(C*)
证明:
The Priceing Mthod:Vertex Cover
带权重的点覆盖:给定一个顶点带权重的图,找到一个权重最小的点覆盖。
Pricing Method:
LP Rounding:Vertex Cover
带权重的点覆盖:
Knapsack Problem
背包问题的输入不是多项式的,因此没有多项式时间的解。
一种直观的近似方法:所有的价格除以价格中的最小值。