算法实验报告.docx

上传人:b****6 文档编号:8841367 上传时间:2023-02-02 格式:DOCX 页数:12 大小:154.56KB
下载 相关 举报
算法实验报告.docx_第1页
第1页 / 共12页
算法实验报告.docx_第2页
第2页 / 共12页
算法实验报告.docx_第3页
第3页 / 共12页
算法实验报告.docx_第4页
第4页 / 共12页
算法实验报告.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

算法实验报告.docx

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

算法实验报告.docx

算法实验报告

 

本科实验报告

 

课程名称:

算法设计与分析

实验项目:

分治法合并排序、贪心法作业调度

动态规划多段图、回溯法求n皇后问题

实验地点:

行勉楼209

专业班级:

软件工程1416班学号:

2014005978

学生姓名:

石慧宇

指导教师:

王幸民

2016年4月9日

 

实验一分治法合并排序

一、实验目的

1.掌握合并排序的基本思想

2.掌握合并排序的实现方法

3.学会分析算法的时间复杂度

4.学会用分治法解决实际问题

二、实验内容

随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组。

三、实验环境

程序设计语言:

c++

编程工具:

microsoftvisualstudio2010

四、算法描述和程序代码

#include

#definerandom(x)(rand()%x)

usingnamespacestd;

classSortableList{

private:

intLength;

inta[100];

public:

SortableList(inta[],intl){

Length=l;

inti;

for(i=0;i

*(this->a+i)=*(a+i);

}

SortableList(intl){

Length=l;

}

voidMerge(intleft,intmid,intright){

inttemp[50+1];

inti=left,j=mid+1,k=0;

while((i<=mid)&&(j<=right))

if(a[i]<=a[j])

temp[k++]=a[i++];

else

temp[k++]=a[j++];

while(i<=mid)

temp[k++]=a[i++];

while(j<=right)

temp[k++]=a[j++];

for(i=0,k=left;k<=right;)

a[k++]=temp[i++];

}

voidMergeSort(){

MergeSort(0,Length-1);

}

voidMergeSort(intleft,intright){

if(left

intmid=(left+right)/2;

MergeSort(left,mid);

MergeSort(mid+1,right);

Merge(left,mid,right);

}

}

voidshowList(){

for(inti=0;i

cout<

}

};

intmain(){

intlength=50;

inta[50];

inti=0;

for(i;i

a[i]=random(50);

cout<<"未排序前的数组为:

"<

for(i=0;i

cout<

SortableListList(a,length);

List.MergeSort();

cout<

"<

List.showList();

return0;

}

5、实验结果截图

六、实验总结

归并排序算法是用分治法实现对规模为n的记录的序列进行排序。

很久没有用C++的我有点儿生疏,刚开始写起来有点慢,但是还是很好得完成了任务。

通过本次实验我既加深了对于C++的熟悉程度,也了解到了很多关于归并排序的知识,这些知识对于我以后的程序开发会有比较大的作用,所以我觉得这次实验对我的作用是比较大的。

 

实验二贪心法作业调度问题

一、实验目的

1掌握贪心算法的基本思想

2掌握贪心算法的典型问题求解

3进一步多级调度的基本思想和算法设计方法

4学会用贪心法分析和解决实际问题

2、实验内容

设计贪心算法实现作业调度,要求按作业调度顺序输出作业序列。

如已知n=8,效益p=(35, 30, 25, 20, 15, 10, 5, 1),时间期限 d=(4, 2, 4, 5, 6, 4, 5, 7),求该条件下的最大效益。

三、实验环境

程序设计语言:

c++

编程工具:

microsoftvisualstudio2010

4、方法描述和程序代码

#include

usingnamespacestd;

constintWork[8]={35,30,25,20,15,10,5,1};//所有作业按收益从大到小排序

constintmaxTime[8]={4,2,4,5,6,4,5,7};

classHomeWork{

private:

intres[8];

boolflag[8];

intmaxReap;

public:

voiddealWith(){

//遍历所有作业:

for(inti=0;i<8;i++){

intTime=maxTime[i]-1;

if(!

flag[Time]){

//如果最大期限那一天还未安排作业,则将当前作业安排在所允许的最大期限那天

res[Time]=Work[i];

flag[Time]=true;

}

else{

//如果当前作业所允许的最大期限那一天已经安排的其他作业,就向前搜索空位,将该作业安排进去

for(intj=Time-1;j>=0;j--)

if(!

flag[j]){

res[j]=Work[i];

flag[j]=true;

break;

}

}

}

cout<<"作业完成顺序为:

"<

for(i=0;i<7;i++){

cout<

}

cout<

"<

for(i=0;i<7;i++)

maxReap+=res[i];

cout<

}

HomeWork(){

for(inti=0;i<8;i++){

flag[i]=false;

}

maxReap=0;

}

};

intmain(){

HomeWorka=HomeWork();

a.dealWith();

getchar();

return0;

}

5、实验结果截图

六、实验总结

贪心算法是算法的重要内容之一,可以高效地解决许多问题。

这次实验解决的是多机调度的最优方案为题。

采用贪心算法会比动态规划高效方便,如果都能解决某个问题的话。

现在我学习贪心算法的时间还不长,理解还很浅显,以后要多加练习,这样才能做到熟练运用。

实验三动态规划法求多段图问题

一、实验目的

1掌握动态规划算法的基本思想

2掌握多段图的动态规划算法

3选择邻接表或邻接矩阵方式来存储图

4分析算法求解的复杂度。

2、实验内容

设G=(V,E)是一个带权有向图,其顶点的集合V被划分成k>2个不相交的子集Vi,1

图中所有边的始点和终点都在相邻的两个子集Vi和Vi+1中。

求一条s到t的最短路线。

参考讲义p136图5-24中的多段图,试选择使用向前递推算法或向后递推算法求解多段图问题。

三、实验环境

程序设计语言:

c++

编程工具:

microsoftvisualstudio2010

4、算法描述和程序代码

#include

using namespace std;

#define MAX 100 

#define n 12 //结点数

#define k 5 //阶段数

void main()

{

int i, j, min, r, temp;

int V[n][n];

int cost[n], d[n], path[n];

for (i = 0; i < 12; i++)

{

for (j = 0; j < 12; j++)

{

V[i][j] = MAX;

}

}

V[0][1] = 9; //对边的权值进行初始化

V[0][2] = 7;

V[0][3] = 3;

V[0][4] = 2;

V[1][3] = 3;

V[1][5] = 4;

V[1][6] = 2;

V[2][5] = 2;

V[2][5] = 4;

V[2][6] = 7;

V[3][7] = 11;

V[4][7] = 8;

V[5][8] = 6;

V[5][9] = 5;

V[6][9] = 3;

V[7][9] = 5;

V[7][10] = 6;

V[8][11] = 4;

V[9][11] = 2;

V[10][11] = 5;

cout << "用动态规划法向前递推多段图的最短路径;" << endl;

for (j = 0; j < n; j++)

cost[j] = 0; //设置向前递推的初值      

for (j = n - 2; j >= 0; j--) //按从2到0的次序计算cost和d

{

temp = 0;

min = V[j][temp] + cost[temp];

for (r = 0; r < n; r++)

{

if (V[j][r] !

= MAX)

{

if ((V[j][r] + cost[r]) < min)

{

min = V[j][r] + cost[r];

temp = r;

}

}

}

cost[j] = V[j][temp] + cost[temp]; //按式计算最小值cost[j]

d[j] = temp; //temp是j在最短子路径上的后继结点

}

path[1] = 0;  //p[1]是源点

path[k] = n - 1; //p[k]是汇点

for (j = 2; j < k; j++)

path[j] = d[path[j - 1]]; //path[j]是最短路径上第阶段的结点?

cout << "从到t的一条长度最短的路径为:

";

for (i = 1; i <= 5; i++)

{

cout << path[i];

if (i < 5)

cout << " --> ";

}

cout << endl;

cout << "最短路径长度为:

" << cost[0];

cout << endl;

}

5、实验结果截图

六、实验总结

通过实现动态规划的这个题目,对动态规划算法有了进一步的了解。

先分析问题,判断是否具有最优子结果和重叠字问题的性质。

对于多段图问题,一个阶段的决策与后面所有求解的子问题相关,所以不能在某个阶段直接作出决定。

 

实验四回溯法求n皇后问题

一、实验目的

1掌握回溯算法的基本思想

2通过n皇后问题求解熟悉回溯法

3使用蒙特卡洛方法分析算法的复杂度

二、实验内容

要求在一个8*8的棋盘上放置8个皇后,使得它们彼此不受“攻击”。

两个皇后位于棋盘上的同一行、同一列或同一对角线上,则称它们在互相攻击。

现在要找出使得棋盘上8个皇后互不攻击的布局。

三、实验环境

程序设计语言:

c++

编程工具:

microsoftvisualstudio2010

4、算法描述和程序代码

#include

usingnamespacestd;

#defineN8

intsum=0;

int*x=newint[N+1];

boolplace(intk)

{

inti;

for(i=1;i

{

if(x[i]==x[k]||abs(i-k)==abs(x[i]-x[k]))

returnfalse;

}

returntrue;

}

voidbacktrack(intt)

{

inti=0;

if(t>N)

{

for(i=1;i<=N;i++)

cout<

cout<

sum++;

}

else

{

for(i=1;i<=N;i++)

{

x[t]=i;

if(place(t))

backtrack(t+1);

}

}

}

voidmain()

{

backtrack

(1);

cout<

}

五、实验结果截图

六、实验总结

回溯法有“通用解题法”之称。

用它可以系统地搜索一个问题的所有解或任一解。

回溯

法在问题的解空间树中,按深度优先策略,从根节点出发搜索解空间树。

算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解。

如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯。

否则,进入该子树,继续按深度优先策略搜索。

它适合于解组合数较大的问题。

回溯法是一种满足某约束条件的穷举式搜索技术,是一种逐步试探求出问题的方法。

N皇后问题是在寻找nxn格的棋盘上放置n个皇后的方案,使得任何2个皇后不放在同一行或者同一列或者同一斜线上。

回溯法有“通用解题法”之称。

用它可以系统地搜索一个问题的所有解或任一解。

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

当前位置:首页 > 高等教育 > 农学

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

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