算法分析复习

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

找出最优解优值。

3.以自底向上的方式计算出最优值。

4.
划一样,备忘录方法用表格保存已解决的子问题的答案,在下次需要解此问题时,只要简单地查看该子问题的解答,而不必重新计算。

不同的是备忘录的递归方式是自顶向下,而动态…。

因此,它们的控制结构相同,区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求
通过一系列局部最优的选择,即贪心选择来达到。

这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。

动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小
针对所的解空间结构;3.以深度优先方式搜索解空间, 于求解目标不同,导致对解空间的搜索方式也不同,回溯法以深度优先的方式搜索解空间,而分枝限界法以广度优先或以最小耗费优先的
机化算法求解两次可能得到完全不同的效果。

数值随机化算法、蒙特卡罗算法、拉斯维加斯算法、舍伍德算法。

算法是由若干条指令组成的有序序列,并且具 要空间资源的量称为空间复杂性。

几个定义。

O 、o ,复杂渐进性
设某算法在输入规模为n 时的计算时间为
T(n)=10*2n。

若在甲台计算机上实现并完成该算法的时间为t 秒,现有一台运行速度是甲的64倍的另一台计算机乙,问在乙计算机用同一算法在t 秒内能解决问题的规模是多大? 设新机器用同一算法在t 秒内能解输入规模为
n1的问题。

则有t=10*2n =10*2n1
/64,可得n1=n+6
设某算法在输入规模为n 时的计算时间为
T(n)=n 2。

若在甲台计算机上实现并完成该算法的时间为t 秒,现有一台运行速度是甲的64倍的另一台计算机乙,问乙计算机上用同一算法在t 秒内能解决的问题的规模是多大? 设新机器用同一算法在t 秒内能解输入规模为
n1的问题。

则有t=n 2 = n12
/64,可得n1=8n 快速排序算法最好、最坏情况下的复杂度为多少?如何修改快速排序算法,使它在最坏情况下的计算时间为O(nlogn)。

快速排序算法最坏情况下的复杂度为
T(n)=O(n 2
)。

修改函数Parition ,可以设计出采用随机策略的快速排序算法。

平均复杂性
O(nlogn);最坏O(n 2
)
分治算法基本思想是将一个规模为n 的问题分解为k 个规模较小的子问题,这些子问题互相独立且与原问题相同。

递归地解这些子问题,
界条件、递归方程。

快速排序算法思想对于输入的子数组a[p:r],按以下3个步骤进行排序:分解、递归求解、合并。

动态规划算法思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解
回溯法思想从开始结点(根节点)出发,以深度优先方式搜索整个解空间。

分支限界法思想:分支限界法常以广度优先或以最小耗费优先的方式搜索问题的解空间树。

用动态规划求解问题中具有两个性质:最优子结构性质、子问题重叠性质
最大子段和问题的简单算法、分治算法和动态规划算法的算法复杂度分别是多少?O(n 3
),O(nlogn),O(n)。

P59-62
矩阵连乘问题动态规划MatrixChain 时间上界
是O(n 3);所占空间是O(n 2
)。

用贪心算法求解的问题中具有两个性质:贪心选择性质、最优子结构性质 贪心算法的活动安排问题要求高效地安排一系列争用某一公共资源的活动,就是要在所给的活动集合中选出最大的相容活动子集合
用回溯法和分支限界法解题时常遇到的两类典型的解空间树是什么通常情况下分别有多少个
叶结点:子集树(2n
)、排列树(n!)
分支限界法最常见的两种方式是什么?根据什么来划分的
队列式(FIFO )分支限界法、优先队列式分支限界法;根据活结点表中选择下一扩展结点的不同方式区分
产生伪随机数最常用的方法是线性同余法
排列问题的算法
Void perm (type list[],int k,int m ) {if(k==m){for(int i=0;i<=m;i++) cout<<list[i];cout<<endl;} elsefor(int i=k;i<=m;i++)
{swap(list[k],list[i]);swap(list,k+1,m); swap(list[k],list[i]);}}
Inline void swap(type &a,type &b) {type temp=a;a=b;b=temp;} 二分搜索技术算法
Int binarysearch(type a[],const type& x,int n)
{int left=0;int right=n-1; while(left<=right)
{int middle=(left+right)/2; if(x==a[middle])return middle; if(x>a[middle])left=middle-1;} return -1;} 快速排序算法
Int partition(type a[],int p,int r) {int i=p,j=r+1;type x=a[p];
While(true){while(a[++i]<x&&i<r);
While(a[--j]>x);if(i>=j)swap(a[i],a[j]);}
a[p]=a[j];a[j]=x;return j;}
最长公共子序列动态规划算法,最长公共子序列长度LCSLength 的算法及复杂度。

构造最长公共子序列LCS 的算法及复杂度。

Void lcslength (int m,int n,char *x,char*y,int **c,int **b) { int i,j; for(i=1;i<=m;i++)c[i][0]=0; for(i=1;i<=n;i++)c[0][i]=0; for(i=1;i<=m;i++) for(j=1;j<=n;j++)
{if(x[i]==y[i]){c[i][j]=c[i-1][j-1]+1;b[i][j]=1;}
Else if(c[i-1][j]>=c[i][j-1]){ c[i][j]=c[i-1][j];b[i][j]=2;}
Else {c[i][j]=c[i][j-1];b[i][j]=3;}}}耗时O(mn)
Void lcs (inr i,int j,char *,int **b){ If(i==0||j==0)return;
If((b[i][j]==1){lsc(i-1,j-1,x,b)cout<<x[i];}
Else if(b[i][j]==2)lcs(i-1,j,x,b); Else lcs(I,j-1,x,b);}时间为O(m+n) 最大子段和问题动态规划算法 Int maxsun(int n,int *a) {int sum=0,b=0;
For(int i=0;i<=n;i++){ if(b>0)b+=a[i];else
b=a[i];if(b>sum)sum=b;}return sum;} 回溯法搜索子集树的算法框架 Void backtrack(int t) {if(t>n)Output(x);
Else for(int i=0;i<=1;i++){x[t]=i; If((Constraint(t)&&Bound(t)) backtrack(t+1);)}}
回溯法搜索排列树的算法框架 Void backtrack(int t) {if(t>n)Output(x); Else for(int i=0;i<=n;i++){swap(x[t],x[i]);
If(Constraint(t)&&Bound(t))backtrack(t+1);
Swap(x[t],x[i];)}}
最大团问题中的回溯算法 Void Clique::Backtrack(int i) {if(i>n){for(int
j=1;j<=n;j++)bestx[j]=x[j];bestn=cn;retu rn;}
Int OK=1;for(int j=1;j<I;j++)
If(x[j]&&a[i][j]==0){OK=0;break;}
If(OK){x[i]=1;cn++;Backtrack(i+1);x[i]=0;cn--;}
If(cn+n-i>bestn){x[i]=0;Backtrack(i+1);}}
0-1背包问题中的回溯算法
Void Knap<typew,typep>;:Backtrack(int i) {if(i>n){bestp=cp;return;} If(cw+w[i]<=c){cw+=w[i];cp+=p[i]; Backtrack(i+1);cw-=w[i];cp-=p[i];} If(Bound(i+1)>bestp)Backtrack(i+1);} 贪心算法多机调度问题:设有n 个独立的作业{1,2,…,n},由m 台相同的机器进行加工处理。

作业i 所需的处理时间为t i ,现约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理,作业不能拆分成更小的子作业。

试写出用贪心算法解决该问题的算法。

class jobnode{
friend void greedy(jobnode *,int ,int); friengvoid main(void);
public:operator int()const{return time;} private:int ID,time;}; class machinenode{
friend void greedy(jobnode *,int,int); public: operator int()const{return avail;}
private:int ID,avail;}
void greedy(type a[],int n,int m) {if(n<=m){cout<<”为每个作业分配一台机器.”<<endl;return;}
Sort(a,n);minheap<machinenode>h(m); Machinenode x;
For(int i=1;i<=m;i++)
{x.avail=0;x.ID=i;H.Insert(x);} For(int i=n;i>=1;i--)
{H.Deletemin(x);cout<<”将机器”<<x.ID<<”从”<<x.avail<<”
到”<<(x.avail+a[i].time<<”的时间段分配给作业”<<a[i].ID<<endl;
x.avail+=a[i].time;H.Insert(x);}}
i mport java.io.BufferedReader; import java.io.IOException;
import java.io.InputStreamReader; public class 异常 {
static void myFunc(String s) throws StringTooShortException,StringTooLongExc eption{ if(s.length()>=5 && s.length()<=10)
System.out.println(s); else if(s.length()<5)
throw new StringTooShortException(s); else throw new StringTooLongException(s);; }
public static void main(String args[]) throws IOException{ InputStreamReader in = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(in);
String str=br.readLine(); try{ myFunc(str); }
catch(StringTooShortException e)
{System.out.println("发生字符串太短异常:"+e); }
catch(StringTooLongException e)
{System.out.println("发生字符串太长异常:"+e); }
finally{System.out.println("程序执行结束"); }} }
class StringTooShortException extends Exception {public StringTooShortException(String s) {System.out.println(s+" is too short!");}}
class StringTooLongException extends Exception{public
StringTooLongException(String s)
{System.out.println(s+" is too long!");}}
迭代器(Iterator )提供了一种通用的方式来访问集合中的元素。

import java.util.ArrayList; public class 迭代器 {
public static void main(String[] args){ ArrayList<Integer> list = new ArrayList<Integer>(); list.add(20); list.add(10); list.add(20); list.add(20);list.add(3);
for(int i:list) System.out.println(i); java.util.Iterator<Integer> it = list.iterator();
while (it.hasNext()){Integer i = it.next();
System.out.println(i);}}}
迭代器(Iterator )提供了一种通用的方式来访问集合中的元素。

编写一个程序把学生的成绩存放在一个链表中,使用迭代器实现遍历链表并显示结果,具体显示结果如下所示。

姓名 学号 成绩 赵好民 9012 80.0
钱小青 9013 90.0 孙力枚 9014 78.0 周左右 9015 55.0
import java.util.ArrayList; public class 迭代器链表 {
public static void main(String[] args) { ArrayList<Student>list=new ArrayList<Student>();
list.add(new Student("199903","张三",70));
list.add(new Student("199904","李四",68));
list.add(new Student("199905","王五",68));
for(Student s:list)
System.out.println(s.getName()); java.util.Iterator<Student> it = list.iterator();
while (it.hasNext()){Student s = it.next();
System.out.println(s.getName());}}}
class Student{ private String sid; private String name; private int grade;
public Student(String id,String name,int grade)
{this.sid = id; = name; this.grade = grade;
public String getSid() {return sid;}
public void setSid(String sid) {this.sid = sid;}
public String getName() {return name;} public void setName(String name) { = name;}
public int getGrade() {return grade;} public void setGrade(int grade) {this.grade = grade;}}
使用Hashtable 存储每个学号对应的学生年龄 import java.util.Hashtable; public class 哈希表存储 {
public static void main(String[] args) { Hashtable<String ,Integer> hTable = new Hashtable<String,Integer>();
hTable.put("003",20);hTable.put("001",19);
hTable.put("002",22);
if (hTable.containsKey("004"))
System.out.print( hTable.get("004")); else{hTable.put("004",21);} java.util.Iterator<String> it = hTable.keySet().iterator(); while (it.hasNext()){ String s =it.next();System.out.print(s+":"); System.out.println(hTable.get(s));}}} 先设计一个类:Student ,包含3个成员变量:学号、姓名、英语成绩,并实现赋成员变量初值的构造方法。

* 然后编写程序,使用Hashtable()创建一个散列表,存放Student 对象,
* 每个Student 对象用该对象的学号作为关键字,检索学号为199902的元素并显示, * 然后遍历当前散列表并显示所有元素 import java.util.Hashtable;
public class 存储遍历学生信息 {
public static void main(String[] args) { Hashtable<String,Student>hTable=new Hashtable<String,Student>(); hTable.put("199903",new
Student("199903","张三",70)); hTable.put("199904",new
Student("199904","李四",68)); hTable.put("199905",new
Student("199905","王五",68)); if (hTable.containsKey("199904")) System.out.println(hTable.get("199904").getName()+""+
hTable.get("199904").getSid()+""+hTable.get("199904").getGrade());
System.out.println( "学生总数:"+hTable.size());
for(String s:hTable.keySet()){ //System.out.println(s);
System.out.println(hTable.get(s).getName ()+""+hTable.get(s).getSid()+" "+hTable.get(s).getGrade());}}}。

相关文档
最新文档