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个皇后不放在同一行或者同一列或者同一斜线上。
回溯法有“通用解题法”之称。
用它可以系统地搜索一个问题的所有解或任一解。