最后待改 算法一直开.docx
- 文档编号:24260555
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:19
- 大小:733.85KB
最后待改 算法一直开.docx
《最后待改 算法一直开.docx》由会员分享,可在线阅读,更多相关《最后待改 算法一直开.docx(19页珍藏版)》请在冰豆网上搜索。
最后待改算法一直开
一、算法时间复杂性问题
1.试证明下面的定理:
(背下来了可以不要!
)
(1)如果f(n)=O(s(n))并且g(n)=O(r(n)),则f(n)+g(n)=O(s(n)+r(n))
(2)如果f(n)=O(s(n))并且g(n)=O(r(n)),则f(n)*g(n)=O(s(n)*r(n))
根据符号O的定义,存在正常数Ci和自然数Ni,使得对所有的n>=N有i=1.2,f(n)<=C1s(n),g(n)<=C2r(n)
所以f(n)+g(n)<=C1s(n)+C2r(n),f(n)*g(n)<=C1C2s(n)r(n);
令C3=max(C1,C2),C4=C1C2;
则:
f(n)+g(n)<=C3[s(n)+r(n)]=O(s(n)+r(n))
f(n)*g(n)<=C4*s(n)*r(n)=O(s(n)*r(n))
2.假设某算法在输入规模为n时的计算时间为:
T(n)=3*2n,在A型计算机上实现并完成该算法的时间为t秒,现有更先进的B型计算机,其运算速度为A型计算机的64倍。
试求出若在先进的B型机上运行同一算法在则T秒内能求解输入规模为多大的问题?
某台t秒内完成的基本运算的次数=3*2^n
新机器t秒内完成的基本运算的次数=64*3*2^n=2^6*3*2^n=3*2^(n+6)
T=T(n)=3*2^nn=log2(T/3)
设新机器输入规模为n1,则:
n1=log2(3*2^(n+6)/3)=n+6
在这台新机器上用同一算法在t秒内能解输入输入规模为n+6的问题。
3.试说明为什么“在现代计算机上运行指数(如2n)时间算法是不可能的,要想在顺序处理机上扩大所处理问题的规模,有效的途径是降低算法计算复杂度的数量级,而不是提高计算机的速度”。
Ο
(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(nn)
一个计算时间为Ο
(1)的算法,它的基本运算执行的次数是固定的,因此,总的时间由一个常数(即,零次多项式)来限界,而一个时间为Ο(n2)的算法则由一个二次多项式来限界。
以下六种计算时间的多项式时间算法是最为常见的,其关系为
Ο(2n)<Ο(n!
)<Ο(nn)
指数时间算法一般有Ο(2n)、Ο(n!
)和Ο(nn)等。
其关系为
其中,最常见的是时间为Ο(2n)的算法。
当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊,因为根本就找不到一个这样的m,使得2n囿界于nm。
换言之,对于任意的m≥0,总可以找到n0,当n≥n0时,有2n>nm。
因此,只要有人能将现有指数时间算法中的任何一个算法简化为多项式时间算法,那就取得了一个伟大的成就。
Ο(log2n)、Ο(n)和Ο(nlog2n)比另外三种时间函数的增长率慢得多。
~由这些结果可看出,当数据集的规模(即n的取值)很大时,要在现代计算机上运行具有比Ο(nlog2n)复杂度还高的算法往往是很困难的。
尤其是指数时间算法,它只有在n值取得非常小时才实用。
要想在顺序处理机上扩大所处理问题的规模,有效的途径是降低算法的计算复杂度的数量级,而不是提高计算机的速度。
二、简答
1.对计算复杂性的研究能够使人们弄清所求解问题的固有难度,并得出评价某类算法优劣的准则,用以指导设计出更高效的算法。
试用简短的语言说明“建立一个问题复杂性的下界要比确定它的上界困难得多!
”
其复杂性上界是已知求解该问题的最快算法的费用,而复杂性下界只能通过理论证明来建立 。
寻求某个问题的计算复杂性上界,只要研究一个算法的复杂性即可。
但是要寻求同一问题的计算复杂性下界,则必须考察所有的解决该问题的算法,证明一个问题的复杂性下界就需要证明不存在任何复杂性低于下界的算法。
显然,建立下界要比确定上界困难得多。
2.满足何种性质的问题被称为称为NP完全问题?
请简述研究NP完全问题的意义;
(1)NP即是多项式复杂程度的非确定性问题。
而如果任何一个NP问题都能通过一个多项式时间算法转换为某个NP问题,那么这个NP问题就称为NP完全问题。
如果一个NP完全问题能在多项式时间内得到解决,那么NP中的每一个问题都可以在多项式时间内解决。
(2)NP完全是指这样一类NP问题,所有的NP问题都可以用多项式时间划归到他们中的一个.所以显然NP完全的问题具有如下性质:
它可以在多项式时间内求解,当且仅当所有的其他的NP-完全问题也可以在多项式时间内求解。
这样一来,只要我们找到一个NPC问题的多项式解,所有的NP问题都可以多项式时间内划归成这个NPC问题,再用多项式时间解决,这样NP就等于P了.
NP完全性理论的重要性:
知道一个问题是NP完全的就给我们提供了有价值的信息,告诉我们采用什么样的途径可以是最富有成效的。
一定不要去优先寻找有效的、精确的算法。
现在比较适当的途径是集中精力致力于其他较低目标的方法。
例如,你可以寻找解决这个问题的各种特殊情况的有效算法。
寻找在大多数情况下看来能快速运算的算法,虽然不能保证它在任何情况下都能快速地运算。
或者你甚至可以放松问题的某些方面,寻找一个只能给出满足大部分要求的快速算法。
简言之,NP完全性理论的初步应用是帮助算法设计人员找到最有可能得到有用的算法的努力方向
3.“当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质”。
问题的最优子结构性质是该问题可用动态规划算法求解的基本要素,试简要阐述“论证某一问题的最优子结构性质”时的一般方法;
矩阵连乘计算次序问题的最优解包含着其子问题的最优解。
这种性质称为最优子结构性质。
在分析问题的最优子结构性质时,所用的方法具有普遍性:
首先假设由问题的最优解导出的子问题的解不是最优的,然后再设法说明在这个假设下可构造出比原问题最优解更好的解,从而导致矛盾。
利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。
最优子结构是问题能用动态规划算法求解的前提。
同一个问题可以有多种方式刻划它的最优子结构,有些表示方法的求解速度更快(空间占用小,问题的维度低)
例如:
假设(y1,y2,…,yn)是0-1背包问题的一个最优解,而(y2,…,yn)是相应子问题的一个最优解,有
假设(y2,…,yn)不是一个最优解,而(z2,…,zn)是最优解,由此可知,
这说明(z1,z2,…,zn)是问题的整体最优解,与(y1,y2,…,yn)是最优解矛盾,所以证明了最优子结构性质!
三、算法设计与分析问题
1.最大值和最小值问题的最优算法(18)
给定n个实数存放于一维数组A中,试设计一个算法在最坏情况下用3n/2-2次的比较找出A中的最大值和最小值(为简化,可假设n为偶数)。
未比较的序列首尾各取一个元素,比较这两个元素的大小;大的元素与max比较来确定max的新值,小的元素与min来比较确定min的新值。
由于成对处理,总的循环次数为n/2,而每次循环进行3次比较,总比较次数就是3n/2次。
-2是针对第一次,只进行一次比较。
确定最初的最大值和最小值!
若n为奇数则总共比较次数是3n/2次,即把一个数拿出来最后分别与最大值和最小值比较!
是两次,正好把前边的-2给去掉!
2.社会名流问题
在n个人中,一个被所有人知道但却不知道别人的人,被定义为社会名流。
现在的问题是如果存在,试找出该社会名流。
你可以使用的唯一方式是询问:
“对不起,请问你知道那个人吗?
”(假定所有回答都正确,甚至这位社会名流也将回答。
)我们的最终目标是将询问的数目最小化。
试设计表达社会名流问题的数据结构(提示:
利用有向图表示这n个人之间的关系),并在此基础上设计问题求解的算法。
(20分)
给定一个n×n邻接矩阵,确定是否存在一个i,
其满足在第i列所有项(除了第ii项)都为1,并
且第i行所有项(除了第ii项)都为0。
大致的算法思路:
随便取一个非对角线元素,比如Array[i][j],如果Array[i][j]=0成立,则j不是社会名流,于是删去第j行和第j列。
同样,如果Array[i][j]=1成立,则删去第i行和第i列;
总之,无论对应项取何值,都可以删去一行和一列,因此整个操作只耗费O(n)的时间。
重复此操作直至剩下最后一个元素。
最后,检验该元素是否为社会名流即可。
如果该元素不是,则该群人中不存在社会名流。
3.数列极差问题
在黑板上写了N个正数组成的一个数列,进行如下的操作:
每一次任选其中的两个数设为a和b,将其擦去,然后在数列中加入一个新的数a*b+1,如此下去直至黑板上只剩下一个数为止。
在所有按这种操作方式最后得到的数中,最大的数记为Max,最小的数记为Min,则该数列的极差定义为M=Max-Min。
试为按上述方法求解“数列极差”设计算法(此题不要求用伪码描述—只需写出实现的思想与理由)。
贪心算法最重要的两个性质是:
贪心选择性质和最优子结构性质。
贪心选择性质是所求问题的整体最优解可以通过一系列局部最优的选择,也就是贪心选择来达到。
而最优子结构性质是指一个问题的最优解包含其子问题的最优解。
问题的关键就是MAXMIN值的求解问题,所以首先看下怎么样来求MAXMIN值。
设有三个数xyz,且x num1=(x*y+1)*z+1=xyz+z+1, num2=(x*z+1)*y+1=xyz+y+1, num3=(y*z+1)*x+1=xyz+x+1。 很容易看出num1>num2>num3。 所以我们可以得出结论: 优先选择数列中最小的2个数进行(a*b+1)运算得到的值大,优先选择数列中最大的2个数进行(a*b+1)运算得到的值小。 我们可以把整体的MAX,MIN值通过一系列局部求MAX,MIN值来求我们想要的结果。 我们在看下用贪心策略求解的合理性: 假设经(N-3)次运算后得到3个数: xymax(max>x>y), 其中max是(N-2)个数经(N-3)次运算后所得的最大值, 此时最大值m=(x*y+1)×max+1。 若经(N-2)次变换后所得的3个数为: xyz(z>x>y)且z不为(N-2)次变换后的最大值, 即z<max则所求得的最大值为: m’=(x*y+1)*z+1, 此时m-m’=(1+x*y)(max-z)>0所以此时不为最优解。 所以若使第k(1≤k≤N-1)次变换后所得值最大,必使(k-1)次变换后所得值最大(符合贪心策略的最优子结构性质),在进行第k次变换时,只需取在进行(k-1)次变换后所得数列中的两最小数x,y进行运算,再把结果插入到数列即可。 所以综上所述: 该算法可以简单的描述为: MAX: 不断地取当前黑板上的两个最小的数进行运算并且放回,会使最后的结果最大。 MIN: 不断地取当前黑板上的两个最大的数进行运算并且放回,会使最后的结果最小。 数列极差就是: MAX-MIN! 另: 使用一个快速排序的迭代模型可以使原递归算法所需的栈空间总量减至O(logn)。 试设计这一迭代模型(算法)。 structnode {intlow,high;}st[10000]; voidquicksort2(intdata[],ints,intt){ inttop=-1,low,high;top++;st[top].low=s;st[top].high=t; while(top>-1){low=st[top].low;high=st[top].high;top--;intw; if(low st[++top].low=low;st[top].high=w-1;st[++top].low=w+1;st[top].high=high;}} 作业题整理补充: 其实已经记下来了,可以不补充! 算法课程经典问题整理: 第一章和第二章: 算法特性: 有穷,可行,确定,输入,输出四元组(Q,I, ,f)时间复杂性的定义掌握,理解上界,下界和精确界 的证明过程,已经背下来了,分为多项式时间算法和指数时间算法;O (1) ) 小的雏形: 买鸡问题: (到最后最好记下来这些简单的,免得占地儿! ) •voidchicken_problem(intn,int&k,intg[],intm[],ints[]) •{inti,j,a,b,c;k=0;i=n/5;j=n/3; •for(a=0;a<=i;a++){ •for(b=0;b<=j;b++){ •c=n-a-b; •if((5*a+3*b+c/3==n)&&(c%3==0)){ •g[k]=a; •m[k]=b; •s[k]=c; •k++}}}} 货郎担问题: •voidsalesman_problem(intn,float&min,intt[],floatc[][]) •{intp[n],i=1; •floatcost; •min=MAx_FLoat_NUM; •while(i<=n! ){ •产生n个城市的第i个排列于p; •cost=路线p的费用; •if(cost •把数组p的内容复制到数组t; •min=cost;} •i++;}} 选择排序及时间复杂度分析: 代码简单自己看一下! 时间复杂度1/2*n(n-1) 顺序查找最坏特性: 失败查找最坏特性WAu(n)=n+1;二分查找思想: (代码记下来很简单) 淘汰法找最大和次大元,没明白再看看找最大元开销: T1(n)=n-1次大元开销: T2(n)=log2n-1整体的时间复杂度: n+log2n-2 递归与分治经典问题 小雏形: 递归删除链表当中的某个元素: voiddelete_L(LinkList&L,ElemTypex){ //删除以L为头指针的带头结点的单链表中 //所有值为x的数据元素 if(L->next){ if(L->next->data==x){ p=L->next;L->next=p->next; delete(p);delete_L(L,x);} elsedelete_L(L->next,x);}}//delete 汉诺塔: voidhanoi(intn,charx,chary,charz){ //将塔座x上按直径有小到大且至上而下编号为1-n的n个圆盘按规则搬到塔座z上,y可用作辅助塔座。 if(n==1) move(x,1,z);//将编号为1的圆盘从x移到z else{ hanoi(n-1,x,z,y);//将编号为1至n-1的圆盘移动到y,z作辅助塔 Move(x,n,z);//将编号为n的圆盘从x移到z Hanoi(n-1,y,x,z);//将y上编号为1至n-1的圆盘移到z,x作辅助塔 } } 合并排序: : (1)合并排序时间复杂度的计算: 类似的找最大元也是这个思想,分别找最大元,再比较出较大的时间复杂度: : T(n)=n-1 (2)第K小元素: (3)时间复杂度分析: (4)快速排序: 主要思想: template voidQuickSort(Typea[],intp,intr) {if(p QuickSort(a,p,q-1);//对左半段排序 QuickSort(a,q+1,r);//对右半段排序}} 最坏时间复杂度O(n2) 平均时间复杂度O(nlogn) 辅助空间: O(n)或O(logn) 贪心经典问题: 贪心选择性质和最优子结构性质! 简答题: 贪心和动态规划的区别! 主要理解贪心的思想局部! 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。 这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。 动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。 贪心算法和动态规划算法都要求问题具有最优子结构性质,这是2类算法的一个共同点 *注意贪心不可以解决0-1背包问题: 只有动态规划可以解决0-1背包问题! 背包问题: 首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。 若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。 依此策略一直地进行下去,直到背包装满为止。 最优装载问题照着这个代码完全可以写出来! 动态规划经典问题: 最优子结构性质和重叠子问题性质! 重点最优子结构证明! 上述习题中已经有了! 小雏形: 矩阵连乘问题: 时间复杂度: O(n3),空间复杂度;O(n2)平方 最长公共子序列: 桶排序: 桶排序工作的原理是: 将阵列分到有限数量的桶子里。 每个桶子再个别排序。 当要被排序的阵列内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。 要对大小为[1..1000]范围内的n个整数A[1..n]排序,可以把桶设为大小为10的范围,具体而言,设集合B[1]存储[1..10]的整数,集合B[2]存储(10..20]的整数,……集合B[i]存储((i-1)*10,i*10]的整数,i=1,2,..100。 总共有100个桶。 然后对A[1..n]从头到尾扫描一遍,把每个A[i]放入对应的桶B[j]中。 然后再对这100个桶中每个桶里的数字排序,这时可用冒泡,选择,乃至快排,一般来说任何排序法都可以。 最后依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,这样就得到所有数字排好序的一个序列了。 假设有n个数字,有m个桶,如果数字是平均分布的,则每个桶里面平均有n/m个数字。 如果对每个桶中的数字采用快速排序,那么整个算法的复杂度是O(n+m*n/m*log(n/m))=O(n+nlogn-nlogm) 从上式看出,当m接近n的时候,桶排序复杂度接近O(n)。 苑的笔记: 分治与递归 1、两路归并排序【2-waysortMergeSort】T(n)=nlogn-n+1=O(nlogn)最坏时间复杂度,平均时间复杂度。 2、找最大元T(n)=n-1 3、大整数的乘法把大整数分成两段,减少乘法次数,T(n)=O(n^(log3))=O(n^1.59) 3T(n/2)+kn(n>1) 递归T(n)=k(n=1)k是整数 4T(n/2)+kn(n>1) T(n)=k(n=1)k是整数 4、矩阵1)普通算法T(n)=O(n^3) 2)Strassen算法T(n)=O(n^log7)=O(n^2.81) 5、Hanoi塔算法T(n)=O(2^n)voidhanoi(n,x,y,z)x源;z目的;y辅助;n盘子个数 6、二分搜索(已排好顺序)T(n)=O(logn) 7、棋盘覆盖chessBoard2^k*2^k的棋盘,用到的L形骨牌个数恰为(4^k-1)/3。 T(k)=O(4^k) 8、快速排序QuikSort(a[],p,r)p上界,r下界。 最坏时间复杂度O(n^2);平均时间复杂度O(nlogn); 9、最接近点对问题T(n)=O(nlogn) 贪心算法 1、活动安排问题1)活动已按结束时间的非递减顺序排列O(n);2)没排序O(nlogn) 2、贪心算法的基本要素两性质1)贪心选择性2)最优子结构性质 3、背包问题: 贪心算法;0-1背包问题: 动态规划 4、最优装载T(n)=O(nlogn) 5、哈夫曼编码O(nlogn) 6、单源最短路径O(n^2) 动态规划 1、矩阵连乘问题时间上界O(n^3)占用空间O(n^2) 2、设计动态规划算法的步骤1)找出最优解的性质,并刻画其结构特征;2)递归地定义最优值;3)以自底向上的方式计算出最优值;4)根据计算最优值时得到的信息构造最优解 3、动态规划算法的基本要素1)最优子结构;2)子问题重叠3)备忘录法 4、最长公共子序列T(n)=O(mn)+O(m+n) 5、多段图问题向前递推 6、 0-1背包问题 设所给0-1背包问题的子问题 作业: 2、SupposewearegiventwoorderedsearchtablesSandT,eachwithnelements(withSandTbeingimplementedwitharrays).DescribeanO(lgn)-timealgorithmforfindingthekthsmallestkeyintheunionofthekeysfromSandT(assumingnoduplicates). 事件复杂度O(log(k)) 在网上看的,和同学商讨过,可行,认为此方法比上个log(m)+log(n)的方法要好 第一个数组m个元素 第二个数组n个元素 分别从两个数组找第k/2个数,a[k/2],b[k/2]; 假设a[k/2] 下面分析为什么可以删去: 因为a[k/2] 其他情况同理; 当m或n小于k/2时,假设m 这样每次k都减半,直到k等于1时,从比较两个数组头中 比较小的就是所求。 行运算,再把结果插入到数列即可。 4、试说明如何修改快速排序算法,使它在最坏情况下的计算时间为O(nlgn)。 每次看选定的标定数是在左半还是右半,然后根据要求对剩下的进行排序 5、试设计在O(n)时间内求得数组A[1..n]的中位数的算法。 桶排序 因为桶式排序是数据排序,所以设置的桶的键值为0~9共十个桶。 每次从数据的最后一个数位开始扫描,如果这个数位的值与桶的键值相等,就把这个数据放入桶内。 桶可以看作是一个有序的链表,后进入的元素排在先进入的数据的后面,直到所有的数据都完成扫描,算作一次扫描。 以后依次取倒数第二个扫描,按照桶的键值开始扫描,同样把数位的值与桶的键值相等的数据放入桶内。 直到所有数据的最高数位也完成扫描。 最后一次扫描完成,桶的键值从低到高,把这些链表串起来输出的结果就是原来数据的从小到大排序。 在桶排序算
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最后待改 算法一直开 最后 算法 一直