1、 实 验 报 告 4一、实验目的:掌握深度优先搜索求解算法的基本思想。二、实验要求:用 C 语言实现城市交通图的代价树深度优先搜索求解三、实验语言环境:C 语言四、设计思路:解法:采用 代价树的深度优先搜索理论: 1. 首先根据交通图,画出代价图代价图 2. 开始搜索 open 表存放刚刚生成的节点。 closed 表存放将要扩展的节点或已经扩展过的节点。背景:如图是 5 城市之间交通路线图,A 城市是出发地,E 城市是目的地,两城市间的交通费用(代价)如图中数字所示,求从 A 到E 的最小费用路线。 解法:采用 代价树的广度优先搜索 理论: 1. 首先根据交通图,画出代价图 代价图 如图 2
2、. 开始搜索 oepn 表存放刚刚生成的节点。 closed 表存放将要扩展的节点或已经扩展过的节点。 open 表结构: 代价|节点|父节点 closed 表结构: 序号|节点|父节点 1) 把 A 放入 open 表 open 表: 0| A | 0 Closed 表: 空 2) 把 A 从 open 表放入 closed 表 open 表: 空 closed 表: 1 | A | 0 3) 扩展 A,得 C1,B1,放入 open 表 C1 的代价:3 B1 的代价:4 Open 表: 3 | C1 | A 4 | B1 | A closed 表: 1 | A | 0 4 | B1 |
3、A closed 表: 1 | A | 0 2 | C1 | A C1 不是目标节点,于是继续扩展 5) 把 C1 扩展得到 D1,放入 open 表 D1 的代价:3+2=5 B1 的代价:4 open 表: 4 | B1 | A 5 | D1 | C1 closed 表: 1 | A | 0 2 | C1 | A 6) 把 B1 从 open 放入 closed 表 open 表: 5 | D1 | C1 closed 表: 1 | A | 0 2 | C1 | A 3 | B1 | A B1 不是目标节点,于是继续扩展 7) 扩展 B1 得 D2,E1,放入 Open 表 D2 的代价:
4、4+4=8 E1 的代价:4+5=9 open 表: 5 | D1 | C1 8 | D2 | B1 9 | E1 | B1 closed 表: 1 | A | 0 2 | C1 | A 3 | B1 | A 8) 把 D1 从 open 表放入 closed 表 open 表: 8 | D2 | B1 9 | E1 | B1 closed 表: 1 | A | 0 2 | C1 | A 3 | B1 | A 4 | D1 | C1 D1 不是目标节点,于是继续扩展 9) 把 D1 扩展得到 E2,B2,放入 open 表 E2 的代价:3+2+3=8 B2 的代价:3+2+4=9 D2 的代
5、价:8 E1 的代价:9 open 表: 8 | E2 | D1 8 | D2 | B1 9 | B2 | D1 9 | E1 | B1 closed 表: 1 | A | 0 2 | C1 | A 3 | B1 | A 4 | D1 | C1 10) 把 E2 从 open 表放入 closed 表 open 表: 8 | D2 | B1 9 | B2 | D1 9 | E1 | B1 closed 表: 1 | A | 0 2 | C1 | A 3 | B1 | A 4 | D1 | C1 5 | E2 | D1 E2 是目标节点,搜索结束。 则搜索路径 A - C1 - D1 -E2 即
6、:A - C - D - E 五、实验代码:#include #include #define INF 32767 /*INF 表示*/typedef int InfoType;typedef char Vertex;#define MAXV 6 /*最大顶点个数*/*以下定义邻接矩阵类型*/typedef struct /*图的定义*/ InfoType edgesMAXVMAXV; /*邻接矩阵*/int n,e; /*顶点数,弧数*/Vertex vexsMAXV; /*存放顶点信息*/ MGraph; /*图的邻接矩阵类型*/*以下定义邻接表类型*/typedef struct ANo
7、de /*弧的结点结构类型*/ int adjvex; /*该弧的终点位置*/struct ANode *nextarc; /*指向下一条弧的指针*/InfoType info; /*该弧的相关信息,这里用于存放权值*/ ArcNode;typedef struct Vnode /*邻接表头结点的类型*/ Vertex data; /*顶点信息*/ArcNode *firstarc; /*指向第一条弧*/ VNode;typedef VNode AdjListMAXV; /*AdjList 是邻接表类型*/typedef struct AdjList adjlist; /*邻接表*/int n
8、,e; /*图中顶点数 n 和边数 e*/ ALGraph; /*图的邻接表类型*/typedef struct char vi,vj;int info;etype;typedef struct CLOSEDListint id; /记住矢量int datan;int cost;int dad; /记住父节点 回溯用closed; /open 表和 close 表都用这个类型void MatToList(MGraph g,ALGraph *ArcNode *p;G=(ALGraph *)malloc(sizeof(ALGraph);for (i=0;iadjlisti.firstarc=NUL
9、L;G-adjlisti.data=g.vexsi;for (i=0;i=0;j-)if (g.edgesij!=INF) p=(ArcNode *)malloc(sizeof(ArcNode);p-adjvex=j;p-info=g.edgesij;p-nextarc=G-adjlisti.firstarc;G-adjlisti.firstarc=p;G-n=n;G-e=g.e;void ListToMat(ALGraph *G,MGraph ArcNode *p;for(i=0;iadjlisti.data;p=G-adjlisti.firstarc;while (p!=NULL) g.e
10、dgesip-adjvex=p-info;p=p-nextarc;g.n=n;g.e=G-e;void DispMat(MGraph g)/*输出邻接矩阵 g*/int i,j;for (i=0;in;i+)p=G-adjlisti.firstarc;printf(“n%3d %c : “,i,G-adjlisti.data );while (p!=NULL)printf(“%d(%d)“,p-adjvex,p-info);p=p-nextarc;printf(“n“);void creatmat(MGraph g.e=e;int k,i,j;for(k=0;kn=n;G-e=e;int k,
11、i,j;for (i=0;iadjlisti.firstarc=NULL;G-adjlisti.data=vexi;for(k=0;kadjlisti.data !=edgek.vi) i+;j=0;while(G-adjlistj.data !=edgek.vj)j+; p=(ArcNode *)malloc(sizeof(ArcNode);p-adjvex=j;p-info=edgek.info;p-nextarc=G-adjlisti.firstarc;G-adjlisti.firstarc=p;p=(ArcNode *)malloc(sizeof(ArcNode);p-adjvex=i
12、;p-info=edgek.info;p-nextarc=G-adjlistj.firstarc;G-adjlistj.firstarc=p;/char dfsv10;char bfsv10;int k;int visited10;/*void DFS(ALGraph *G,int v) /深度优先遍历ArcNode *p;int w;dfsvk=G-adjlistv.data;k+;visitedv=1;p=G-adjlistv.firstarc;while(p!=NULL) w=p-adjvex;if(visitedw=0)DFS(G,w);p=p-nextarc;*/*void BFS(
13、ALGraph *G,int v,int dest) /广度优先搜索 ,v 是出发结点序号,dest 是目标节点序号closed op20; /定义 open 表大小closed cl20; /定义 closed 表大小int front,rear; /定义指针int crear=-1;int cost=0; /定义费用变量ArcNode *p;front=rear=-1;k=0;rear+; oprear.id=0; oprear.datan=0; oprear.cost=0; oprear.dad=-1;while(frontadjlistii.data;ii=clii.dad;to+;f
14、or(int j=to-1;j=0;j-)printf(“%c“,toprtj);printf(“%cn“,G-adjlistclcrear.datan.data);/printf(“Least cost: %dnn“,clcrear.cost);return;p=(ArcNode *)malloc(sizeof(ArcNode);p=G-adjlistclcrear.datan.firstarc; /first tobe 扩展结点while(p!=NULL) /若不是目标节点,则对其扩展,并将扩展结果放入 open 表表尾部 rear+;oprear.id=rear; /open 新节点位置
15、oprear.dad=crear; /记录父节点在 close 表中的位置,方便后来回溯oprear.datan=p-adjvex; /是哪个字符,即位置oprear.cost=clcrear.cost+p-info;/计算费用p=p-nextarc;int i=rear,j;bool exchange=true; /将 open 表在所有待扩展范围内全排序,代价小的在上面。排序方法:冒泡closed temp;while(exchange) exchange=false;for(j=front+1;ji;j+)if( opj.costopj.cost) temp=opj+1;opj+1=op
16、j;opj=temp;exchange=true;i-;/*/以下为主函数;void main()MGraph g;char vex=“abcde“;etype edge=a,b,4, a,c,3, c,d,2,d,b,4,d,e,3,b,e,5;ALGraph *G;creatmat(g,vex,5,edge,6);printf(“n“);printf(“ 有向图 G 的邻接矩阵:n“);DispMat(g);creatlink(G,vex,5,edge,6);printf(“ 图 G 的邻接矩阵转换成邻接表:n“);DispAdj(G);int i;/*for(i=0;iMAXV;i+)visitedi=0;DFS(G,0);*/for(i=0;iMAXV;i+)visitedi=0;BFS(G,0,4);