我有一个节点列表,每个节点都分解为更多节点。例如
因此,我们有Node0 = w01 * w12 * Node2 + w03 * Node3 + w01 * w14 Node4。
我的C ++代码针对给定的一组权重分解执行上述聚合/分解/合并,如下所示。但是,我觉得有很多需要优化的地方。仅举一个例子,我正在遍历ScriptEngine engine = engineManager.getEngineByName("graal.js")
的密钥,并将它们收集在topWeights
中,这似乎效率很低。
是否有任何STL算法可以帮助我加快速度,并避免不必要的复制?
topNodeNames
答案 0 :(得分:2)
主要问题是您要将每个节点递归到每个子节点,这通常是高度冗余的。避免这种情况的一种方法是在节点名称上引入顺序,其中“较高”的节点仅取决于“较低”的节点,然后以相反的顺序进行计算(对于每个节点,您已经完全知道所有子权重)。但是,我认为没有isNumberKey(evt)
{
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57))
return false;
return true;
}
算法会为您找到此顺序,因为您不能廉价地临时确定节点依赖性(“节点X是否依赖于节点Y?如果不是直接取决于节点Y,我们可能搜索整个树...“)。
因此,您可以走动态编程路线,并将完全计算出的节点存储在某个位置。甚至更好-您可以在遍历整个树时将其整平为只有叶子的权重。只要您在整个递归过程中保持展平,实际上在递归形式中这是相当优雅的:
std
由于每个节点最多只能展平一次,因此您无法运行原始算法所拥有的指数运行时间。
答案 1 :(得分:2)
我建议先进行拓扑排序,然后再进行动态编程算法。使用Khan算法的Standard versions类拓扑需要花费时间O(V+E)
。 (如果该链接失效,则可以使用Google查找其他链接。)在这种情况下,V
是节点数,E
是出现在所有表达式中的术语数。
如果排序失败,则您发现了循环依赖项。以这种方式发现它比炸毁代码要好。
有了这种排序后,使用DP从头到尾非常简单。
此外,如果您真正关心性能,则性能限制之一是每个操作都使用字符串比较来完成。扔很多字符串是容易和方便的-这就是为什么脚本语言一直都这样做。但是它也很慢。我发现过去值得创建一个查找结构,该结构在输入性能关键代码之前将字符串转换为索引,然后抛出某种类型的int
而不是字符串。然后最后使用查找将其转换回字符串。