我在matlab中使用树中的递归调用,函数的基本结构在这里:
function recursion(tree, targetedFeatures)
if (some conditions fulfilled)
return;
end
for i = 1:1:size(targetedFeatures,2)
.....
.....
if (some conditions that using index i is true)
targetedFeatures(1,i) = 1;
end
end
if(tree has child nodes)
recursion(tree.child(j).targetedFeatures)
end
end
树的结构如下:
root
/ | \
/ | \
/ | \
leaf1 leaf2 leaf3
函数递归的输入参数是一个名为targetedFeatures的向量,假设它的初始值是[0 0 0],并且在访问leaf1的过程中,向量变为[1 0 0], BUT < / strong>访问leaf2时,targetedFeature 更改回[0 0 0] 。
我怀疑是因为matlab中的vector不喜欢其他编程语言中对象的引用?
如何避免此问题?感谢。
答案 0 :(得分:2)
Matlab对正常类型的变量使用call-by-value,请参阅here。解决它的方法是让函数返回修改后的副本作为输出参数:
function targetedFeatures = recursion(tree, targetedFeatures)
...
targetedFeatures = recursion(tree.child(j).targetedFeatures);
...
end
相反,可以使用evalin('caller', ...)
和inputname
来模拟按引用调用。
答案 1 :(得分:1)
当recursion
函数需要修改targetedFeatures
时,会创建targetedFeatures
的副本,该副本对于该函数调用是本地的。如果您希望将更新传回给调用范围,则需要从函数中返回更新的targetedFeatures
。
function targetedFeatures = recursion(tree, targetedFeatures)
if (some conditions fulfilled)
return;
end
for i = 1:1:size(targetedFeatures,2)
.....
.....
if (some conditions that using index i is true)
targetedFeatures(1,i) = 1;
end
end
if(tree has child nodes)
targetedFeatures = recursion(tree.child(j).targetedFeatures)
end
end
这并不像使用C中的指针那样有效,但是你不应该看到代码已经在做什么的显着性能,因为你已经在更新时创建了本地副本targetedFeatures
。
感谢chappjc提供了this post的链接,该链接讨论了写时复制机制。
答案 2 :(得分:0)
根据树的长度和最终深度,上面基于回归的解决方案很快变得非常丑陋,因为你总是必须改变根节点,而原则上你只想改变许多叶子中的一个。
相反,您可能希望研究为TreeNode对象实现句柄类。 这将从一些简单的事情开始:
classdef TreeNode < handle
properties
targetedFeatures;
child; % vector keeping handles to TreeNode children
parent; % handle of the parent node, of which this node is a child
end
methods
...
end
end
你显然必须填写添加/删除孩子等的方法。 使用这样的树,您可以递归到最深的叶子并更改其值,而无需始终携带对顶级根节点的引用。 一旦你有了这个,你应该能够使用你的功能而无需修改。
有点类似的类的实现是链表的实现,在MATLAB文档中演示: http://www.mathworks.de/de/help/matlab/matlab_oop/example--implementing-linked-lists.html 这里每个节点都有一个前一个和下一个“子”,而不是父节点和多个子节点,但是一般结构非常相似。
如果您计划在此树上进行大量其他操作,例如添加/删除节点,搜索等,那么在某些时候它肯定是值得的。 如果您碰巧碰到了那棵树,并且一旦解决了这个问题就完成了,那就去找基于回报的解决方案了。