c++ - 在 C++ 中计算 DAG 的关键路径

标签 c++ path graph-theory dynamic-programming directed-acyclic-graphs

我正在根据 this algorithm 计算图像 DAG 的关键路径另一个帖子。我的老师要求实现aarray,我简化了作业语句,一个通过数组实现的简单图。

enter image description here

这是我的代码,其中有 3 个数组 v、u 和 d,分别代表边的起始节点、边的结束节点和每对顶点之间的距离,如上图所示。在图像图中,项目的持续时间等于 25,对应于距关键路径的距离总和。

根据this link的伪代码,我的代码无法很好地计算距离。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

int main (){


    int numberVertex=6; //number  of vertex
    int numberActivities=9;//number of edges
    int i, j;

    /*vertices are of the form (v, u) */
    //indegree of each vertex (that is, count the number of edges entering them) 
    int indegree [6]={0,0,0,0,0,0};

    int v[9]={0,0,1,1,2,4,3,3,3};//array v represent the starting vertex of de edge 
    int u[9]={1,2,2,3,4,5,4,5,5};//array u represent the coming vertex of de edge 
    int d[9]={5,6,3,8,2,12,0,1,4};//array d represent the time of de activity (v,u)
    int project_duration=0;//project duration


    /*# Compute the indegree for each vertex v from the graph:
    for each neighbor u of v: indegree[u] += 1*/
    for (j=0; j<numberActivities; j++){
        indegree[u[j]]++;
    }

    for (j=0;j<numberVertex; j++)
        printf ("indegree %d= %d\n",j,indegree[j] );

    queue<int> Q; //queue Q = empty queue
    int distance [numberVertex];
    memset(distance, 0, sizeof(int) * numberVertex);//distance = array filled with zeroes

    //for each vertex v:
    //if indegree[v] = 0:
    //insert v on Q
    for (j=0; j<numberVertex; j++)
    {
        if (indegree[j]==0)
            Q.push(v[j]);
    }

    int first;

    //printf ("first in the queue=%d\n", Q.front());

    /*for each neighbor u of v:
    d istance[u] = max(distance[u], distance[v] + time(v, u))
    indegree[u] -= 1
    if indegree[u] = 0:
    insert u on Q
    */
    while (!Q.empty()){ //while Q is not empty:
        first= Q.front ();  //v = get front element from Q
        Q.pop(); //delete de first from queue
        distance[u[first]]=std::max(distance[u[first]],
            distance[v[first]]+ d[first]);
        indegree[u[first]]-=1;

        if (indegree[u[first]]==0){

            Q.push(u[first]);
        }
    }



    for (j=0; j<numberVertex; j++)
    {
        printf ("dist [%d]= %d\n", j, distance[j]);
    }
    /*Now, select the vertex x with the largest distance. 
    This is the minimum total project_duration.*/
    printf ("Total Project Duration %d\n", project_duration);


    return (0);

}

我做错了什么或者它如何解决代码以告诉我项目的持续时间是多少(对应于与关键路径的距离总和)?只能计算到前 3 个顶点的距离。

最佳答案

您的队列包含顶点。您的数组 uvd 由边号索引。 所以你不能写

first = Q.front();
... u[first] ...

因为 first 是一个顶点。

更一般地说,如果您使用有意义的变量名,您的代码将更易于阅读(错误也会更明显)。 first 不是很明确(首先是什么?),uvd 也很隐晦。

写类似的东西

cur_vertex = todo.front()
distance[dest[cur_vertex]] = std::max(distance[dest[cur_vertex]], 
    distance[source[cur_vertex]]+ weight[cur_vertex]);

马上就会提出一个问题:一个顶点的来源,那是什么? (这里我们使用变量名来代替正确的类型检查。ADA 程序员会声明两种不同的整数类型以避免顶点和边数之间的混淆。)

另一个问题:first 的后继循环到哪里去了?它在伪代码中,但不在您的源代码中。

关于c++ - 在 C++ 中计算 DAG 的关键路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6080542/

相关文章:

sql-server - 更改SQL Server Management Studio的默认安装路径

c++ - 已编译的应用程序想要从绝对路径加载 DLL

artificial-intelligence - 如何使用 A-Star 或 Dijkstra 算法解决 15 个难题?

Prolog 图深度优先搜索

c++ - 为什么在 SDL 和 OpenGL 中使用 IMG_Load 加载到纹理的图像看起来偏蓝?

c++ - 为什么通过基指针删除 [] 派生对象数组是未定义的行为?

model-view-controller - 在 MVC 中,分页信息应该放在路径还是查询字符串中?

c++ - 更紧密地打包位域

C++删除二叉树中的最小元素

algorithm - 在两个顶点之间创建成本最低的路径