我有bool[,]
,并且输入Vector2(x,y)
,我想找到最近的true
的索引。我可以天真地遍历2d数组并检查输入的距离,但这将给我一个O(LxW)的运行时间。我想知道是否有更快的方法找到最接近O(LxW)。我愿意在Hashset<Vector2>
或排序的List<Vector2>
或任何其他类型的集合中添加所有真实坐标,如果它能更快地查找。
性能比此处的代码可读性更重要。
示例:
T, T, F
T, F, T
T, T, T
GetNearestTrue(new Vector2(2, 3)) // returns (1, 2)
GetNearestTrue(new Vector2(1, 1)) // returns (0, 1) or (1, 0) or (1, 2) or (2, 1), since they're equidistant it doesn't matter
答案 0 :(得分:2)
如果你有大量的“假”,那么就有更快的方法。您可以从O(L * W)= O(nFalse + nTrue)优化到约 O(log nTrue)。
您可以使用multidim-index(四叉树,kd-tree,R-Plus-Tree,PH-Tree)并插入每个&#39; true&#39; at(x,y)带坐标(x,y)的多维度索引中的一个点。 现在,找到最近的&#39; true&#39;对于一个点&#39; p&#39;,你只需在索引中进行最近邻搜索即可获得点数&#39; p&#39;。例如,this表示存在一种算法&#34;它声称保证了O(log n)的复杂性。&#34;
虽然kd-tree可能是最简单的(对于许多索引,请参阅here for Java实现),但PH-Tree可能有意义,因为它可以直接使用整数作为坐标,而不是浮点值。但是,我不知道PH-Tree的C#版本。
答案 1 :(得分:1)
是否有更快的方法找到最接近的O(LxW)?
如果L和W分别是2d阵列的长度和宽度,则答案为否。
简单证据: 想象一下,你必须证明网格中没有最接近的真实。 I.E.网格只包含false。在访问网格的每个单元格之前,你永远不能说没有。这意味着运行时间始终至少为O(LxW)。
为了证明节点(x,y)离(a,b)最近,你必须证明在半径为|Max(x-a, y-b)|
的(a,b)周围的圆中只有假而且在最坏的情况下,半径将是Max(L, W)
,这使得最坏情况下的运行时间为O(LxW)
虽然您可以通过从中心执行BFS来进行一些优化,但这会通过某些因素减少运行时间,但更糟糕的情况保持不变。