算法导论上机报告.docx

上传人:b****6 文档编号:8546189 上传时间:2023-01-31 格式:DOCX 页数:24 大小:26.58KB
下载 相关 举报
算法导论上机报告.docx_第1页
第1页 / 共24页
算法导论上机报告.docx_第2页
第2页 / 共24页
算法导论上机报告.docx_第3页
第3页 / 共24页
算法导论上机报告.docx_第4页
第4页 / 共24页
算法导论上机报告.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

算法导论上机报告.docx

《算法导论上机报告.docx》由会员分享,可在线阅读,更多相关《算法导论上机报告.docx(24页珍藏版)》请在冰豆网上搜索。

算法导论上机报告.docx

算法导论上机报告

 

算法导论

上机报告

 

班级:

1313012

学号:

姓名:

黄帮振

实验编号

1

题目1

归并排序算法

实验内容

描述一个运行时间为θ(nlgn)的算法给定n个整数的集合S和另一个整数x该算法能确定S中是否存在两个其和刚好为x的元素。

实验目的

用分治思想,设计子问题,实现归并排序算法;

报告正文

一、算法分析

1、运用归并排序算法

归并排序运用的是分治思想,时间复杂度为θ(nlgn)能够满足题目要求的运行时间。

归并排序的分解部分是每次将数组划分两个部分,时间复杂度为θ

(1)再对已经分解的两个部分再进行分解直到将数组分解成单个元素为止。

解决部分是递归求解排序子序列,合并部分是将已经排序的子序列进行合并得到所要的答案,时间复杂度为θ(lgn)。

2、在已经排好序的基础上,对其运用二分查找

二分查找算法的时间复杂度为θ(lgn)在题目要求的范围内,二分查找的条件为待查的数组为有序序列。

算法的主要思想为设定两个数low指向最低元素high指向最高元素,然后比较数组中间的元素与待查元素进行比较。

如果待查元素小于中间元素,那么表明查找元素在数组的前半段,反之,如果待查元素大于中间元素,那么表明查找元素在数组的后半段。

二、伪代码:

MERGE(A,p,q,r)

1.n1=q-p+1

2.n2=r-q

3.LetL[1..n1+1]andR[1..n2+1]benewarrays

4.Fori=1ton1

5.L[i]=A[p+i-1]

6.Forj=1ton2

7.R[j]=A[q+j]

8.L[n1+1]=无穷

9.R[n2+1]=无穷

10.I=1

11.J=1

12.Fork=ptor

13.IfL[i]<=R[j]

14.A[k]=L[i]

15.I=i+1

16.ElseA[k]=R[j]

17.J=j+1

MERGE-SORT(A,p,r)

1、ifp

2、q=(p+r)/2(取下限)

3、MERGE-SORT(A,p,q)

4、MERGE-SORT(A,q+1,r)

5、MERGE(A,p,q,r)

3、实验总结

在主函数中调用二分查找的时候,参数应该为BinSearch(a,j+1,n,x-a[j])从j+1开始遍历而不是都是从第一个开始。

在程序中由于程序语言规定数组的下标从0开始而算法伪代码要求从1开始,因此在定义数组大小的时候将数字加1,但是在编译运行的时候会得不到想要的结果,出现数组下标访问错误。

实验编号

1

题目2

优先队列排序

实验内容

实现优先队列排序算法,需要支持以下操作:

INSERT(S,x):

把元素x插入到集合S中

MAXMUM(S):

返回S中具有最大key的元素

EXTRACT-MAX(S):

去掉并返回S中的具有最大key的元素

INCREASE-KEY(S,x,k):

将元素x的关键字值增到k。

实验目的

堆排序,运用堆来实现优先队列。

报告正文

1、算法原理

1、堆排序算法是引用堆这个数据结构进行信息管理。

堆排序的时间复杂度是θ(nlgn),但是与归并排序不同的是堆排序具有空间的原址性,任何时候都只需要常数个额外的元素空间存储临时数据。

堆排序算法分为3个过程MAX-HEAPIEY:

调整堆以满足小顶堆性质其时间复杂度为θ(lgn);BUILD-MAXHEAP:

从无序的输入数据数组中构造小顶堆,其时间复杂度为线性时间;HEAP-SORT:

对数组进行原址排序,其时间复杂度为θ(nlgn)。

2、在堆的基础上实现优先队列INSERT、MAXMUM、EXTRACT-MAX、INCREASE-KEY时间复杂度为θ(lgn)。

2、伪代码

BUILD-MAX-HEAP(A)

1.=

2.Fori=2(取下限)downto1

3.MAX-HEAPIFY(A,i)

HEAPSORT(A)

1.Build-MAX-HEAP(A)

2.Fori=downto2

3.ExchangeA[1]withA[i]

4.=-1

5.MAX-HEAPIFY(A,1)

HEAP-MAIMUM(A)

1.returnA[1]

HEAP-EXTRACT-MAX(A)

1.if<1

2.Error“heapunderflow”

3.Max=A[1]

4.A[1]=A[]

5.=-1

6.MAX-HEAPIFY(A,1)

7.Returnmax

HEAP-INCREASE-KEY(A,i,key)

1.ifkey

2.Error“newkeyissmallerthancurrentkey”

3.A[i]=key

4.Whilei>1andA[PARENT(i)]

5.ExchangeA[i]withA[PARENT(i)]

6.I=PARENT(i)

MAX-HEAP-INSERT(A,key)

1.=+1

2.A[]=负无穷

3.HEAP-INCREASE-KEY(A,,key)

三、实验总结

一开始没有理解将一个序列转换成小顶堆的过程,在编写MAX-EXSTRACT函数的时候,当去掉第一个元素后,程序并没有调用MAX-HEAP进行调整堆,因此最后序列是无序状态。

实验编号

1

题目3

快速排序算法

实验内容

实现快速排序算法。

实验目的

使用Java实现插入排序算法。

报告正文

一、算法原理

快速排序采用分治策略,时间复杂度为θ(nlgn),但是最坏情况下为θ(n2),并且快速排序算法属于原地排序,并不需要开辟空间。

快速排序复杂的步骤为其分解的步骤分解的过程数组A[p..r]被划分为两个子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每个元素都小于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。

而在实现的过程总是选择将A[r]作为基准点进行划分A[p..r]数组。

二、伪代码

QUICKSORT(A,p,r)

1ifp

2q=PARTITION(A,p,q)

3QUICKSORT(A,p,q-1)

4QUICKSORT(A,q+1,r)

PARTITION(A,p,r)

1x=A[r]

2i=p-1

3forj=ptor-1

4ifA[j]x

5i=i+1

6exchangeA[i]withA[j]

7exchangeA[i+1]withA[r]

8returni+1

三、实验总结

问题答案:

当选取第一个或者最后一个为基准点时,当n个元素相同的时候为最坏情况比较次数为n*(n-1)/2;快速排序比较次数最少为θ(nlgn),,最大的比较次数为θ(n2)。

实验编号

1

题目4

用分治算法实现题目要求的时间复杂度运算

实验内容

运用分治的策略将两个已经排好序的序列中,找出第k大的元素且要求时间复杂度为θ(lgm+lgn),其中m和n分别为两个序列的长度。

实验目的

用分治算法实现题目要求。

报告正文

1、算法原理

如果K是中位数,则(M+n)是奇数还是偶数是有关系的。

如果是奇数,那么中位数唯一,如果是偶数就有两个中位数,可以随便取一个。

如果找到的第K大数是x,假如在A的位置是A(x),在B中的位置是B(x),则Ax+Bx-1=k是成立的。

 接下来是具体实现逻辑:

1、首先假设K大数在A数组中,首先检查 (m/(m+n))*(k-1),假设其值为A1。

然后检查B中(k+1-(n/(m+n))*(k-1))假设为B1,检查A1、B1是否相等,或者大于B中的第(k+1-(n/(m+n))*(k-1)),并且小于(k+1-(n/(m+n))*(k-1))+1个元素。

满足条件就可以知道A1就是所求,否则看条件2。

2、如果两个条件都不满足,那么需要判断第K个元素是位于A1左边还是右边。

如果A1>B1,那么K肯定不在A[0,(m/(m+n))*(k-1)]以及B[(k+1-(m/(m+n))*(k-1))+1,n]中;

如果A1

第K个元素有可能在B中,同理可以假设在B中,再进行一次搜索。

复杂度log(m)+log(n)。

2、伪代码

Searchkth(A,B,alow,ahigh,blow,bhigh,k)

1.amid=(alow+ahigh+1)/2

2.bmid=(blow+bhigh+1)/2

3.Ifalow>ahigh

4.returnB[blow+k-1]

5.Ifblow>bhigh

6.returnA[alow+k-1]

7.IfA[amid]<=B[bmid]

8.IfA[amid]<=B[bmid]

9.Ifk<=amid-alow+bmid-blow+1

10.ReturnSearchkth(A,B,alow,ahigh,blow,bmid-1,k)

11.Else

12.ReturnSearchkth(A,B,amid+1,ahigh,blow,bhigh,k-(amid-alow)-1)

13.Else

14.Ifk<=amid-alow+bmid-blow+1

15.ReturnSearchkth(A,B,alow,amid-1,blow,bhigh,k)

16.Else

17.ReturnSearchkth(A,B,alow,ahigh,bmid+1,bhigh,k-(bmid-blow)-1)

3、实验总结

理解分治策略的三个步骤:

分解、解决和合并对于具体问题的具体表现,要善于根据时间复杂度与所学的算法进行结合,找出可以利用的地方。

实验编号

2

题目1

矩阵链乘

实验内容

用动态规划实现矩阵链乘,保证相乘的次数最少。

实验目的

用动态规划实现矩阵链乘

报告正文

1、算法原理

1最优子结构为:

如果最优的加括号的方式将其分解为Ai..k与Ak+1..j的乘积则分别对Ai..k与Ak+1..j加括号的方式也一定是最优的。

2定义m[i,j]为计算矩阵Ai..j所需标量乘法次数的最小值,对于i=j时,矩阵链乘只包含唯一的矩阵Ai,因此不需要做任何标量乘法运算,所以m[i,i]=0;当i

3矩阵链乘的递归式

4在算法设计的时候需要m数组记录Ai..j最小相乘次数,s数组记录构造最优解所需要的信息,其记录的k值指出了AiAi+1Aj的最优括号化方案的分割点应在AkAk+1之间。

5矩阵链乘的时间复杂度为θ(n3)

2、伪代码

MATRIX-CHAIN-ORDER(p)

=

m[1..n,1..n]ands[1..n-1,2..n]benewtables

i=1ton

4.M[i,i]=0

l=2ton

6.Fori=1ton-l+1

7.J=i+l-1

8.M[i,j]=无穷

9.Fork=itoj-1

10.Q=m[i,k]+m[k+1,j]+p(i-1)*p(k)*p(j)

11.Ifq

12.M[i,j]=q

13.S[i,j]=k

PRINT-OPTIMAL-PARENS(s,i,j)

1.ifi==j

2.Print“A”

3.Elseprint“(”

4.PRINT-OPTIMAL-PARENS(s,i,s[i,j])

5.PRINT-OPTIMAL-PARENS(s,s[i,j]+1,j)

6.Print“)”

3、实验总结

矩阵链乘主要运用动态规划的思想,这种思想的重要之处在于找到最优的子结构,并设计出最优解的形式。

编程是并未遇到什么问题,过程较为顺利。

实验编号

2

题目2

最长公共子序列

实验内容

用动态规划求下列字符串的最长公共子序列。

实验目的

用动态规划实现寻找最长公共子序列算法。

报告正文

1、算法原理

1最优子结构:

令X=和Y=为两个序列Z=为X和Y的任意LCS。

如果xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的一个LCS;如果xm≠yn,则zk≠xm意味着Z是Xm-1和Y的一个LCS;如果xm≠yn,则zk≠yn意味着Z是X和Yn-1的一个LCS。

2定义一个b[i,j]指向表项对应计算c[i,j]时所选择的子问题最优解,过程返回表b和表c,c[m,n]保持X和Y的LCS长度。

3LCS的递归式为

 

4LCS的时间复杂度为θ(m+n),b表的空间复杂度为θ(mn)。

2、伪代码

LCS-LENGTH(X,Y)

1.m=

2.n=

3.Letb[1..m,1..n]andc[0..m,0..n]benewtables

4.Fori=1tom

5.c[i,0]=0

6.Forj=0ton

7.c[0,j]=0

8.Fori=1tom

9.Forj=1ton

10.Ifxi==yj

11.c[i,j]=c[i-1,j-1]+1

12.b[i,j]=1

13.Elseifc[i-1,j]>=c[i,j-1]

14.c[i,j]=c[i-1,j]

15.b[i,j]=2

16.Elsec[i,j]=c[i,j-1]

17.b[i,j]=3

PRINT-LCS(b,X,i,j)

1.ifi==0orj==0

2.Return;

3.Ifb[i,j]==1

4.PRINT-LCS(b,X,i-1,j-1)

5.Printxi

6.Elseifb[i,j]==2

7.PRINT-LCS(b,X,i-1,j)

PRINT-LCS(b,X,i,j-1)

三、实验总结

用动态规划求取最长公共子序列的时候,要理解b数组的用途和使用。

一开始编程时将输入的字符串转化为字符出现问题,后来使用charAt()函数解决了问题。

实验编号

2

题目3

最长公共子串

实验内容

用动态规划求取以下字符串的最长公共子串。

实验目的

用动态规划实现最长公共子串算法

报告正文

一、算法原理

1最优子结构令X=和Y=为两个序列Z=为X和Y的任意最长公共子串。

如果xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的一个最长公共子串;如果xm≠yn,则zk≠xm意味着Z是Xm-1和Y的一个最长公共子串;如果xm≠yn,则zk≠yn意味着Z是X和Yn-1的一个最长公共子串。

2定义L[i,j]为以x[i]和y[j]为结尾的相同子串的最大长度,记录着X和Y的最长公共子串的最大长度。

3最长公共子串的递归式

4最长公共子串的时间复杂度为θ(mn),空间复杂度为θ(mn)。

2、伪代码

getLCString(str1,tr2)

len1=;

len2=;

maxLen=len1>len2len1:

len2;

int[]max=newint[maxLen];

int[]maxIndex=newint[maxLen];

int[]c=newint[maxLen];

Letmax[0..maxlen-1],maxindex[0..maxlen-1]andc[0..maxlen-1]benewtables

Fori=0tolen2

forj=len1-1to0

ifstr2[i]==str1[j]

ifi==0orj==0

c[j]=1;

else

c[j]=c[j-1]+1;

else

c[j]=0;

ifc[j]>max[0])

max[0]=c[j];

maxIndex[0]=j;

fork=1tomaxLen

max[k]=0;

maxIndex[k]=0;

elseifc[j]==max[0]

fork=1tomaxLen

ifmax[k]==0

max[k]=c[j];

maxIndex[k]=j;

forjtomaxLen

ifmax[j]>0

Printj+1

fori=maxIndex[j]-max[j]+1tomaxIndex[j]

Printstr1[i]

三、实验总结

要同上述的最长公共子序列进行对比区分他们的不同之处。

也要理解用动态规划求解时的相同之处和不同之处。

实验编号

2

题目4

最大子段和

实验内容

给定n个整数(可能为负数)组成的序列a[1],a[2]...a[n],求该序列a[i]+a[i+1]...a[j]的子段和的最大值。

实验目的

用动态规划实现数列的最大和

报告正文

1、算法原理

1最优子结构:

定义当所给整数全为负数的时候,最大子段和为0,则最大子段和为max{0,a[i]+a[i+1]...+a[j]},1≤i≤j≤n

2引入一个辅助数组b,动态规划的分解分为两步:

(1)计算辅助数组的值;

(2)计算辅助数组的最大值。

辅助数组b[j]用来记录以j为尾的子段以及集合中的最大子段和。

3最大子段和的递归式

 

4最大子段和使用动态规划进行计算的时间复杂度为θ(n)。

2、伪代码

Maxsum(A)

1.sum=0

2.temp=0

3.B[1..]=arraycopy(A)

4.Fori=0to

5.IfB[i]>0

6.Sum=B[i]

7.Break

j=i+1to

9.IfB[j]>0

10.Fora=itoj

11.temp=temp+b[a]

12.Iftemp>sum

13.sum=temp

max

三、实验总结

对比比较了动态规划和分治法的不同,感受到用动态规划解决的便捷。

实验编号

2

题目5

最短路径问题

实验内容

解决多级图中的最短路径问题

实验目的

用动态规划解决多级图中的最短路径问题

报告正文

一、算法原理

1可以由图可知,图中的顶点讲图划分7个阶段,分别了解每个阶段可以有几种可供选择的点,引入f[k]表示状态k到终点状态的最短距离。

最优子结构为当前状态的f[k]由上个状态的f[k-1]和状态k-1到状态k的距离决定决策:

当前状态应在前一个状态的基础上获得。

决策需要满足规划方程,规划方程f(k)表示状态k到终点状态的最短距离。

2多段图最短路径的递归式

 

2、伪代码

Shortestpath

letindexs[0..W1[0].length],isLabel[0..W1[0].length] beanewtable

i_count=-1

distance=W1[start]     

index=start

presentShortest=0

indexs[++i_count]=index; 

isLabel[index]=true; 

whilei_count

min=; 

  fori=0to

     if!

isLabel[i]anddistance[i]!

=-1andi!

=index 

       ifdistance[i]

          min=distance[i] 

          index=i 

     ifindex==end

      break;     

isLabel[index]=true

indexs[++i_count]=index

ifW1[indexs[i_count-1]][index]==-1orpresentShortest+W1[indexs[i_count-1]][index]>distance[index]

     presentShortest=distance[index]; 

      else

      presentShortest+=W1[indexs[i_count-1]][index]; 

fori=0to

      ifdistance[i]==-1andW1[index][i]!

=-1

distance[i]=presentShortest+W1[index][i]; 

      elseifW1[index][i]!

=-1andpresentShortest+W1[index][i]

      distance[i]=presentShortest+W1[index][i]; 

     returndistance[end]-distance[start]; 

 

三、实验总结

遇到的问题:

无法将多段图的每个阶段点的状态表示并记录下来。

并不了解如何将动态规划与贪心算法的如迪杰斯特拉算法进行对比,真正从最优子结构将最短路径表示出来。

实验编号

3

题目1

分数背包问题和0/1背包问题

实验内容

解决分数背包和0/1背包问题

实验目的

分别用贪心算法和动态规划实现分数背包问题和0/1背包问题

报告正文

1、算法原理

10-1背包问题:

选择n个元素中的若干个来形成最优解,假定为k个。

对于这k个元素a1,a2,...ak来说,它们组成的物品组合必然满足总重量<=背包重量限制,而且它们的价值必然是最大的。

假定ak是我们按照前面顺序放入的最后一个物品,它的重量为wk,它的价值为vk。

前面k个元素构成了最优选择,把ak物品拿走,对应于k-1个物品来说,它们所涵盖的重量范围为0-(W-wk)。

假定W为背包允许承重的量,最终的价值是V,剩下的物品所构成的价值为V-vk。

这剩下的k-1个元素构成了W-wk的最优解。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1