与该问题有关的第一件事是何时何地需要什么数据。为此,我通常从问题的愚蠢的串行版本开始。
查找所有x大于x $ /英亩的地块,它们与另一个地价小于z $ /英亩的地块y英尺之内。
foreach p in parcels {
if value(p) > x {
foreach q in parcels {
if (dist(p,q) <= y) and (value(q) < z) {
emit(p)
}
}
}
}
虽然此算法未优化,但可以解决问题。
我为硕士论文解决了一个类似的问题,该论文为数据集中的每个点找到了最近的地块。我在PostGIS,Hadoop
和MPI中实现了该解决方案。我的论文的完整版本在这里,但是我将总结适用于此问题的要点。
MapReduce并不是解决此问题的好平台,因为它需要访问整个数据集(或精心选择的子集)来处理单个宗地。MapReduce无法很好地处理辅助数据集。
但是,MPI可以轻松解决此问题。最困难的部分是确定如何拆分数据。此拆分基于存在的数据量,要在其上运行的处理器数量以及每个处理器有多少内存。为了获得最佳缩放比例(并因此获得最佳性能),您将需要一次在内存中(跨所有计算机)拥有宗地数据集的多个副本。
为了解释它是如何工作的,我假设您的50台计算机中的每台都具有8个处理器。然后,我将指派每台计算机检查1/50包裹的责任。该检查将由计算机上的8个进程执行,每个进程都具有相同地块的1/50部分和地块数据集的1/8的副本。请注意,这些组不仅限于一台计算机,还可以跨越计算机边界。
该过程将执行该算法,从第1/50个宗地集合中获取p的宗地,从第1/8个宗地集合中获取q的宗地。内循环之后,同一台计算机上的所有进程将一起交谈以确定是否应发出包裹。
对于我的问题,我实现了与此类似的算法。您可以在此处找到源。
即使使用这种未优化的算法,我也可以获得令人印象深刻的结果,这些结果针对程序员的时间进行了高度优化(这意味着我可以编写一个愚蠢的简单算法,并且计算仍然足够快)。要优化的下一个位置(如果确实需要)是为每个过程设置第二个数据集(从中获取q)的四叉树索引。
回答原始问题。有一个体系结构:MPI + GEOS。从我的ClusterGIS实施中获得一点帮助,可以做很多事情。所有这些软件都可以作为开源软件找到,因此无需任何许可费用。当我在linux上工作时,我不确定它对Windows的可移植性(也许与Cygwin兼容)。该解决方案可以部署在EC2,Rackspace或任何可用的云上。当我开发它时,我正在大学中使用专用的计算集群。