在2D阵列中找到峰值的算法

时间:2012-03-06 15:54:27

标签: java algorithm max multidimensional-array

假设我在java int[][] array中有一个2D累加器数组。该数组可能如下所示:

(x和z轴表示数组中的索引,y轴表示值 - 这些是int[56][56]的图像,值为0~4500) array sample 1

array sample 1

我需要做的是在数组中找到峰 - 第一个中有2个峰,第二个数组中有8个峰。这些峰值总是“明显的”(峰值之间始终存在间隙),但它们不必像这些图像那样相似,它们可能或多或少是随机的 - 这些图像不是基于真实数据,只是样本。真正的阵列可以有5000x5000的大小,峰值从几千到几十......算法必须是通用的,我不知道阵列或峰值有多大,我也不知道那里有多少个峰值是。但我确实知道某种阈值 - 峰值不能小于给定值。

问题是,一个峰可以由附近的几个较小的峰组成(第一个图像),高度可以是非常随机的,并且在一个阵列中大小可以显着不同(大小 - 我的意思是它需要的单位数在阵列中 - 一个峰值可以由6个单位组成,其他峰值可以由90个单位组成。它也必须快速(全部在1次迭代中完成),数组可能非常大。

感谢任何帮助 - 我不希望你的代码,只是正确的想法:)谢谢!

<小时/> 编辑:您询问了域名 - 但它非常复杂,而且它无法解决问题。它实际上是一个带有3D点的ArrayLists数组,如ArrayList&lt; Point3D&gt; [] []和有问题的值是ArrayList的大小。每个峰包含属于一个簇的点(在这种情况下为平面) - 该数组是算法的结果,该算法对点云进行分段。我需要在峰值中找到最高值,这样我就可以将“最大”的arraylist中的点拟合到一个平面,从中计算一些参数,然后正确地聚集来自峰值的大部分点。

3 个答案:

答案 0 :(得分:7)

他对使用某种优化启发式估算全局最大值不感兴趣 - 他只想在多个独立的聚类中找到最大值。

  

这些峰值总是“明显的”(峰值之间始终存在差距)

根据您的图片,我认为您的意思是总是有一些0 - 值将群集分开?如果是这种情况,您可以使用简单的flood-fill来识别群集。您还可以在执行洪水填充时跟踪每个群集的最大值,因此您既可以识别群集又可以同时找到它们的最大值。

这也尽可能快,而不依赖于启发式(可能会返回错误的答案),因为每个群集的最大值可能是群集中的任何值,所以你必须至少检查一次。


请注意,这将遍历数组中的每个项目。这也是必要的,因为(根据您提供给我们的信息),数组中的任何单项都可能成为其自己的集群(这也会使其成为峰值) 。在阵列中有大约2500万个项目,这在现代计算机上只需要几秒钟。

答案 1 :(得分:2)

这可能不是最佳解决方案,但由于问题听起来有点流畅,我会把它写下来。

  1. 构建超过最小阈值的所有值(和坐标)的列表。
  2. 按高度降序排序。
  3. 第一个元素将是最大的峰值,将其添加到峰值列表中。
  4. 然后下拉列表,如果当前元素超过所有现有峰值的最小距离,则将其添加到峰值列表。
  5. 这是一个线性描述,但所有步骤(3除外)都可以简单地并行化。在步骤4中,您还可以使用覆盖图:一个二维布尔数组,显示哪些坐标已被附近的峰“覆盖”。

    (警告说:一旦你改进了标准,这个解决方案可能会变得完全不可行,但总的来说它可行。)

答案 2 :(得分:1)

Simulated annealinghill climbing就是我们想到的。但这些算法并不能保证找到所有峰值。

但是如果你的“峰值”被0的值除以间隙,那么connected components analysis可能会有所帮助。如果区域连接的值大于0(或者如果您有一个特定的阈值,标签区域已连接超过该阈值),您可以将区域标记为“已连接”,然后您的组件数量将是您的峰值数量。然后,您还可以再次传递数组以查找每个组件的最大值。

我应该注意,连通分量可以在线性时间内完成,找到峰值也可以在线性时间内完成。