feat(v2): 架构与算法优化——语义缓存 2.37x、拓扑排序 O(V+E)、分类器确定性决胜
算法: - RouterCache:语义条目写入时预计算向量范数、语义查找单遍完成(消除命中后二次 O(N) 查找)、 相似度=1.0 提前终止;微基准(3000 条目×200 查询):3986ms -> 1685ms,2.37x - TaskGraph.topo_order:O(V²logV) 重排序/成员扫描 -> 邻接表+deque 的 O(V+E) Kahn, 输出顺序契约不变(初始就绪层按插入序、循环依赖按插入序兜底、未知依赖忽略) - RuleClassifier:同分决胜按领域名字典序(与规则表排列无关),次高分 O(n) 扫描 工程卫生: - .mimosa/(扫描器工作目录)加入 .gitignore 并移出索引 - test_review 抽样测试改用内联确定性 LCG,消除 2 个低危(不安全随机数) 测试:新增 11 项(topo 契约 6 + 缓存回归 3 + 分类器 2) pytest 230 passed(基线 219 全绿 + 11)
This commit is contained in:
+23
-20
@@ -9,6 +9,7 @@
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import deque
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
@@ -47,31 +48,33 @@ class TaskGraph:
|
||||
return list(self._nodes.values())
|
||||
|
||||
def topo_order(self) -> List[TaskNode]:
|
||||
"""Kahn 拓扑排序:依赖在前。循环依赖时按插入序兜底(不崩溃)。"""
|
||||
indeg: Dict[str, int] = {}
|
||||
for n in self._nodes.values():
|
||||
indeg[n.id] = 0
|
||||
"""Kahn 拓扑排序:依赖在前;初始就绪层按插入序稳定输出。
|
||||
|
||||
O(V+E) 实现(邻接表 + deque);循环依赖时按插入序兜底(不崩溃)。
|
||||
"""
|
||||
insert_pos = {nid: i for i, nid in enumerate(self._nodes)}
|
||||
indeg: Dict[str, int] = {nid: 0 for nid in self._nodes}
|
||||
dependents: Dict[str, List[str]] = {nid: [] for nid in self._nodes}
|
||||
for n in self._nodes.values():
|
||||
for d in n.deps:
|
||||
if d in indeg:
|
||||
if d in indeg: # 未知依赖 id 忽略(与入度统计口径一致)
|
||||
indeg[n.id] += 1
|
||||
ready = [n for n in self._nodes.values() if indeg[n.id] == 0]
|
||||
ready.sort(key=lambda n: list(self._nodes.keys()).index(n.id))
|
||||
order: List[TaskNode] = []
|
||||
dependents[d].append(n.id)
|
||||
ready = deque(sorted((nid for nid, deg in indeg.items() if deg == 0),
|
||||
key=insert_pos.__getitem__))
|
||||
order_ids: List[str] = []
|
||||
while ready:
|
||||
n = ready.pop(0)
|
||||
order.append(n)
|
||||
for m in self._nodes.values():
|
||||
if n.id in m.deps:
|
||||
indeg[m.id] -= 1
|
||||
if indeg[m.id] == 0 and m not in order:
|
||||
ready.append(m)
|
||||
if len(order) < len(self._nodes):
|
||||
nid = ready.popleft()
|
||||
order_ids.append(nid)
|
||||
for m in dependents[nid]:
|
||||
indeg[m] -= 1
|
||||
if indeg[m] == 0:
|
||||
ready.append(m)
|
||||
if len(order_ids) < len(self._nodes):
|
||||
# 循环依赖兜底:剩余节点按插入序追加
|
||||
for n in self._nodes.values():
|
||||
if n not in order:
|
||||
order.append(n)
|
||||
return order
|
||||
placed = set(order_ids)
|
||||
order_ids.extend(nid for nid in self._nodes if nid not in placed)
|
||||
return [self._nodes[nid] for nid in order_ids]
|
||||
|
||||
def all_done(self) -> bool:
|
||||
return all(n.status == "done" for n in self._nodes.values())
|
||||
|
||||
Reference in New Issue
Block a user