一、实验目的
- 掌握图的逻辑结构和物理结构,能根据实验内容分析问题,选择合适的数据结构描述问题,并定义物理结构,尤其是构造有向网;
- 学会灵活运用图描述工程问题;
- 掌握关键路径和最短路径的求解原理、实现方法;
- 学会灵活运用拓扑排序解决关键路径求解过程中的问题;
- 学会使用Dijkstra算法或Floyd算法求顶点间最短路径;
- 从终端输入AOE网相关信息,具体的输入和输出格式不限;
- 算法要具有较好的健壮性,对错误操作要做适当处理。
二、实验任务
- 对给出的一个具体工程,输入相关数据,构造一个AOE网;
- 求出该项工程的所有关键活动,通过关键活动所对应的从源点到汇点的路径求出关键路径;
- 对给出的一个具体的有向网或无向网,输入相关数据,构造邻接矩阵;
- 求出该网络每对顶点间的最短路径。
三、实验过程与结果
1.
#include"stdafx.h"
#include <iostream>
#include <iomanip>
#include "stdlib.h"
#include<stdio.h>
#include<string.h>
using namespace std;
////////////////////////////Stack
typedef int ElemType;
typedef struct{ElemType *base;int top;int stacksize;}Sqstack;
bool stackIsEmtype(Sqstack S){if(!S.top)return 1;else return 0;}
bool InitSqstack(Sqstack &S,int stacksize){
S.base=(ElemType*)malloc(stacksize*sizeof(ElemType));
if(!S.top)return 0;else{S.stacksize=stacksize;S.top=0;return 1;}}
bool Push(Sqstack &S,ElemType e){
ElemType *newbase;
if(S.top==S.stacksize){
newbase=(ElemType*)realloc(S.base,(S.stacksize+1)*sizeof(ElemType));
if(!newbase)
return 0;
S.base=newbase;
S.stacksize++;
}
S.base[S.top]=e;S.top++;return 1;}
bool Pop(Sqstack &S,ElemType &e){
if(!S.top)return 0;else{S.top--;e=S.base[S.top];return 1;}}
////////////////////////////Queue
typedef int QElemtype;
typedef struct{QElemtype *base;int front,rear;int queueSize;}CirQueue;
bool InitCirQueue(CirQueue &Q,int Qsize){
Q.base=new QElemtype[Qsize];
if(!Q.base)return 0;
Q.queueSize=Qsize;Q.front=Q.rear=0;return 1;}
bool queueIsEmpty(CirQueue Q){if(Q.front==Q.rear)return 1;else return 0;}
bool insertQueue(CirQueue &Q,QElemtype e){
if((Q.rear+1)%Q.queueSize==Q.front)return 0;
Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%Q.queueSize;return 1;}
bool deleteQueue(CirQueue &Q,QElemtype &e){
if(Q.front==Q.rear)return 0;
e=Q.base[Q.front];Q.front=(Q.front+1)%Q.queueSize;return 1;}
////////////////////////////Graph
#define MAX 40
typedef char VertexType[20];
typedef enum{DG,DN,UDG,UDN}GraphKind;
typedef struct ArcNode{int adjvex;int weight;struct ArcNode *nextarc;}ArcNode;
typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode;
typedef struct{VNode vertices[MAX];int vexNum,arcNum;GraphKind kind;}ALGraph;
typedef struct VexTimeType{int ve;int vl;}VexTime;
int locateVex(ALGraph &G,VertexType v){
int i;
for(i=0;i<G.vexNum;i++)if(strcmp(G.vertices[i].data,v)==0)return i;
return -1;
}
void createGraph(ALGraph &G){
VertexType v1,v2;int d;
int i,j,k;
ArcNode *p;
FILE *f;
char fn[100];
G.kind=DN;
cout<<"please input source file name:";cin>>fn;
//可输入测试文件名distG13.txt
f=fopen(fn,"r");
fscanf(f,"%d%d",&G.vexNum,&G.arcNum);
cout<<G.vexNum<<" "<<G.arcNum<<endl;
for(i=0;i<G.vexNum;++i)
{fscanf(f,"%s",G.vertices[i].data);G.vertices[i].firstarc=NULL;}
for (i=0;i<G.vexNum;i++) cout<<G.vertices[i].data<<" ";cout<<endl;
for(k=0;k<G.arcNum;++k){
fscanf(f,"%s%s%d",v1,v2,&d);
cout<<v1<<"-->"<<v2<<":"<<d<<endl;
if((i=locateVex(G,v1))==-1)return ;
if((j=locateVex(G,v2))==-1)return ;
p=new ArcNode;p->weight=d;
p->adjvex=j;
p->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p;}
fclose(f);
}
void findIndegree(ALGraph &G,int indegree[]){
int i;
ArcNode *p;
for(i=0;i<G.vexNum;i++)indegree[i]=0;
for(i=0;i<G.vexNum;i++)
{p=G.vertices[i].firstarc;
while(p){indegree[p->adjvex]++;p=p->nextarc;}}}
bool ve_time(ALGraph &G,VexTime vtime[],Sqstack &S){
int i,k;
int count=0;
int *indegree;
ArcNode *p;
CirQueue Q;
InitCirQueue(Q,G.vexNum);
indegree=new int[G.vexNum];
for(i=0;i<G.vexNum;i++)vtime[i].ve=0;
findIndegree(G,indegree);
for(i=0;i<G.vexNum;i++){if(indegree[i]==0)insertQueue(Q,i);}
while(!queueIsEmpty(Q)){
deleteQueue(Q,i);Push(S,i);count++;
p=G.vertices[i].firstarc;
while(p){
k=p->adjvex;indegree[k]--;
if(indegree[k]==0)insertQueue(Q,k);
if(vtime[i].ve+p->weight>vtime[k].ve)
vtime[k].ve=vtime[i].ve+p->weight;
p=p->nextarc;} }
if(count<G.vexNum)return 0;else return 1;
}
void vl_time(ALGraph &G,VexTime vtime[],Sqstack &S){
int i,k;ArcNode *p;
Pop(S,k);
for(i=0;i<G.vexNum;i++)vtime[i].vl=vtime[k].ve;
while(!stackIsEmtype(S)){
Pop(S,i);p=G.vertices[i].firstarc;
while(p){
k=p->adjvex;
if(vtime[k].vl-p->weight<vtime[i].vl)
vtime[i].vl=vtime[k].vl-p->weight;
p=p->nextarc;} }
}
bool criticalpath(ALGraph &G){
int i,k,al,ae;
VexTime *vtime;
ArcNode *p;
Sqstack S;
InitSqstack(S,G.vexNum);
vtime=new VexTime[G.vexNum];
if(!ve_time(G,vtime,S))return 0;
vl_time(G,vtime,S);
cout<<"所求关键活动如下:"<<endl;
for(i=0;i<G.vexNum;i++){
p=G.vertices[i].firstarc;
while(p)
{k=p->adjvex;ae=vtime[i].ve;al=vtime[k].vl-(p->weight);
if(ae==al)
cout<<"<"<<G.vertices[i].data<<","<<G.vertices[k].data<<">:"<<p->weight<<endl;
//cout<<G.vertices[i].data<<"-->"<<G.vertices[k].data<<endl;
p=p->nextarc;} }
return 1;
}
int main(){ALGraph G;createGraph(G);criticalpath(G);return 0;}
2.
#include"stdafx.h"
#include<iostream>
#include<iomanip>
using namespace std;
#define MAX 100
#define N 100
int a[MAX][MAX],path[MAX][MAX]; //全局矩阵
FILE *f1;
void pf(int c0,int c1) //递归求最短路径存入文件
{ int T;
T=path[c0][c1];
if(T==0) fprintf(f1,"->V%d",c1);//cout<<"->"<<"V"<<c1;
else{pf(c0,T);pf(T,c1);}
}
void p(int c0,int c1) //递归求最短路径
{ int T;
T=path[c0][c1];
if(T==0) cout<<"->"<<"V"<<c1;
else{p(c0,T);p(T,c1);}
}
void floyd(int cost[][MAX],int n)
{ int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){a[i][j]=cost[i][j];path[i][j]=0;}
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(a[i][k]+a[k][j]<a[i][j]){a[i][j]=a[i][k]+a[k][j];path[i][j]=k;}
cout<<"***********************"<<endl;
}
void print(int h[][MAX],int n)
{int i,j;
for(i=1;i<=n;i++)
{cout<<endl;
for(j=1;j<=n;j++) cout<<setw(6)<<h[i][j];
cout<<endl;
}
cout<<endl;
}
int main()
{ int c0,c1,i,j,k,n,cost[MAX][MAX];
char fn[100];
printf("please input n and cost:\n"); //输入结点数和cost矩阵
scanf("%d\n",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&cost[i][j]);
print(cost,n);
floyd(cost,n);
print(a,n);print(path,n);
cout<<"please input file name:";cin>>fn;
f1=fopen(fn,"w");
for(c0=1;c0<=n;c0++)
for(c1=1;c1<=n;c1++)
{fprintf(f1,"V%d",c0);
//cout<<"V"<<c0;
pf(c0,c1);
//cout<<": "<<a[c0][c1]<<endl;
fprintf(f1,": %ld\n",a[c0][c1]);}
fclose(f1);
k=1;
while(k) //查询键盘所输入顶点对间的最短路径及长度
{ printf("please input c0 and c1:\n");scanf("%d%d",&c0,&c1);
if(c0>=1&&c0<=n&c1>=1&&c1<=n)
{cout<<"V"<<c0;p(c0,c1);cout<<": "<<a[c0][c1]<<endl;}
else if(c0==0&&c1==0)k=0;
}
return 0;
}