关键路径

来源:互联网 发布:淘宝怎么上传质检报告 编辑:程序博客网 时间:2024/04/27 14:48
#include <iostream>#include <iomanip>#include <stack> using namespace std;#define MAX 100typedef char VertexType; typedef struct ArcNode { int adjvex;    //邻接点域,存储该弧指向顶点的下标 (终点)  struct ArcNode *next;//指向下一条弧的指针  int weight;//权重 }ArcNode;//边结构 typedef struct VertexNode {VertexType data;//数据域 ArcNode *firstArc;//指向第一条依附该顶点的弧的指针 }VertexNode,AdjVerList[MAX];typedef struct {AdjVerList vertices;//顶点集int vexnum,arcnum; //图的顶点数和弧数}ALGraph;//图结构int ve[MAX];//各事件的最早发生时间 void CreateALGraph(ALGraph *G);void Display(ALGraph *G);int CriticalPath(ALGraph *G);/*求关键路径的基本步骤:1.对图中顶点进行拓扑排序,在排序过程中按拓扑系列求出每个事件的最早发生事件ve(i)2.按逆拓扑序列求出每个事件的最晚发生时间vl(i)3.求出每个活动i的最早开始时间 e(i)和最晚发生时间l(i)4.找到e(i)=l(i)的活动,即为关键路径 */int main(){ALGraph G;CreateALGraph(&G);CriticalPath(&G);return 0;}//求顶点位置函数int LocateVex(ALGraph *G,VertexType v){    int i;    for(i=0;i<G->vexnum;i++)    {        if(G->vertices[i].data == v)            return i;    }    return -1;}//有向无环图 void CreateALGraph(ALGraph *G){    VertexType v1,v2;    int w;    ArcNode *Arc;    cout<<"请输入顶点数和边数:";    cin>>G->vexnum>>G->arcnum;    cout<<"请输入各顶点的数据:";         for(int i=0;i<G->vexnum;i++){        cin>>G->vertices[i].data;        G->vertices[i].firstArc = NULL;     //顶点的边表设为空    }    cout<<"请依次输入"<<G->arcnum<<"组边对应的两个顶点以及权值,以空格分割:"<<endl;    for(int k=0;k<G->arcnum;k++) {cin>>v1>>v2>>w;        int i = LocateVex(G,v1);        int j = LocateVex(G,v2);          Arc = new ArcNode;//新建边         Arc->adjvex = j;        Arc->weight = w;        Arc->next = G->vertices[i].firstArc;                G->vertices[i].firstArc = Arc;    }}//求各顶点的入度(遍历整个邻接表)void FindIndegree(ALGraph *G,int indegree[MAX]){int i;ArcNode *p;    //初始化每个顶点的入度为0for(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->next;        }        //cout<<i<<"元素的入度为:"<<indegree[i]<<endl;    } } //拓扑排序 int TopoSort(ALGraph *G,stack<int> &T)//T为返回逆拓扑序列的栈 {stack<int> s;//设置辅助栈(正拓扑序列栈) ArcNode *p;int i,k;int indegree[MAX]; //各顶点的入度数组 FindIndegree(G,indegree);for(i=0;i<G->vexnum;i++){//将入度为0的顶点入栈if(indegree[i]==0)s.push(i); }for(i=0;i<G->vexnum;i++) ve[i] = 0;//初始化最早发生时间 int count = 0;while(!s.empty()){i = s.top();s.pop();//将栈顶从S栈出栈T.push(i);//将i节点进入T栈,形成逆拓扑序列count++;//统计已输出的顶点数 p = G->vertices[i].firstArc;while(p!=NULL){k = p->adjvex;indegree[k]--;//i号顶点已出栈,所以将i号顶点的每个邻接点的入度自减 if(indegree[k]==0)s.push(k);//如果入度减为0,则入栈if(ve[i]+p->weight>ve[k])ve[k] =  ve[i]+p->weight;//按拓扑顺序更新事件的最早发生事件 p = p->next; }}if(count<G->vexnum)return -1;//存在回路 elsereturn 0;}//求关键路径(AOE网,边表示活动的网) int CriticalPath(ALGraph *G) {int i,j,k;int dut,ei,li;int vl[MAX];//每个事件的最晚发生事件ArcNode *p;stack<int> T;if(TopoSort(G,T))//求事件的最早发生时间和逆拓扑序列 return -1; for(i=0;i<G->vexnum;i++) vl[i] = ve[G->vexnum-1];//将各事件的最迟发生事件初始化为汇点的最早发生时间while(!T.empty())//按逆拓扑序列求各事件的最晚发生时间{j = T.top();T.pop();p = G->vertices[j].firstArc;while(p!=NULL)//遍历整个栈 {k = p->adjvex;dut = p->weight;if(vl[k]-dut<vl[j])vl[j] = vl[k]-dut; p = p->next; }} cout<<"关键活动的相关信息如下:"<<endl;cout<<"活动"<<setw(16)<<"最早发生时间"<<setw(16)<<"最晚发生时间"<<setw(10)<<"持续时间"<<endl;  for(j =0;j<G->vexnum;j++)//扫描每一条弧,求出e(i),l(i),找出关键路径 {p = G->vertices[j].firstArc;while(p){k = p->adjvex;dut = p->weight;ei = ve[j];//活动的最早发生时间li = vl[k]-dut;//活动的最晚发生时间 if(ei==li)//输出关键活动的相关信息(ei,li,dut) {cout<<"("<<G->vertices[j].data<<","<<G->vertices[k].data<<")"<<setw(10)<<ei<<setw(14)<<li<<setw(14)<<dut<<endl;} p = p->next;}}return 0;}/*a b c d e f g h i a b 6a c 4a d 5b e 1c e 1d f 2e g 9b h 7f h 4g i 2h i 4*/

0 0
原创粉丝点击