使用哈希映射会为所有访问增加 log(n) 复杂度(然后遍历整个网格通常会花费 n log(n)),因此显然它不是最佳解决方案。
现在您的问题是如何有效地存储和遍历邻接信息,即每个单元格的相邻单元格列表。您可以将一个单元格映射到其邻居列表的第一件事:您可以使用数组而不是哈希,这将消除 log(n) 成本。
然后,使用数组,这意味着您需要存储不同长度的列表数组(如果您的网格有任意多面体),这通常不是很有效:每个列表都有自己的内存开销要添加到使用的内存中通过它包含的元素。存储此类信息(即不同长度的列表数组)的一种更有效的方法是“压缩行存储”(称为 CRS、CSR 或耶鲁格式)表示 [1],用于存储稀疏矩阵。
编辑如果您的输入中不存在邻接信息,那么您将需要重新创建它。而不是使用其他答案中建议的散列或关联映射,另一种方法是将所有方面存储在一个数组中然后排序这个数组。排序后,与相邻单元格对应的分面对在数组中是连续的。我观察到它的效率要高得多(至少在 C++ 中,我没有在 Python 中测试过)。另请参阅我对这个问题的回答 [2]。为了使我的答案适应您的多面体网格,构面记录将具有一个构面索引,并且作为键,三个顶点索引(构面中的最低顶点 id 和通过边缘连接到它的两个顶点,按递增顺序)。通过按字典顺序对构面记录进行排序,您将检索数组中连续的一对相邻构面。
算法:
For each cell c
For each facet f of cell c
Find v1 the smallest vertex index in facet f
Find v2 and v3, the vertices before and after v1 in facet f
If v3 < v2, swap v2 and v3
Append a new record [v1, v2, v3, c] to the array
Sort the record array with the lexicographic order on (v1,v2,v3)
In the record array, find (by scanning the array) the contiguous
pairs of record (v1,v2,v3,c1);(v1,v2,v3,c2) with the same (v1,v2,v3).
For each such pair, c1 and c2 are adjacent.
如果输入数据具有 facet id,则记录只是 (f,c) 对,它们按 f 排序(而不是 (v1,v2,v3))。
[1] https://en.wikipedia.org/wiki/Sparse_matrix
[2]生成元素边数的网格选项(tetgen-triangle)