【发布时间】:2019-12-02 07:50:49
【问题描述】:
我们有一个长的(大约 100,000 个)二维 numpy 数组。 喜欢:
A_in =
[[1, 2, 3, 4, 3, 2, 1, ..., 100000],
[2, 3, 3, 5, 4, 3, 1, ..., 100000]](代码中的edge_index_cpu)
您可以在此处将一列视为一组。每个数字表示一个点,一列表示这两个点之间的线。
我们需要得到输出,比如:
A_out =
这些输出值在原始数组中的索引,如:
Idx_out = [0, 2, 3]
输出组不能与之前的所有组有任何交集。另外,如果前一个组已经被移除(如上面的[[2],[3]]),那么被移除的组将不会用于计算交集(因此,[[3],[3]]被保留)。
它可以通过 for 循环轻松实现。但是因为数据对于‘for循环’来说太大了,所以我们想求一个可以并行化的算法来解决这个问题。
我尝试使用扁平版 A_in 中的 numpy 唯一运算符 ([1, 2, 2, 3, 3, 3, 4, 5, 3, 4, 2, 3, 1, 1, ...])。但它不能满足这个“如果前一个组已经被移除(如上面的[[2],[3]]),那么被移除的组将不会用于计算交集(因此,[[3],[3] ] 保留)”。
我们要处理包含边和点的图。
edge_index_cpu = edge_index.cpu()
for edge_idx in edge_argsort.tolist():
source = edge_index_cpu[0, edge_idx].item()
if source not in nodes_remaining:
continue
target = edge_index_cpu[1, edge_idx].item()
if target not in nodes_remaining:
continue
new_edge_indices.append(edge_idx)
cluster[source] = i
nodes_remaining.remove(source)
if source != target:
cluster[target] = i
nodes_remaining.remove(target)
i += 1
# The remaining nodes are simply kept.
for node_idx in nodes_remaining:
cluster[node_idx] = i
i += 1
cluster = cluster.to(x.device)
【问题讨论】:
-
假设 32 位非负整数索引高达 1000000(可能要少得多),那么为什么不使用直方图标记已使用的点将您的问题转换为单个
O(n)for循环?您只需要一个直方图,其中包含每个可能的点索引的单个整数(或只是位)所以hist[1000000]...这应该很快,所以不需要并行化...在标准 PC 上的 C++ 中我希望它应该占用到 1 秒甚至更短……我不会用 Python 编写代码,C++ 示例会有帮助吗? -
@Spektre 谢谢。我不明白你的想法,你介意给一些更详细的解释吗?有 100 个字符(每个字符 10000 个顶点),一次只处理 12 个字符。你可以考虑 100,000 而不是 100 万。
-
@Spektre CG 电影或游戏中的每个角色都包含大约 10,000 个顶点。我使用这些顶点来构建图形并将这些图形输入到图形神经网络中。期待您的回答
标签: python-3.x graphics