【问题标题】:How to make this for loop more efficient?如何使这个 for 循环更有效?
【发布时间】:2019-10-16 22:49:06
【问题描述】:

我为一个函数编写了代码,该函数从一个三角曲面中找到所有连接的顶点。 曲面由顶点列表 (VL) m x 3 和面列表 (FL) n x 3 组成。 VL 的每一行都是一个点 (x y z)。
FL 的每一行索引 VL 的三行。这三个点构成一个三角形。

function List = findVLInd(FL, StartingPoint)

  List = StartingPoint;

  for a = 1:50000
    List = [List;find(List(a,1)==FL(:,1))];
    List = [List;find(List(a,1)==FL(:,2))];
    List = [List;find(List(a,1)==FL(:,3))];

    Lz = FL(List,:);
    List = [List;Lz(:,1);Lz(:,2);Lz(:,3)];
    List = unique(List);
  end 
end

脚本运行后,有 50,000 个数字可用作 VL 的索引。

不幸的是,这真的很慢。可能是因为 for 循环和每个循环增长的列表。 50,000这个数字是任意设定的。我的 FL 大约有 116,000 行,但并非所有行都相互连接。

如何提高效率?

【问题讨论】:

  • List(a,1) 在循环中做了什么?鉴于您扩展List 的方式,元素a 是相当随意的。该列表可以比a 增长更快或更慢,unique 将改变元素的顺序。除此之外,加快速度的方法是使用适当的索引来更快地找到相邻的面。建立一个顶点列表,链接到每个顶点使用的每个面。
  • 感谢您的建议。我偶然想到,a总是会索引一些不同的点。我会尽量按照你推荐的方式制作一个列表
  • 如果您提供一些示例数据和几行有用的解释。我的直觉是你应该完全避免 for 循环。粗等价也不可靠。应用 abs(x-y) 并找到最小值的 bsxfun 行中的某些东西似乎可以完成这项工作。如果你提供一些具体的数据,我可以试试。祝你好运

标签: matlab performance for-loop


【解决方案1】:

在语法方面我建议如下:

function List = findVLInd(FL, StartingPoint)

  List = StartingPoint;

  for a = 1:50000
    List(end+1, :) = [find(List(a,1)==FL(:,1))];
                      find(List(a,1)==FL(:,2))];
                      find(List(a,1)==FL(:,3))];

    Lz = FL(List,:);
    List(end+1:end+size(Lz,1), :) = [Lz(:,1);Lz(:,2);Lz(:,3)];
    List = unique(List);
  end 
end

这删除了重新分配操作List = [List; X],它将列表的内容复制到另一个变量中,然后将其删除(尽管新变量与前一个变量具有相同的名称)并用附加操作替换它,这在Matlab,虽然仍然很慢。通过在单个块中调用 for 循环中的前三行,我还可以减少此类操作的数量。

根据 ChrisLuengopacta-sunt-servanda 的 cmets,您可能还需要解决其他旨在改进代码功能的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-25
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2021-11-18
    • 1970-01-01
    • 2018-11-01
    相关资源
    最近更新 更多