超图二分

通过递归划分张量超图构建收缩树,小规模子问题使用动态规划。

本页目录

用划分构建收缩树

超图二分(hypergraph bisection)把张量作为节点,把共享 index 作为连接相关节点的超边。算法将节点分成两组,递归处理各组,再合并两侧的结果。

普通图的一条边连接两个节点;超图的一条超边可以连接多个节点。例如,同一个 index 同时出现在三个张量中,就用一条超边连接这三个张量。划分决定先在各组内部收缩,再收缩两组的结果。

虚线是一次划分的分界。橙色超边同时连接两侧节点;每条跨侧超边只计一次,不按端点数重复计数。

划分时,在两侧规模约束下尽量减少跨侧超边的加权总和:

cut⁡(L,R)=∑e∩L≠∅e∩R≠∅log⁡2de.\operatorname{cut}(L,R)= \sum_{\substack{e\cap L\ne\varnothing\\e\cap R\ne\varnothing}} \log_2 d_e.

ded_e 是对应 index 的维度。这个划分代价不等于完整路径的 FLOPs 或读写量。划分只用于确定收缩树,不会删除 index,也不是切片。

递归过程

先在合并节点后的较小超图上求划分,再逐层展开并调整划分。对每一侧重复这个过程;节点数不超过 cutoff 时,改用子集动态规划。

pseudocode
构建子树(S):
    if S 只有一个张量:
        return 该张量
    if S 的张量数 <= cutoff:
        return 用子集 DP 求得的局部树
    (L, R) = 对 S 做超图二分
    left = 构建子树(L)
    right = 构建子树(R)
    return 合并 left 和 right 得到的树

不同随机种子和不平衡参数产生不同候选;多次尝试后,按完整路径的目标值选优。互不连通的分量分别处理,最后按大小进行外积合并。

接口

bisect 使用默认目标;bisect_with_objective 可指定比较完整候选的目标。小问题中的 optimal_dp 仍使用默认目标 F+64RF+64R,不是调用者传入的权重。cutoff 的范围为 2–20;函数签名见 Rust API。

二分是启发式方法,不保证全局最优。Light 使用二分候选,Heavy 不使用,见 Light / Heavy 接口。