节点编辑器评估的高效图遍历
Posted
技术标签:
【中文标题】节点编辑器评估的高效图遍历【英文标题】:Efficient Graph Traversal for Node Editor Evaluation 【发布时间】:2022-01-16 09:59:16 【问题描述】:我有一个由用户创建的有向无环图,其中图的每个节点(顶点)代表对某些数据执行的操作。节点的输出取决于其输入(显然),并且该输入由其父节点提供。然后将输出传递给它的孩子。循环保证不存在,因此可以忽略。
此图的工作原理与Shader Editor in Blender 相同。每个节点对其输入执行一些操作,并且该操作可能非常昂贵。因此,我只想在严格要求时评估这些操作。
当通过用户输入或其他方式更新节点时,我需要重新评估依赖于更新节点输出的每个节点。但是,鉴于我无法证明多次评估同一个节点是合理的,我需要一种方法来确定更新节点的正确顺序。基本的广度优先遍历并不能解决问题。要了解原因,请考虑以下图表:
传统的广度优先遍历将导致D
在B
之前被评估,尽管D
取决于B
。
我尝试过反向进行广度优先遍历(即,从 O1
和 O2
节点开始,然后遍历 up 图),但我似乎在运行进入同样的问题。反向广度优先遍历将在B
之前访问D
,因此I2
在A
之前,导致I2
被排序之后 A
,尽管A
取决于I2
.
我确定我在这里遗漏了一些相对简单的东西,我觉得反向遍历是关键,但我似乎无法绕开它并让所有部分都适合。我想一个潜在的解决方案是按预期使用反向遍历,但不是避免多次访问每个节点,而是每次出现时访问每个节点,确保它具有绝对正确的顺序。但是多次访问每个节点以及随之而来的指数扩展是一个非常没有吸引力的解决方案。
对于这类问题是否有众所周知的高效算法?
【问题讨论】:
这不是topological sorting吗? 【参考方案1】:是的,有一种众所周知的高效算法。我是topological sorting。
创建一个包含所有节点及其对应入度的字典,我们称之为indegree_dic
。 in-degree 是该节点的父/或传入边的数量。有一组入度为零的节点S
。
取自***页面,稍作修改:
L ← Empty list that will contain the nodes sorted topologically
S ← Set of all nodes with no incoming edge that haven't been added to L yet
while S is not empty do
remove a node n from S
add n to L
for each child node m of n do
decrement m's indegree
if indegree_dic[m] equals zero then
delete m from indegree_dic
insert m into S
if indegree_dic has length > 0 then
return error (graph is not a DAG)
else
return L (a topologically sorted order)
这种排序不是唯一的。我提到这一点是因为它对您的算法有一些影响。
现在,每当任何节点发生更改时,您都可以安全地避免重新计算拓扑排序列表中位于更改节点之前的任何节点,但需要重新计算其之后的节点。如果您在计算中遵循排序列表,则可以确保所有父母都在他们的孩子之前被处理。
此算法不是最优的,因为在更改的节点之后可能有节点不是该节点的子节点。就像在以下场景中一样:
A
/ \
B C
一个正确的拓扑排序是[A, B, C]
。现在,假设 B
发生变化。你跳过A
,因为它没有任何改变,但是重新计算C
,因为它在B
之后。但实际上你不需要这样做,因为B
对C
没有任何影响。
如果此影响不大,您可以使用此算法并保持实现更容易且不易出现错误。但如果效率是关键,这里有一些想法可能会有所帮助:
您可以每次都进行拓扑排序,并将哪个节点更改为一个因素。在上述算法中从S
中选择节点时,请在选择更改的节点之前选择所有其他节点。换句话说,只有当S
的长度为1 时,您才从S
中选择更改的节点。这可以保证您处理不低于之前更改节点层次结构的每个节点。当排序比处理节点便宜得多时,这种方法会有所帮助。
我不完全确定是否正确的另一种方法是在拓扑排序列表中查看更改的节点,并仅在到达更改节点的第一个子节点时开始处理。
另一种方法依赖于想法 1,但如果您可以进行一些预处理,则会很有帮助。您可以为每个节点被更改的情况创建拓扑排序。当一个节点发生变化时,你会尝试尽可能晚地把它放在排序中。您将所有这些排序保存在一个节点中的排序字典中,然后根据更改的节点选择该排序。
【讨论】:
拓扑排序!我知道它必须存在,但它很难寻找,哈哈。谢谢!以上是关于节点编辑器评估的高效图遍历的主要内容,如果未能解决你的问题,请参考以下文章