优化堆栈大小以评估 RPN 表达式
Optimizing stack size for evaluating RPN expression
我正在尝试制作一个程序,该程序基本上会使用 OpenCL(并行使用不同的参数值)在 GPU 上以反向抛光表示法计算表达式。
我有一个表达式的 AST,我需要将它转换为 RPN,但是因为我的二元运算是可交换的,所以有不止一种方法可以做到这一点,我需要找到一个使用最少堆栈的方法space 评估期间。
例如,我可以用 1 2 + 3 + 4 +
(任何时候只需要堆栈上的 2 个项目)或 1 2 3 4 + + +
(需要 4 个项目)对数字 1 到 4 求和。
我可以使用什么算法来做到这一点?
如果你所有的二元运算都是可交换的,你可以使用树平衡算法(一些例子here)。平衡树将具有最小深度。然后对这棵平衡树进行深度优先遍历,产生最小栈大小的RPN。
如果您只能依赖交换性(或者,等效地,如果每个运算符都以两个版本实现,其中一个版本反转其参数),那么您可以通过在每个节点递归遍历 AST 来最小化堆栈成本首先访问成本最高的child。为了计算一个节点的成本,执行一个简单的递归计算:叶子的成本是一个,non-leaf 的成本是其成本最高的 child 的成本,如果=]ren 的成本不同,除此之外,还比 child 的成本多一个。 (另一个表达式是 max(max(left, right), min(left, right)+1)
)。 (如果你有超过两个 children 的节点,你需要一个类似但更复杂的公式。)
如果你也可以依靠关联性,允许你用 ab+c+d+
(成本 2)替换 ab+cd++
(成本 3),那么你应该从最大限度地 unbalancing AST.
我正在尝试制作一个程序,该程序基本上会使用 OpenCL(并行使用不同的参数值)在 GPU 上以反向抛光表示法计算表达式。
我有一个表达式的 AST,我需要将它转换为 RPN,但是因为我的二元运算是可交换的,所以有不止一种方法可以做到这一点,我需要找到一个使用最少堆栈的方法space 评估期间。
例如,我可以用 1 2 + 3 + 4 +
(任何时候只需要堆栈上的 2 个项目)或 1 2 3 4 + + +
(需要 4 个项目)对数字 1 到 4 求和。
我可以使用什么算法来做到这一点?
如果你所有的二元运算都是可交换的,你可以使用树平衡算法(一些例子here)。平衡树将具有最小深度。然后对这棵平衡树进行深度优先遍历,产生最小栈大小的RPN。
如果您只能依赖交换性(或者,等效地,如果每个运算符都以两个版本实现,其中一个版本反转其参数),那么您可以通过在每个节点递归遍历 AST 来最小化堆栈成本首先访问成本最高的child。为了计算一个节点的成本,执行一个简单的递归计算:叶子的成本是一个,non-leaf 的成本是其成本最高的 child 的成本,如果=]ren 的成本不同,除此之外,还比 child 的成本多一个。 (另一个表达式是 max(max(left, right), min(left, right)+1)
)。 (如果你有超过两个 children 的节点,你需要一个类似但更复杂的公式。)
如果你也可以依靠关联性,允许你用 ab+c+d+
(成本 2)替换 ab+cd++
(成本 3),那么你应该从最大限度地 unbalancing AST.