美文网首页
图-关键路径算法

图-关键路径算法

作者: 如春天 | 来源:发表于2020-08-17 13:49 被阅读0次

    关键路径(CriticalPath)

    我们把路径上各个活动所持续时间之和称为路径长度,从源点到汇点具有最大长度的路径叫关键路径,在关键路径上的活动叫做关键活动.。

    AOV网和AOE网

    在这里插入图片描述

    算法用到的4个关键变量:

    1. etv (Earliest time of vertex):事件的最早发生时间,即顶点k的最早发生时间
    2. ltv(Latest time of vertex):事件最晚发生时间,即顶点k的最晚发生时间
    3. ete(Earliest time of edge):活动最早开工时间,即弧k的最早发生时间
    4. lte(Latest time of edge):活动最晚开工时间,即弧k的最晚发生时间

    我们可以根据1,2求得3,4,再根据ete[k] 是否与lte[k]相等来判断k是否为关键活动

    etv[k] 与 ltv[k]的计算公式:

    在这里插入图片描述 在这里插入图片描述

    关键路径算法借助到了改进过的拓扑排序算法,多了一个stack2栈,用来存放倒过来的拓扑序列(由于栈是后进先出的),同时计算生成了etv数组,计算公式如上图。

    #include <stdio.h>
    #include <stdlib.h>
    #define OK 1
    #define ERROR 0
    #define STATUS int 
    typedef struct EdgeNode 
    {
        int adjvex;/*邻接点域*/
        int weight;/*权值*/
        struct EdgeNode *next;
    }EdgeNode;
    
    typedef struct VertexNode
    {
        int in; /*入度*/
        int data;
        EdgeNode *firstEdge;
    }VertexNode, AdjList[MAXVEX];
    
    typedef struct 
    {
        AdjList adjList;
        int numVertexes, numEdges;
    }*GraphAdjList, graphAdjList;
    
    /*改进的辅助拓扑排序算法*/
    /*需要定义几个全局变量*/
    int *etc, *ltv;
    int *stack2;/*stack2存放拓扑序列的栈*/
    int top2; /* top2必须是全局变量,以为在辅助算法和主算法都用到了 */
    Status TopologicalSort(GraphAdjList G)
    {
        EdgeNode *e;
        int i, k, gettop;
        int top = 0;
        int count = 0;
        int top2 = 0;/*初始化stack2数组的栈顶指针*/
        int *stack;
    
        stack = (int *)malloc(G->numVertexes * sizeof(int));
        etv = (int *)malloc(G->numVertexes * sizeof(int));/*初始化*/
        stack2 = (int *)malloc(G->numVertexes * sizeof(int));/*初始化*/
    
        for(i = 0; i < G->numVertexes; i++)
        {
            etv[i] = 0;/*每个事件的最早发生时间,都先初始化为0*/
    
            if(0 == G->adjList[i].in)
            {
                stack[++top] = i;/*如果入度为0,入栈*/
            }
        }
    
        while(top != 0)
        {
            gettop = stack[top--];
            count++;
            stack2[++top2] = gettop;/*stack2栈用于保存拓扑序列,后进先出,所以是倒过来的*/
    
            for(e = G->adjList[gettop].firstEdge; e; e = e->next)
            {
                k = e->adjvex;
                if(!(--G->adjList[k].in))
                {
                    stack[++top] = k;
                }
    
                if((etv[gettop] + e->weight) > etv[k])
                {   
                    /*gettop就是刚刚弹出的顶点,k就是与gettop相邻的顶点 找一个大的值保存*/
                    /*v[gettop] ----[weight]----> v[k]*/
                    /*确定顶点k事件的最早发生时间并且保存以供后续的关键路径算法使用。*/
                    etv[k] = etv[gettop] + e->weight;
                }
            }
        }
    
        if(count < G->numVertexes)
        {
            return ERROR;
        }else
        {
            return OK;
        }
    }
    
    void CriticalPath(GraphAdjList G)
    {
        EdgeNode *e;
        int i, gettop, k, j;
        int ete, lte;
        TopologicalSort(G);
        ltv = (int *)malloc(G->numVertexes * sizeof(int))
        for(i = 0; i < G->numVertexes; i++)
        {
            ltv[i] = etv[G->numVertexes-1];/*所有事件的最晚发生时间都初始化为 拓扑序列最后一个顶点事件的最早发生时间*/
        }
        /*从后往前开始计算ltv,ltv的计算公式在图中给出*/
        while(top2 != 0)
        {
            gettop = stack2[top2--];
            for(e = G->adjList[gettop].firstedge; e; e = e->next)
            {
                k = e->adjvex;
                if(ltv[k] - e->weight < ltv[gettop])
                {
                    /* v[gettop] -----[weight]------> v[k] */
                    itv[gettop] = ltv[k] - e->weight;
                }
            }
        }
        for(j = 0; j < G->numVertexes; j++)
        {
            for(e = G->adjList[j].firstedge; e; e = e->next)
            {
                k = e->adjvex;
                ete = etv[j]; /*活动最早开始时间就等于事件最早发生时间*/
                lte = ltv[k] - e->weight; /*活动最晚开始时间等于 后继事件最晚发生时间 减去 活动的持续时间(权值)*/
                if(ete == lte)
                {
                    /*输出打印*/
                    printf("<v%d, v%d> length: %d, ", G->adjList[j].data, G->adjList[k].data, e->weight);
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:图-关键路径算法

          本文链接:https://www.haomeiwen.com/subject/eicqjktx.html