跳转至

DAG IR 设计

DAG(有向无环图)IR 是 OptAgent 的核心中间表示,是问题结构的唯一真实来源。

设计理念

为什么需要 DAG IR?

不同的优化问题(线性规划、调度、路由)有不同的数学表达形式,但底层都可以抽象为"变量 + 约束 + 目标"。DAG IR 提供了一个统一的图结构来表达这些元素,使得分析器和求解器可以独立于具体的建模 API 工作。

图结构

graph TD
    subgraph "DAG IR Example: 简单调度问题"
        V1[Var: start_time[0]] -->|precedence| C1[Constraint: start[1] >= start[0] + dur[0]]
        V2[Var: start_time[1]] --> C1
        V1 --> O1[Objective: min max(start_time + duration)]
        V2 --> O1
        C1 --> O1
    end

节点类型

节点类型 描述 示例
VarNode 决策变量 x[i] ∈ [0, 10]
ConstraintNode 约束条件 Σ x[i] ≤ 20
ObjectiveNode 目标函数 min Σ c[i]·x[i]
OpNode 运算节点 +, *, max, if-then-else
ConstNode 常量节点 3.14, true

属性系统

每个节点可以附带属性,用于下游分析:

# VarNode 属性示例
{
    "vtype": "INTEGER",
    "lb": 0,
    "ub": 100,
    "domain": None,  # None 表示连续区间
    "name": "start_time",
    "tags": ["scheduling", "start"]
}

# ConstraintNode 属性示例
{
    "sense": "LE",  # LE | GE | EQ
    "is_linear": True,
    "is_redundant": False,
    "tightness": 0.7,
    "tags": ["precedence"]
}

序列化

DAG IR 支持多种序列化格式:

{
  "nodes": [
    {"id": "v0", "type": "var", "lb": 0, "ub": 10},
    {"id": "c0", "type": "constraint", "sense": "LE"}
  ],
  "edges": [
    {"src": "v0", "dst": "c0", "weight": 1.0}
  ]
}
from optagent.ir import DAG

dag = DAG()
v0 = dag.add_var(lb=0, ub=10, name="x")
c0 = dag.add_constraint(v0 <= 5)
dag.set_objective(v0, sense="min")

# 序列化
json_str = dag.to_json()
dag2 = DAG.from_json(json_str)

与求解器的映射

DAG IR 节点被映射到具体求解器的原语:

DAG 节点 CP-SAT MILP Heuristic
VarNode(INTEGER) IntVar IntegerVar int
VarNode(BINARY) BoolVar BinaryVar bool
ConstraintNode(LE) Add(x) <= y x <= y 惩罚项
ObjectiveNode Model.Minimize model objective 适应度函数