计算图的关键路径

时间:2011-05-15 08:15:22

标签: graph path graph-theory

对于图论的作业,我要求按以下格式计算项目的{Critical (s) Routes (s)和时间松弛:

项: 第一行输入将是一个整数C,它表示测试用例的数量(模拟项目活动的图形)。每个测试用例的第一行分别包含两个整数N和M,其中N表示项目中的节点数和活动量M.然后是m行,每行有3个整数I,J和D,其中I和J表示活动的开始和结束节点。

该条目应该从文件“entrada.in”中读取,该文件将在 程序文件夹。如果您的计划提供阅读机会,则被视为奖金 来自任何路径的文件通过图形界面(即没有 写完整的路径。)

输出:

在每个测试用例的第一行中必须显示以下字符串“Case G:Duration Total P”,其中G表示测试用例的数量(从1开始),P表示项目总持续时间。然后X行应该为项目的(s)Critical(s)Route(s)表示活动,遵循与输入相同的格式(除了表示持续时间的整数),但另外,边缘是有序的(因为第一优先级应该是从较低节点到较高节点的主节点和从最低节点到最高节点的节点)。然后必须按照上面列出的相同顺序,按照与非关键活动相对应的“Y”行。对于每个非关键活动,应显示4个整数,I,J,T和F,其中T和F分别代表每个活动的总松弛和自由松弛。此外,如果活动标有红色标记,则必须在行尾添加R.应该避免虚拟活动不是输出的关键路径的一部分。

每个测试用例后应打印一个空行。 输出应写在文件“salida.out。”

实施例: example of entry and output

我需要告诉我一些如何做我需要的想法,我不是要求一个解决方案只是一点帮助(例如伪代码),感谢所有

1 个答案:

答案 0 :(得分:3)

首先,我假设我们有一个有向无环图(DAG)。

1 - 我们需要为每个顶点找到每个活动的最小可能开始时间。这就像找到图中每个顶点的最长路径一样。对于一般图,这是NP难的,但由于图是DAG,我们可以使用拓扑排序在多项式时间内执行此操作。

2 - 计算每个顶点的indegree(即计算输入它们的边数)。由于图是非循环的,因此至少有一个顶点具有零度。将所有这些顶点放在队列中。此外,将距离数组初始化为0。

伪代码

# Compute the indegree
for each vertex v from the graph:
    for each neighbor u of v:
        indegree[u] += 1

queue Q = empty queue
distance = array filled with zeroes
for each vertex v:
    if indegree[v] = 0:
        insert v on Q

3 - 从队列中选择第一个顶点v。对于v的每个邻居u,将距离[u]更新为距离[u] = max(距离[u],距离[v] +时间(v,u)),其中时间(v,u)是所需的时间执行任务(u,v)。从图表中删除v。这可以通过减少每个邻居的不确定性来完成。将任何现在具有0 indegree的新顶点排入队列。重复此过程,直到处理完所有顶点。

伪代码

while Q is not empty:
    v = get front element from Q
    for each neighbor u of v:
        distance[u] = max(distance[u], distance[v] + time(v, u))
        indegree[u] -= 1
        if indegree[u] = 0:
            insert u on Q

4 - 现在,选择距离最大的顶点x。这是项目总的最短持续时间。

5 - 我们需要重新构建关键路径。如果时间紧,即距离[u] +时间(u,v)=距离[v],则任务(u,v)在关键路径上。因此,从顶点x开始并搜索到起始顶点的路径,具有以下约束:如果您在顶点a中,则只能转到顶点b,其中有一条边(b,a),这样距离[a] =距离[b] +时间(b,a)。

6 - 对于不在路径上的边缘,您需要找到总松弛度和自由松弛度。自由松弛很容易:要不延迟以下任务,您需要计算下一个任务开始和当前任务结束时间之间的时间量。这可以通过以下公式找到:distance [v] - (distance [u] + time(u,v))每个(u,v)。

7 - 要找到总松弛,您需要一条新信息,这是一项任务可以在不延迟整个项目的情况下开始的最新时间。这可以通过恢复图形边缘的方向来完成。然后,从顶点x开始,以项目总持续时间延迟初始化数组。

8 - 再次,使用拓扑顺序,无论何时出列顶点v,对于它的所有邻居u,你都会延迟[u] = min(晚[u],晚[v] - 时间(v,u) )。在恢复方向bacj之后,很容易看出每个边缘(u,v)的晚[v] - (晚[u] +时间(u,v))给出总松弛。

9 - 最后,据我所知,你必须用R标记所有具有完全松弛的边缘>自由松弛。