我为每个网格单元输入了“Unique Id”,如图所示,另一个输入“flow direction”,它指示网格的流向。流向的值是指“唯一ID”。例如,如果流向为5,则表示它流向具有唯一ID 5的单元。 流量只会越来越多地传播。
我想在流向上求和唯一ID的值。我正在寻找的输出显示在最右边的矩阵“Cumulative”上。
unqid = [1,5,4,0;0,6,7,12;0,0,10,13;0,0,0,0];
flowd = [5,7,7,0;0,7,13,13;0,0,13,13;0,0,0,0];
unqid(unqid==0)=nan;
flowd(flowd==0)=nan;
z = zeros(size(unqid));
for i=1:size(unqid,1)
for j=1:size(unqid,2)
idx = find(flowd==unqid(i,j));
z(i,j) = unqid(i,j) + nansum(nansum(unqid(idx)));
end
end
答案 0 :(得分:1)
剩下的主要问题是您的流量根本不会传播。 1流向5,但后来不再对7或13做出贡献。
如果您知道传播只会在遍历网格时以越来越多的数量传播,那么传播很简单。在这种情况下,上面的核心需要一个简单的修改 - 在循环中放置z而不是unqid。
z(i,j) = unqid(i,j) + nansum(nansum(z(idx)));
如果传播是一般的(从点(3,3)的流程也可以转到(2,2)),它会变得更复杂。一个好主意是从图像处理世界中获取线索并研究这些技术,你可能会发现一个比下面更简洁的解决方案,特别是如果你使用工具箱。可能的概念上简单的传播方法是:
在第一步中,z = unqid;
在下一步中,找出流量。执行所有唯一流目标的列表:unqDest = unique(flowd(~isnan(flowd))
。你得到[5, 7, 13]
。现在做类似的事情:
while ~isempty(unqDest) && tries < length(initialUnqDest) % Second condition makes it possible to exit if flows loop - values will be pointless anyway, it at least exits instead of being stuck in an infinite loop.
tries = tries + 1;
for i = length(unqDest) : -1 : 1
%if unqDest depends only on known values, update z and unqDest. Else skip.
end
end
确定unqDest
是否依赖于已知值应该是直截了当的 - 只需检查哪些unqids对应于flowd。流向5取决于1,因为flowd=5
仅在(1,1)
和unqid(1,1) = 1;
上。 1不在unqDest
列表中,因此可以更新5。流向7取决于4,5,6。5在unqDest
列表中,无法更新。类似于流向13。
现在流向5将被删除,unqDest
变为1个元素更短,只有7和13.加上z
得到更新:
z(flow destination) = z(flow destination) + sum(z(flow sources));
如上面的伪代码所示,直到unqDest用完元素为止。如果你有一些循环,这将永远不会发生,因为循环部分不会删除unqDest,这是第二个条件的原因 - 在固定次数的尝试之后等于最大可能步骤(在每个步骤中删除一个单身unqDest)你只是放弃。最后,你应该检查unqDest是否为空 - 如果是,你的矩阵应该是正确的,如果不是你在流程中有循环。