我有一个网格(不一定是正方形,但我将其绘制为方形以简化它)以及与每个较小正方形相关联的某些值。给定一个半径为x
的圆,我试图找到值的总和最大的区域。以下图片将清楚说明:
我的猜测是,如果使用大量的小方块将平面划分为网格,将圆近似为正方形只会导致一些过度近似,这对我来说是好的,因为我还没有最终确定如何解决与部分正方形重叠的圆的情况(它的值是什么?)。
我能想到的最简单的方法是蛮力:可能在左下方开始,然后开始沿曲折路径移动,直到我们到达右上方并输出具有最大总和的区域。我对这种方法很好,但是对于大型平面区域,将会有大量的正方形,并且在某种程度上这种方法可能会证明是昂贵的。我不确定是否有更好的方法来解决这个问题,但我真的很感激,如果有人对如何解决这个问题有其他想法。
答案 0 :(得分:1)
除非小方块中的数据存在趋势,否则我认为可能确实需要使用蛮力方法,尽管您可能想要找出一个不会采用我相信的多项式或指数时间的方法。需要一种天真的蛮力方法。
但是,如果存在趋势(较高值的值往往被组合在一起,或者您更有可能在一侧遇到比另一侧更高的值),您可以设置一个算法来预测您的区域网格更有可能包含更高的值。
当然,我可能会遗漏一些东西。
答案 1 :(得分:1)
矩形表壳和圆形表壳完全不同。
如果您正在寻找最佳的矩形区域,您的蛮力方法是O(nk)
(n =区块总数,k =区域内的区块数),可以很容易地改进到O(n)
通过沿行/列缓存一些部分和 - 这是您可能做的最好的,因为您必须至少查看一次每个图块。如果您需要经常这样做,使用不断变化的区域或区块,空间数据结构将比O(n)更快,但需要进行一些初始设置。
对于圆形情况,如果圆的中心仅限于平铺边,我不确定如何改进O(nk)
强力算法。
但是,如果圆圈可以像你所说的那样真正任何地方,那么你就无法对每个可能的圆圈位置进行蛮力,因为有无限可能的位置!
相反,你需要一些更聪明的东西;例如,请参阅this answer (将每个图块的中心视为加权点)。请注意,由于这些点是加权的,因此您必须记住,最佳圆圈可能只有一个点!答案 2 :(得分:1)
为了在常规网格中的矩形中找到一个和,实际上有一个简单的算法可以在O(n)中进行。设G为该网格,g(x,y)为单元格(x,y)
的值令H为新网格,使得对于所有i <= x,h(x,y)=和g(i,j); j&lt; = y(你可以在线性时间内完成)。
现在,矩形(x1,y1)..(x2,y2)中的和等于h(x2,y2)-h(x1,y2)-h(x2,y1)+ h(x1,y1)
我明白你的原始问题比这更复杂,但也许可以采用类似的方法?
答案 3 :(得分:0)
我有一个想法可能有助于加快搜索圆的大小远小于小方块的情况。
不是一次移动圆圈一个小方块,而是先用非重叠圆圈平铺整个平面并计算每个圆圈的值。这将允许您建立所有剩余圆的可能总和的上限。
例如,假设你只有9个圆圈,在计划的3x3平铺中,他们的总和是:
10 10 10
10 1 1
1 1 1
然后你知道任何一个圆圈可以拥有的最多是31,而一个31的圆圈必须与左上角的4个圆圈重叠:0,0 0,1 1,0和1,1(行,左上角的col位置)。
鉴于上述数字,您可以立即忽略仅位于右下区域内的所有圆圈:1,1 1,2,2 2,1 2,2。
实现这个算法会有点棘手,但如果圆圈比正方形大得多并且数字分布不均匀(也就是说,如果某些区域的数字更大,那么它应该可以工作并为您提供大量的加速比其他人。)