算法设计与分析实验报告.docx
《算法设计与分析实验报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析实验报告.docx(25页珍藏版)》请在冰豆网上搜索。
算法设计与分析实验报告
算法分析与设计实验报告
学院:
信息科学与工程学院
专业:
计算机科学与技术0804班
学号:
0909081711
姓名:
刘勇
指导老师:
郑瑾
2010年1月6日
目录
一、实验要求
二、实验内容
三、思想设计
四、测试结果
五、实验心得
六、附:
源程序
一、实验要求
实验一
用BFS求最短路径
(1)readGraph()从文件中读入图的信息;
(2)printGraph()以邻接表的形式显示图的信息;
(3)shortestPath()输入图的两个顶点,若存在路径,
显示路径长度,并顺序输出路径中的顶点。
实验二
用DFS判断图是否连通,图中是否有环
(1)Connectivity_DFS(MGraphm)判断图是否连通;
(2)Cycle_DFS(MGraphm)判断图中是否有环存在。
实验三
两个经典问题
(1)N-queens问题的求解;
(2)M-coloring问题的求解。
二、实验内容
1、实验一的内容
(1)要求用三个函数完成实实验:
readGraph(),printGraph(),
shortestPath()。
图的信息如:
可存储其信息在文件中,如下:
12
13
14
24
(2)输入顶点s、d,求出两顶点之间的最短路径长度,
并顺序输出s到d之间的路径中的顶点。
若无,则不用输出。
2、实验二的内容
(1)给予一个图,利用DFS遍历图,测试图是否连通;
(2)测试给予的图是否有环存在。
3、实验三的内容
(1)N皇后问题,每一行或每一列只能只能放一个皇后,并且斜线上也不能放;否则皇后之间会互相攻击;
(2)M着色问题,给定一个无向连通图G和m种不同的颜色。
用这些颜色为图G的各顶点着色,每个顶点着一种颜色。
试问是否有使得G中任何一条边的2的顶点着不同颜色的着色法。
三、思想设计
1、实验一的思想
先把图的信息存于文件Graph.txt中,用readGraph()函数实现从文件读入信息,把图的信息转存与邻接矩阵中。
在求最短路径时,用到广度优先搜索遍历。
首先访问所以和初始顶点邻接的顶点,然后是离它两条边的所有未访问的顶点,以此类推,直到所有与初始顶点同一个连通分量中的顶点都访问了为止。
如果仍然存在未访问的顶点,该算法必须从其他的连通分量中的顶点开始。
用BFS来求两个顶点间边的数量最少的路径,从一个顶点开始遍历,一旦访问到另一个顶点就结束。
便可得到从我们所求的最短路径。
2、实验二的思想
利用DFS求解图的连通问题,可以从任意顶点开始访问图的顶点,然后把该顶点标记为已访问。
在每次迭代的时候,该算法紧接着处理与当前顶点邻接的未访问的顶点。
这个过程一直持续,直到遇到一个死端的时候,并试着继续从那里访问未访问的顶点,在后退到起始顶点,并且起始顶点也是一个死端,该算法最终停止了。
四、测试结果
1、实验一测试结果如下图:
2、实验二的测试结果
3、实验三的测试结果
(1)n-queens
(2)m-coloring
五、实验心得
通过实验课的学习,从课本的许多经典算法理论中看到他们的实现解决问题是非常有效的,增加了自己的动手能力,在计算机科学领域,有思想是非常重要的,并且还要有很强的动手能力,把你的设想实现。
每一次对问题的求解总是要思索,思索后便是具体的实现过程,通过多方面的查找,多次实践后,把自己的好的想法证明。
这就是我们技术的一种好的成就。
所以,实验课的学习是非常重要的,在每一个的debug中找寻自己的错误,并纠正自己的错误,然而一步步完善。
似乎这就是一种人生观的体现,学习就如生活中的事一样。
发现问题,解决问题,这个过程会有很多收获。
六、附:
源程序
1、实验一源程序
/************************************************************************/
/*算法设计一
/*实现:
从文件中读取图信息,然后用BFS求两节点之间的路径*/
/*@author:
刘勇
/*完成时间:
2010-01-3
/************************************************************************/
#include"stdafx.h"
#include
#include
#include
#include
usingnamespacestd;
#defineMAX_VERTEX_NUM50//定义最大顶点数
#defineMAXQSIZE100//定义最大队列长度
typedefintvertexType;
intadjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstructSqQueue//定义辅助队列
{
vertexType*base;
intfront;//定义首尾指针
intrear;
}SqQueue;
/************************************************************************/
/*函数声明部分*/
/************************************************************************/
voidcreateGraph(int&max);
voidprintGraph(intmax);
voidshortPath(vertexTypes,vertexTyped,intmaxVertex);
/************************************************************************/
/*建图:
从文件中读入图的信息。
图存于graph.txt文档中*/
/************************************************************************/
voidcreateGraph(int&max)
{
inti=0;
FILE*fp;
charbuff[MAX_VERTEX_NUM];
if((fp=fopen("f:
\\graph.txt","r"))==NULL)
{
printf("connotopenthefile!
\n");
exit(0);
}
do
{
buff[i]=fgetc(fp);//从文件读取存入字符数组buff[]中;
}while(buff[i++]!
=EOF);
fclose(fp);
for(inth=0;h{
for(intl=0;l{
adjMatrix[h][l]=0;
}
}
for(intj=0;j
{
if(isdigit(buff[j])&&isdigit(buff[j+2]))
{
inttemp1=buff[j]-48;
inttemp2=buff[j+2]-48;
intma;
if(max<(ma=temp1>temp2?
temp1:
temp2))
{
max=ma;
}
//cout<adjMatrix[temp1][temp2]=1;
adjMatrix[temp2][temp1]=1;
}
}
cout<<"邻接矩阵:
"<for(intk=1;k<=max;k++)
{
for(intn=1;n<=max;n++)
{
cout<}
cout<}
}
/************************************************************************/
/*输出图:
以邻接表形式输出图信息*/
/************************************************************************/
voidprintGraph(intmax)
{
cout<<"邻接表:
"<for(inti=1;i<=max;i++)
{
cout<<"vertex"<
for(intj=1;j<=max;j++)
{
if(adjMatrix[i][j]==1)
{
cout<}
}
cout<}
}
/************************************************************************/
/*最短路径:
shortestPath顶点s---->d的最短路径并且顺序输出顶点*/
/************************************************************************/
intInitQueue(SqQueue&Q)//初始化队
{
Q.base=(vertexType*)malloc(MAXQSIZE*sizeof(vertexType));
if(!
Q.base)//申请空间
{
printf("申请失败!
");
return0;
}
Q.front=Q.rear=0;//初始化队指针
return1;
}//InitQueue()end
intEnQueue(SqQueue&Q,vertexTypee)//进队
{
if((Q.rear+1)%MAXQSIZE==Q.front)//队头等于队尾时,队满
{
printf("Errer!
TheSqQeueuisfull!
");
return0;
}
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return1;
}//EnQueue()end
intQueueEmpty(SqQueueQ)//队空
{
if(Q.front==Q.rear)
return1;
else
return0;
}//QueueEmpty()end
intDeQueue(SqQueue&Q,vertexType&e)//出队
{
if(Q.front==Q.rear)//队空
{
printf("Errer!
It'sempty!
");
return0;
}
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
returne;
}//DeQueue()end
//intFirstAdjVer(intadjMatrix[][],vertexTypev)
//{
//
//}
voidshortPath(vertexTypes,vertexTyped,intmaxVertex)
{
intv,u,w;
intvisited[MAX_VERTEX_NUM];
intpathLen=0;
intpath[MAX_VERTEX_NUM];
SqQueueQ;
SqQueueP;
for(v=1;v<=maxVertex;v++)
{
visited[v]=0;//初始化访问标记
}
InitQueue(Q);//初始化辅助队列
for(v=s;v<=maxVertex;v++)
{
if(visited[v]==0)
{
visited[v]=1;
printf("%d-->",v);
pathLen++;
EnQueue(Q,v);
//EnQueue(P,v);
//inti=1;
while(!
QueueEmpty(Q))
{
DeQueue(Q,u);
for(inti=1;i<=maxVertex;i++)
{
if(adjMatrix[v][i]==1)
{
w=i;
if(visited[w]==0)
{
visited[w]=1;
/*if()
{
}*/
printf("%d-->",w);
/*if(w==d)
{
return;
}*/
EnQueue(Q,w);
}
}
}
}
pathLen++;
}
}
cout<<"\n2-->3路径长度:
"<}
/************************************************************************/
/*主函数*/
/************************************************************************/
intmain()
{
inttempMax;
createGraph(tempMax);
//cout<<"tempMax:
"<printGraph(tempMax);
shortPath(2,3,tempMax);
return0;
}
2、实验二源程序
#include"stdafx.h"
#include
#include
usingnamespacestd;
#defineMAX_VERTEX_NUM20
typedefstruct
{
intweight;
}Adj,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct
{
AdjMatrixarc;
intvexnum;
}MGraph;
/************************************************************************/
/*创建图,以邻接矩阵存储*/
/************************************************************************/
voidCreateMGraph(MGraph&M)
{
cout<<"请输入结点的个数:
";
cin>>M.vexnum;
cout<<"请输入该图的邻接矩阵:
"<for(inti=1;i<=M.vexnum;i++)
{
for(intj=1;j<=M.vexnum;j++)
{
cin>>M.arc[i][j].weight;
}
}
}
voidprint(MGraphm)
{
for(inti=1;i<=m.vexnum;i++)
{
for(intj=1;j<=m.vexnum;j++)
{
cout<}
cout<}
}
/************************************************************************/
/*应用DFS思想判断图是否连通*/
/************************************************************************/
boolConnectivity_DFS(MGraphm)
{
queueq;
boolvisa[MAX_VERTEX_NUM];//之前先初始化为false;
intcount=0;
memset(visa,0,sizeof(visa));
q.push
(1);
while(!
q.empty())
{
intv=q.front();
visa[v]=true;
q.pop();
count++;
for(inti=1;i<=m.vexnum;i++)//把与v连通并且没有被访问过的结点压进队列面
{
if(m.arc[v][i].weight)
if(!
visa[i])
{
q.push(i);
visa[i]=true;//标志被访问过。
}
}
}
if(count==m.vexnum)//如果压进栈的结点个数刚好等于总结点的个数,则连通;
returntrue;
returnfalse;
}
/************************************************************************/
/*判断一个图是否有环*/
/************************************************************************/
boolCycle_DFS(MGraphm)
{
MGraphjudgemat;
judgemat.vexnum=m.vexnum;
inti,j;
for(i=1;i<=m.vexnum;i++)
{
for(j=1;j<=m.vexnum;j++)
{
if(m.arc[i][j].weight)
judgemat.arc[i][j].weight=1;//初始化判断矩阵
else
judgemat.arc[i][j].weight=0;
}
judgemat.arc[i][i].weight=1;
}
for(intx=1;x<=judgemat.vexnum;x++)//采用warshall算法判断图的连通性。
注意下标。
{
for(inty=1;y<=judgemat.vexnum;y++)
{
if(judgemat.arc[x][y].weight)
{
for(intz=1;z<=judgemat.vexnum;z++)
{
if(judgemat.arc[z][x].weight)
judgemat.arc[z][y].weight=1;
}
}
}
//print(judgemat);
}
for(i=1;i<=judgemat.vexnum;i++)
{
for(j=1;j<=judgemat.vexnum;j++)
if(!
judgemat.arc[i][j].weight)//只要还没全为1就不连通;
returnfalse;
}
returntrue;
}
/************************************************************************/
/*主程序部分,入口*/
/************************************************************************/
intmain()
{
MGraphMAP;
CreateMGraph(MAP);
cout<<"UseDFS:
"<if(Connectivity_DFS(MAP))
cout<<"Connectivity!
"<else
cout<<"NotConnectivity!
"<if(!
Cycle_DFS(MAP))
{
cout<<"Cycle"<}
else
{
cout<<"Nocycle"<}
return0;
}
3、实验三源程序
(1)n-queens
#include
#include
boolPlace(intx[],intk)//考察皇后k放置在x[k]列是否发生冲突
{inti;
for(i=1;iif(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
return0;
return1;
}
voidOutput(intn,intx[])
{
cout<<"[";
for(inti=1;icout<cout<return;
}
voidQueue(intn,intx[])
{
inti;
for(i=1;i<=n;i++)//初始化
x[i]=0;
intk=1;
intnum=0;
while(k>=1)
{
x[k]=x[k]+1;//在下一列放置第k个皇后
while(x[k]<=n&&!
Place(x,k))
x[k]=x[k]+1;//搜索下一列
if(x[k]<=n&&k==n){//得到一个解,输出
Output(n,x);
num++;
}
elseif(x[k]<=n&&kk=k+1;//放置下一