'稳定'的多维缩放算法

时间:2013-11-28 10:40:53

标签: c++ algorithm graph-algorithm

我有一个节点的无线网状网络,每个节点都能够向其邻居报告它的“距离”,以(简化的)信号强度测量它们。节点在地理上位于3d空间中,但由于无线电干扰,节点之间的距离不需要三角(三角)?一致。即,给定节点A,B和C,A和B之间的距离可能为10,A和C之间的距离也为10,但在B和C 100之间。

我想要做的是根据节点的连接性来可视化逻辑网络布局,即包括视觉中节点之间的逻辑距离。

到目前为止,我的研究表明,多维缩放(MDS)就是针对这种情况而设计的。鉴于我的数据可以直接表示为2d距离矩阵,它甚至可以是更为通用的MDS的简单形式。

现在,似乎有许多MDS算法,例如, http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.htmlhttp://tapkee.lisitsyn.me/。我需要在C ++中这样做,我希望我可以使用现成的组件,即不必从纸上重新实现算法。所以,我想这个:https://sites.google.com/site/simpmatrix/就是票。它有效,但是:

  • 布局不稳定,即每次重新运行算法时,节点的位置都会发生变化(请参阅下面的图像1和2之间的差异 - 这是因为已经运行了两次,没有任何进一步的更改)。这是由于初始化矩阵(包含每个节点的初始位置,算法然后迭代地校正)传递给该算法 - 我传递一个空的矩阵,然后实现派生一个随机的。通常,布局确实接近我从给定输入数据预期的布局。此外,在不同的运行之间,节点的方向(顺时针或逆时针)可以改变。见下面的图3。

  • 我认为很明显的'解决方案'是传递一个稳定的默认初始化矩阵。但是当我把所有节点放在同一个地方时,它们根本就没有移动;当我把它们放在一个轴上时(节点0在0,0;节点1在1.0;节点2在2.0等),它们只沿那个轴移动。 (见下图4)。但是它们之间的相对距离是可以的。

所以看起来这个算法只改变节点之间的距离,但不会改变它们的位置。

感谢您阅读这篇文章 - 我的问题是(我很乐意回答其中的一个或几个,因为每个人都可能会给我一个关于继续前进方向的线索):

  • 我在哪里可以找到有关许多MDS算法的属性的更多信息?
  • 是否有算法可以导出网络中每个节点的完整位置,而不必为每个节点传递初始位置?
  • 有没有一种可靠的方法来估计每个点的位置,以便算法可以正确地缩放它们之间的距离?我没有这些节点的地理位置,这是本练习的重点。
  • 是否有任何算法可以保持网络在运行之间的“角度”保持不变?

如果所有其他方法都失败了,我的下一个选择是使用我上面提到的算法,增加迭代次数以保持运行之间的差异在几个像素左右(我必须尝试迭代次数)然后“旋转”节点0周围的每个节点,例如,从左到右对齐水平线上的节点0和1;这样,在通过MDS算法确定它们的相对距离之后,我将“校正”点的位置。我还必须纠正每个节点周围的连接节点(顺时针或逆时针)的顺序。这可能会很快变得毛茸茸。

显然,我更喜欢稳定的算法解决方案 - 增加迭代以平滑随机性并不是非常可靠。

感谢。

编辑:我被转介到cs.stackexchange.com,并在那里做了一些评论;有关算法建议,请参阅https://cs.stackexchange.com/questions/18439/stable-multi-dimensional-scaling-algorithm

图像1 - 使用随机初始化矩阵:

Image 1 - with random initialization matrix

图像2 - 运行相同的输入数据后,与1:

比较时旋转

Image 2 - after running with same input data, rotated when compared to 1

图像3 - 与之前的2相同,但节点1-3处于另一个方向:

Image 3 - same as previous 2, but nodes 1-3 are in another direction

图4 - 在一条线上节点的初始布局,它们在y轴上的位置不会改变:

Image 4 - with the initial layout of the nodes on one line, their position on the y axis isn't changed

3 个答案:

答案 0 :(得分:3)

大多数缩放算法有效地在节点之间设置“弹簧”,其中弹簧的静止长度是边缘的期望长度。然后他们试图最小化弹簧系统的能量。当您将所有节点初始化为彼此之上时,任何一个节点移动时释放的能量量在每个方向上都是相同的。因此,相对于每个节点位置的能量梯度为零,因此算法离开节点所在的位置。类似地,如果您以直线方式启动它们,则渐变始终沿着该线,因此节点只会沿着它移动。

(这在许多方面都是一个有缺陷的解释,但它适用于直觉)

尝试将节点初始化为位于单位圆上,网格上或任何其他方式,使得它们不是全部共线的。假设库算法的更新方案是确定性的,那么应该为您提供可重现的可视化并避免简并条件。

如果库是非确定性的,要么找到另一个确定性的库,要么打开源代码并用随固定种子初始化的PRNG替换随机性生成器。我推荐使用前一个选项,因为其他更高级的库应该允许你设置你想要“忽略”的边缘。

答案 1 :(得分:0)

我已阅读“SimpleMatrix”MDS库的代码,发现它使用随机置换矩阵来确定点的顺序。修复排列顺序后(只使用srand(12345)而不是srand(time(0))),相同数据的结果不变。

答案 2 :(得分:0)

显然,这个问题一般没有确切的解决方案;只有4个节点ABCD和距离AB=BC=AC=AD=BD=1 CD=10,您无法清晰地绘制出合适的2D图表(甚至不是3D图表)。

这些算法所做的只是在节点之间放置弹簧,然后模拟排斥/吸引力(取决于弹簧是否比规定距离更短或更长),可能还会增加空间摩擦以避免共振和爆炸。

要保持“稳定”图表只需构建解决方案,然后只更新距离,重新使用先前解决方案中的当前位置作为起点。挑选两个固定节点并对齐它们似乎是防止缓慢漂移的好主意,但我会说弹簧力永远不会最终产生旋转动量,因此我认为只要缩放和居中解决方案应该足够了。 / p>