关键词解释:DAG 系统(Directed Acyclic Graph,有向无环图)

看到这个名字我是很懵的什么是DAG?系统?查了一下才知道是有向无环图
从零开始学习 DAG 系统(Directed Acyclic Graph,有向无环图)
。我会按照「由浅入深、理论+实践」的思路,分阶段带你掌握核心概念、应用场景和动手能力。


🧭 学习路线总览

阶段 目标 内容
第1步 理解基础概念 什么是图?什么是 DAG?数学定义与可视化
第2步 掌握关键性质 拓扑排序、路径、入度/出度、无环性判断
第3步 应用场景入门 工作流调度、数据处理、区块链等典型用例
第4步 动手实践 用 Python 构建简单 DAG,实现拓扑排序
第5步 深入系统案例 学习 Airflow / Spark / IOTA 中的 DAG 实现
第6步 扩展与思考 DAG 的局限性、与其他模型对比、前沿研究

✅ 第1步:理解 DAG 是什么?

1.1 图(Graph)基础

  • 图 = 节点(顶点) + 边
  • 有向图:边有方向(A → B ≠ B → A)
  • 无环:不能从一个节点出发,沿着箭头走回自己

1.2 DAG 定义

DAG(Directed Acyclic Graph) 是一个有向图 ,且不存在任何环路

✅ 例子:

复制代码
A → B → C  
 ↘     ↗  
   D

这是一个 DAG:所有路径都是"向前"的,没有循环。

❌ 反例:

复制代码
A → B → C  
    ↑    ↓  
    ← D ←

存在环(B→C→D→B),所以不是 DAG


✅ 第2步:DAG 的关键性质

2.1 拓扑排序(Topological Sort)

  • 将 DAG 的节点排成线性序列,使得所有依赖关系都满足"前驱在前"
  • 用途:任务调度、编译顺序、课程安排等。

📌 举例:

任务:洗衣服(W)、晾衣服(D)、买洗衣液(B)

依赖:W 依赖 B;D 依赖 W

DAG:B → W → D

拓扑排序结果:[B, W, D]

2.2 入度(In-degree)与出度(Out-degree)

  • 入度:指向该节点的边数
  • 出度:从该节点指出的边数
  • 入度为 0 的节点通常是"起点"

2.3 如何判断一个图是不是 DAG?

  • 方法1:尝试做拓扑排序,若成功 → 是 DAG
  • 方法2:DFS 检测是否有回边(back edge)

✅ 第3步:DAG 的典型应用场景

领域 应用 DAG 的作用
任务调度 Airflow, Prefect 定义任务依赖,自动并行执行
大数据处理 Apache Spark 优化计算流程,避免重复计算
区块链 IOTA, Nano 替代链式结构,支持高并发交易
软件工程 Makefile, npm install 管理构建或依赖安装顺序
AI/ML TensorFlow 1.x(静态图) 定义计算图,优化执行

💡 核心思想:"谁先做,谁后做" + "能并行就并行"


✅ 第4步:动手实践 ------ 用 Python 实现一个简单 DAG

目标:构建 DAG 并输出拓扑排序

复制代码
from collections import defaultdict, deque

class DAG:
    def __init__(self):
        self.graph = defaultdict(list)
        self.in_degree = defaultdict(int)

    def add_edge(self, u, v):
        """添加边 u -> v"""
        self.graph[u].append(v)
        self.in_degree[v] += 1
        if u not in self.in_degree:
            self.in_degree[u] = 0

    def topological_sort(self):
        # 初始化队列:所有入度为0的节点
        queue = deque([node for node in self.in_degree if self.in_degree[node] == 0])
        result = []

        while queue:
            node = queue.popleft()
            result.append(node)
            for neighbor in self.graph[node]:
                self.in_degree[neighbor] -= 1
                if self.in_degree[neighbor] == 0:
                    queue.append(neighbor)

        # 检查是否有环
        if len(result) != len(self.in_degree):
            raise ValueError("图中存在环,不是 DAG!")
        return result

# 示例使用
dag = DAG()
dag.add_edge("买洗衣液", "洗衣服")
dag.add_edge("洗衣服", "晾衣服")
dag.add_edge("买衣架", "晾衣服")

print("拓扑排序结果:", dag.topological_sort())

输出:

复制代码
拓扑排序结果: ['买洗衣液', '买衣架', '洗衣服', '晾衣服']

✅ 你已经实现了一个最简 DAG 调度器!


✅ 第5步:深入真实系统(选学)

5.1 Apache Airflow(工作流调度)

  • 用 Python 代码定义 DAG:

    复制代码
    from airflow import DAG
    from airflow.operators.bash import BashOperator
    from datetime import datetime
    
    with DAG('my_dag', start_date=datetime(2025, 1, 1)) as dag:
        task1 = BashOperator(task_id='task1', bash_command='echo "Hello"')
        task2 = BashOperator(task_id='task2', bash_command='sleep 5')
        task1 >> task2  # task1 必须在 task2 之前完成
  • Airflow 自动根据 DAG 并行调度、重试、监控。

5.2 IOTA(DAG 区块链)

  • 每笔交易是一个节点
  • 发起新交易时,必须验证之前的两笔交易(形成 DAG)
  • 无需矿工,交易费为 0,适合物联网微支付

✅ 第6步:思考与扩展

❓ DAG 有什么缺点?

  • 复杂性高:图结构比线性链难理解和调试
  • 一致性挑战(在分布式 DAG 中):如何保证所有节点对图状态达成一致?
  • 可视化困难:节点多时图会非常混乱

🔁 DAG vs 链表 vs 树

结构 是否有向 是否有环 分支能力
链表 无(线性)
有(但每个子节点只有一个父节点)
DAG 强(允许多父节点)

📚 推荐学习资源

相关推荐
独行soc38 分钟前
2025年渗透测试面试题总结-264(题目+回答)
网络·python·安全·web安全·网络安全·渗透测试·安全狮
汤姆yu1 小时前
基于python的外卖配送及数据分析系统
开发语言·python·外卖分析
Yue丶越1 小时前
【C语言】字符函数和字符串函数
c语言·开发语言·算法
如何原谅奋力过但无声2 小时前
TensorFlow 1.x常用函数总结(持续更新)
人工智能·python·tensorflow
翔云 OCR API2 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
小白程序员成长日记2 小时前
2025.11.24 力扣每日一题
算法·leetcode·职场和发展
有一个好名字2 小时前
LeetCode跳跃游戏:思路与题解全解析
算法·leetcode·游戏
AndrewHZ3 小时前
【图像处理基石】如何在图像中提取出基本形状,比如圆形,椭圆,方形等等?
图像处理·python·算法·计算机视觉·cv·形状提取
蓝牙先生3 小时前
简易TCP C/S通信
c语言·tcp/ip·算法
温轻舟4 小时前
Python自动办公工具05-Word表中相同内容的单元格自动合并
开发语言·python·word·自动化办公·温轻舟