【发布时间】:2018-09-07 09:34:42
【问题描述】:
TL;DR:我有一堆四面体,我想知道哪些是它的 4 个(或更少)相邻(共享面)四面体,我通过检查 3D 中的点来做到这一点他们分享。这很慢。
我正在从三角剖分构建一个连通图。该图的结构为[1]:
Graph.element.nodeId
.neighbours
.nodes.positions
三角剖分的输出有 2 个矩阵,TRI 和 points,第一个是 Ntri x 4 数组,每一行都有每个四面体的节点 ID,而第二个是一个列表点Npoint x 3 大小。
我目前正在按照以下代码构建图形,但对于任何尺寸合适的网格来说,它的速度都非常慢。几乎所有时间的单行是find 行(在代码中标记),即找到当前元素的邻居的部分。
当前算法为每个四面体获取其所有节点,然后找到所有其他也包含这些相同节点的四面体。然后过滤掉所有与当前四面体不包含3个相同节点的四面体,只留下当前四面体的邻居。
function graph=trimesh2graph(TRI,points)
nD=size(points,2);
% preallocate.
graph.elements(size(TRI,1)).neighbours=[];
% For each element, find its node Ids and neighbouring elements
for ii=1:size(TRI,1)
nodeids=TRI(ii,:);
elem=[];
for jj=1:(nD+1)
[iind,~]=find(nodeids(jj)==TRI); % this is 80% of the time
elem=[elem; iind];
end
u = unique(elem);
% of all elements that have shared nodes with the current element,
% get only the ones that have 3 shared nodes.
graph.elements(ii).neighbours = int32((u(histc(elem,u)==nD)));
% some other code
end
% some other code
使用演示数据运行此脚本:
x = gallery('uniformdata',[30 1],0);
y = gallery('uniformdata',[30 1],1);
z = gallery('uniformdata',[30 1],2);
vertices=[x,y,z];
TRI= delaunay(x,y,z)
trimesh2graph(TRI,vertices);
如何提高此代码的性能?我预计它将需要一种不同的方法,而不仅仅是更快的命令。我看了一些 voronoi 图,但似乎无论如何都需要完成这个发现 (find)。
注意:我不一定需要MATLAB代码,如果你知道解决问题的算法请回答,我会在MATLAB中编写代码。
[1] 是的,最好将此信息存储在一维数组中。我稍后会,但现在使用当前结构更容易理解。
【问题讨论】:
-
你传递给你的函数的
delaunayTriangulation对象有它自己的neighbors方法,在解决你用来介绍你的问题的问题的性能上很难被击败。您描述的struct是否采用它为任何其他必要目的而使用的形式? -
@Will 没有通过
delaunayTriangulation对象,但我会在 MATLAB 中检查该版本的三角测量。是的,确实我需要这些信息来获取其他自己的代码。 -
@Will 说清楚,我从其他地方复制粘贴时出现拼写错误,我使用的是
delaunay()。但也许我应该使用那个 -
这样就搞定了!当以性能为目标时,应该直接使用
delaunayTriangulation类可以做的任何事情。剩下的三角测量问题可能需要从第一性原理解决的问题已经不多了。 -
@Will 确实没有!我正在探索,那可能会有答案;)谢谢
标签: matlab performance graph-theory adjacency-matrix undirected-graph