有向无环图实现

有向无环图

有向无环图(Directed Acyclic Graph,简称DAG)是由顶点和有向边组成的图结构,其中顶点之间的边是有方向性的,并且图中不存在从某个顶点出发经过若干条边再回到该顶点的闭合路径。在有向无环图中,每条边都有一个方向,指向另一个顶点,这种有向性使得图中的信息流动具有明确的方向性。同时,无环性质保证了图中不存在循环,也就是说,无法从一个顶点出发经过若干条有向边回到原始顶点,这种特性使得有向无环图在许多领域中有重要的应用。

dag

有向无环图在计算机科学和工程中有着广泛的应用,例如:

  1. 任务调度:在工作流程、编译器优化、作业调度等领域中,DAG被用于表示任务之间的依赖关系,确保任务按照正确的顺序执行。
  2. 数据流分析:编译器和静态代码分析工具利用DAG来表示变量之间的赋值和依赖关系,用于优化程序和分析数据流。
  3. 无环依赖关系建模:在数据处理、数据库设计、图形学等领域中,DAG被用来表示对象之间的依赖关系,并确保不存在循环依赖。

实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_map>

class Graph 
{
private:
    std::unordered_map<int, std::vector<int>> adjList;

public:
    void addEdge(int u, int v) 
    {
        adjList[u].push_back(v);
    }

    void topologicalSortUtil(int v, std::unordered_map<int, bool>& visited, std::stack<int>& stack) 
    {
        visited[v] = true;

        for (int i : adjList[v]) 
        {
            if (!visited[i])
            {
                topologicalSortUtil(i, visited, stack);
            }
        }

        stack.push(v);
    }

    void topologicalSort() 
    {
        std::unordered_map<int, bool> visited;
        std::stack<int> stack;

        // Initialize all vertices as not visited
        for (auto& pair : adjList)
        {
            visited[pair.first] = false;
        }

        for (auto& pair : adjList) 
        {
            int vertex = pair.first;
            if (!visited[vertex]) 
            {
                topologicalSortUtil(vertex, visited, stack);
            }
        }

        // Print contents of the stack
        std::cout << "Topological sorting order: ";
        while (!stack.empty()) 
        {
            std::cout << stack.top() << " ";
            stack.pop();
        }
        std::cout << std::endl;
    }
};

int main() 
{
    Graph dag;

    dag.addEdge(5, 2);
    dag.addEdge(5, 0);
    dag.addEdge(4, 0);
    dag.addEdge(4, 1);
    dag.addEdge(2, 3);
    dag.addEdge(3, 1);

    dag.topologicalSort();

    return 0;
}

首先,基于map储存图的节点间的关系,然后基于拓扑排序的方法计算图的顺序关系。拓扑排序通过深度优先搜索(DFS)实现,首先访问没有前驱(即入度为0)的顶点,并将其压入栈中。然后递归地访问与当前顶点相邻的顶点,并重复此过程,最终得到的栈即为拓扑排序的结果。这个排序结果为图节点的顺序,如果每个节点是一个任务,那么基于此顺序就可以实现对任务的调度和执行。比如常见的低代码平台就是如此

visionmaster


微信公众号