关键词解释: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 强(允许多父节点)

📚 推荐学习资源

相关推荐
CAU界编程小白2 小时前
数据结构系列之十大排序算法
数据结构·c++·算法·排序算法
顾安r3 小时前
11.7 脚本网站 中国象棋
python·bash
好学且牛逼的马3 小时前
【Hot100 | 6 LeetCode 15. 三数之和】
算法
橘颂TA3 小时前
【剑斩OFFER】算法的暴力美学——二分查找
算法·leetcode·面试·职场和发展·c/c++
WenGyyyL3 小时前
微信小程序开发——第二章:微信小程序开发环境搭建
开发语言·python·微信小程序
循环过三天3 小时前
3.2、Python-元组
开发语言·python
Q_Q5110082853 小时前
python+django/flask的篮球馆/足球场地/运动场地预约系统
spring boot·python·django·flask·node.js·php
lkbhua莱克瓦243 小时前
Java基础——常用算法4
java·数据结构·笔记·算法·github·排序算法·快速排序
云雾J视界3 小时前
AI驱动半导体良率提升:基于机器学习的晶圆缺陷分类系统搭建
人工智能·python·机器学习·智能制造·数据驱动·晶圆缺陷分类