有限度量嵌入:好的算法?

时间:2011-09-28 17:16:23

标签: python algorithm graph-algorithm metric

我有一个有限度量空间给定为(对称)k乘k距离矩阵。我想要一种算法(近似)在欧几里德空间R ^(k-1)中等距地嵌入它。虽然通过求解距离给出的方程组并不总是可以完成,但我正在寻找一种嵌入了一些(非常小的)可控误差的解决方案。

我目前使用多维缩放(MDS),输出维度设置为(k-1)。在我看来,通常MDS可能会针对您尝试将环境嵌入维度减少到小于(k-1)(通常为2或3)的情况进行优化,并且可能有更好的算法用于我的限制情况下。

问题:使用欧氏距离在R ^ {k-1}中实现大小为k的度量空间的好/快算法是什么?

一些参数和指针:

(1)我的k相对较小。说3< k< 25

(2)我实际上并不关心我是否嵌入了R ^ {k-1}。如果它简化了事物/使事情变得更快,任何R ^ N也会很好,只要它是等距的。如果我有一个更快的算法,或者如果我增加到R ^ k或R ^(2k + 1),我会很高兴。

(3)如果你可以指向python实现,我会更开心。

(4)任何比MDS更好的方法都可以。

2 个答案:

答案 0 :(得分:1)

为什么不试试LLE,你也可以在那里找到代码。

答案 1 :(得分:0)

好的,正如这里所承诺的一个简单的解决方案:

表示法:让d_{i,j}=d_{j,i}表示点ij之间的平方距离。让N为点数。让p_i表示点ip_{i,k}k - 坐标。

我们希望我现在正确地推导出算法。之后会有一些解释,所以你可以检查推导(我讨厌出现很多索引时)。

该算法使用动态编程来获得正确的解决方案

Initialization:
p_{i,k} := 0 for all i and k

Calculation:
for i = 2 to N do
   sum = 0
   for j = 2 to i - 1 do
     accu = d_{i,j} - d_{i,1} - p_{j,j-1}^2
     for k = 1 to j-1 do
       accu = accu + 2 p_{i,k}*p_{j,k} - p_{j,k}^2
     done
     p_{i,j} = accu / ( 2 p_{j,j-1} )
     sum = sum + p_{i,j}^2
   done
   p_{i,i-1} = sqrt( d_{i,0} - sum )
done

如果我没有做过任何严重的索引错误(我通常这样做),这应该可以解决问题。

这背后的想法:

我们在原点设置第一个任意点,让我们的生活更轻松。对于点p_i而言,我们永远不会在k时设置坐标k > i-1。即对于第二个点,我们只设置第一个坐标,对于第三个点,我们只设置第一个和第二个坐标等。

现在让我们假设我们有所有点的坐标p_ {k'} k'<i我们想要计算p_{i}的坐标,以便满足所有d_{i,k'}(我们不会关注k>k')点的任何约束。如果我们写下我们有的方程组

d_{i,j} = \sum_{k=1}^N (p_{i,k} - p_{j,k} )^2

因为p_{i,k} p_{j,k}k>k'都等于零,我们可以将其减少为:

d_{i,j} = \sum_{k=1}^k' (p_{i,k} - p_{j,k} )^2

另请注意,通过循环不变量,p_{j,k}时所有k>j-1都将为零。所以我们将这个等式分开:

d_{i,j} = \sum_{k=1}^{j-1} (p_{i,k} - p_{j,k} )^2 + \sum_{k=j}^{k'} p_{i,j}^2

对于我们得到的第一个等式:

d_{i,1} = \sum_{k=1}^{j-1} (p_{i,k} - p_{j,k} )^2 + \sum_{k=j}^{k'} p_i{i,1}^2

这个需要稍后进行一些特殊处理。

现在,如果我们在正规方程中求解所有二项式,我们得到:

d_{i,j} = \sum_{k=1}^{j-1} p_{i,k}^2 - 2 p_{i,k} p_{j,k} + p_{j,k}^2 + \sum_{k=j}^{k'} p_{i,j}^2

从中减去第一个等式,然后留下:

d_{i,j} - d_{i,1} = \sum_{k=1}^{j-1} p_{j,k}^2 - 2 p_{i,k} p_{j,k}

对于所有j&gt; 1。

如果你看一下这个,你会注意到p_i坐标的所有方格都消失了,我们需要的唯一方格已经知道了。这是一组线性方程,可以使用线性代数方法轻松解决。实际上,关于这组方程还有一个特别之处:方程已经是三角形,所以你只需要传播解的最后一步。对于最后一步,我们留下一个单一的二次方程,我们可以通过取一个平方根来解决。

我希望你能按照我的推理。这有点晚了,我的头脑从这些指数中略微旋转。

编辑:是的,存在索引错误。固定。当我有时间测试时,我会尝试在python中实现它。