创新点: 在流式图数据中,当出现边删除的情况时,通过修剪受影响的顶点的值来实现安全有效的顶点更新,以在用户查询时返回正确的结果。
一、引言
-
过去的算法:
- 流式图,图结构在不断地更新,因而系统中有图形批量更新程序;
- 系统对数据的执行是迭代处理的。
- 将图的批量更新程序与迭代处理进行交互,使迭代处理逻辑维护了一个中间结果,这个结果是在图的最新版本上的计算结果的近似。
-
当查询到来时,直接在中间结果上进行计算,而不是在原始图上。受边更新影响的点亦如此。
流式图数据处理过程
当图的更新请求不断到来时,这些更新被分批次地传入迭代系统,且直到所有批次的迭代结束,才会将更新应用到图结构中去。因此,当查询在中间到来时,主循环逻辑会分出一个分支循环来处理查询,而此时的查询输入值,是之前更新到的中间结果,而不是图的初始值。
此种设计背后的理念是:在图中,比起初始的顶点值,更新前的值是对实际结果的更好的近似。因而若是从中间结果直接进行计算,可以更快地实现收敛。
前提:当图发生突变的时候,中间结果确实比初始值更接近实际结果。否则就会出现错误。- 问题:对于呈现单调性计算特性的图算法(如SSSP、BFS、SSWP),删除一条边会改变图结构并打破图的单调性,使中间结果无效。
比如SSSP算法,若在计算过程中,图中某一条边 A->B 突然被删除,那么此时B的入边应少一条,其最短路径应重新计算。但此种算法会从上一步的中间结果计算,若此结果与被删除的边有关,则可能会导致计算结果出错。
-
KickStarter方法:运行时的技术,通过修剪(Trim),在边删除时能为受影响的顶点计算一个安全而有效的近似值。
- 关键思想:先识别被所删除的边直接或间接影响的顶点值,再在这些值被送入后续计算之前调整它们(计算一个合适的值)。
在有单调特性的图算法中,有一个共有的点,即对图中的某一个点,其当下的值,究其根本只依赖于其某一条入边,而与其他入边的权重无关。 因而有着较为简单的依赖关系。
- 解决办法:通过 在迭代中标记全部可能的受影响点 或者 跟踪顶点的依赖关系 来识别需要调整数值的顶点。
二、背景
- SSWP与SSSP
以两个算法为例,说明过去系统在面对边删除时存在的两个问题
(1)问题1:结果错误(以SSWP为例)
图1:以A为源点的最宽路径
(2) 问题2:执行力降低(以SSSP为例)
图2:SSSP的图
(3) 比较:SSWP最终得到了错误结果,SSSP得到了正确结果单执行力非常差耗时很长。其不同点在于,前者在迭代中只进行了值选择,后者在迭代中对顶点值进行了计算。
三、算法核心:修剪近似
1. 可恢复的近似:指用迭代的流算法S对该近似集合进行计算,也可以得到在G上的最终的正确解答。
2. 两种技术:
(1)利用标记机制,标记可能受到影响的所有顶点,并重置顶点值(代价太大);
(2)跟踪顶点之间的动态依赖关系,得到精确的顶点集。
3. 方法1:标记 + 重置
(1) 流程:首先标记被删除的边e的目标顶点,在后续处理中,若某条边的源点被标记,则其目标顶点添加标记。结束标记后,将被标记顶点的值都恢复到初始化的值。
(2) 缺陷:会标记许多不必要的顶点,如图一,会标记所有点,然而 C 点和 F 点并未真正受 A->D 边的影响,算法中将这两点也重置为0,使其结果错误。
4. 方法2:跟踪动态依赖
(1) 值依赖(Value Dependence)
图4:关系的传递闭包
图5:leads-to 关系
第二个条件是关键,因为它限定了u和v不在一个圈内,则对于v的值计算,不会依赖于v原来的值。
-
依赖树(Dependence Tree)
图中的每条边都代表了一个leads-to关系
图6:依赖树
(2)计算新的近似值
- 先要找到受影响点:找到DT中以被删边的目标顶点为根的子树。
- 计算这些点的最优近似值:
- 若被删的边在DT中没有对应边,就忽略;
- 若有,则为该边的目标顶点计算一个安全的替代值。
- 检查是否要对当前的顶点在DT中的直接孩子节点进行修剪。
怎么计算安全的近似替代值? 由于环的存在,会影响顶点值的设定,因此只为不依赖自己的顶点进行重新计算替代值,否则直接设置为0。如图1和图7中的D顶点。
算法:用层次信息(level information)来解决,根节点层次为0,向下依次增高。若找到了合适的新路径,则用新路径的值为需要替代值的顶点求值。
何时停止修剪? 理论上,为顶点找到新的安全值后,KS还要检查新的值是否破换了图算法的单调性,若是破坏了,那就需要继续修剪其直接孩子节点。否则若是没破坏,则修剪可以停止。
例子:图6的后3张图。(3)并行修剪的算法
网友评论