【问题标题】:Fill in the gaps of a 2D array填充二维数组的空白
【发布时间】:2016-05-03 22:31:42
【问题描述】:

我有一个人口稀少的数组,如下所示。有没有一种算法可以用线性有意义的值填充所有空白? IE。从周围的原始值推导出来。

我看过双线性插值和双三次插值,但还有其他的吗?

     |    1    |    2   |    3    |    4    |    5    |    6    |    7
---------------------------------------------------------------------------------
1    | 
2    |
3    |             55
4    |             50                                     12         6
5    |             45                                                19
6    |             xxx 
7    |             35        45       50        yyy
8    |
9    |
10   |
11   |
12   |                       zzz
13   |
14   |
15   |

例如,我希望 xxx 在 40 附近,而 yyy 在 50 附近。然而,zzz 可能具有更随机的值。但请注意:我想填充每个空白空间,而不仅仅是 xxx、yyy 和 zzz。并且能够对任何人口稀少的数组这样做。

这样的算法存在吗?

【问题讨论】:

    标签: algorithm interpolation bicubic bilinear-interpolation


    【解决方案1】:

    存在一百万个这样的算法。所以首先你有一些已知值的字典,如下所示:

    known_values = {
        (2, 3): 55.0,
        (2, 4): 50.0,
        (2, 5): 45.0,
        (2, 7): 35.0,
        (3, 7): 45.0,
        (4, 7): 50.0,
        (6, 4): 12.0,
        (7, 4): 6.0,
        (7, 5): 19.0,
    }
    

    最简单的方法是说任何点的值是所有填充点的加权平均值。按 1/距离平方加权。所以在你上面的例子中,你会有这样的代码:

    def interpolate(known_values, p):
         total_weight = 0.0
         total_sum = 0.0
         for q, value in known_values:
             if p == q:
                 return value
             d_square = (p[0] - q[0])**2 + (p[1] - q[1])**2
             total_weight = total_weight + 1.0 / d_square
             total_sum = total_sum + value / d_square
         return total_sum/total_weight
    

    只要矩阵有任何填充数据,此解决方案就可以工作。

    但是,从您提出问题的方式来看,您可能需要在任何小区域中近似线性的平滑插值。一种方法是查找(a, b, c),以便函数a*x + b*y + c 最小化误差平方的加权和,权重是从所需点到已知点的距离的4 次方。 (前 2 个幂撤消该区域的平方,其他两个对附近点的权重更大。)

    这里使用最小二乘法的原因是数学很简单。当abc 的微小变化不会使值发生太大变化时,您将最小化,这意味着偏导数为 0。因此,三个偏导数为您提供 3 组线性方程。在 3 个变量中求解 3 个方程相当容易。

    但是推导过程又长又乱。如果您想尝试一下,您应该查看通常的最小二乘推导,并尝试处理细节。然后尝试实现它。但仅当您真的想要尝试对远离您拥有数据的点进行线性投影时才尝试这样做。

    【讨论】:

      【解决方案2】:

      这个问题可以看作是一个“二元插值”问题,在这个领域有大量的研究。您可以在 Wiki 中搜索“多元插值”并在“二维”部分下查找算法。

      在各种方法中,双线性/双三次插值需要数据形成网格,而您的数据并非如此。根据您的情况,Delaunay 三角测量方法不适合外推。反加权距离方法易于实现并且适用于外推,但结果往往不能令人满意。只要您没有太多数据点(如数千个),我个人建议使用径向基函数。

      【讨论】:

        【解决方案3】:

        我已经在 GitHub 上上传了我自己的解决方案,它使用了薄板样条方法:

        https://github.com/lunarquaker/ThinPlateSpline_DotNet

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-05-27
          • 1970-01-01
          • 1970-01-01
          • 2014-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多