如何根据邻接矩阵有效地更新权重?

时间:2016-04-22 02:37:22

标签: scala apache-spark graph spark-graphx

我有一张非常大的图表。节点之间有链接的地方。每个边缘最初都具有重量1。我必须根据变换的邻接矩阵更新边的权重。

enter image description here

其中A是调整矩阵。节点(i,j)中的新权重将由M(i,j)给出。

我必须在Graphx中这样做。我该怎么做呢?

我的方法:找到每个节点的所有相邻节点,内部连接它们。对。然后更新每个节点的权重。

但我对在Graphx中编写高效代码感到困惑。 我该怎么办呢?我们赞赏代码片段。

1 个答案:

答案 0 :(得分:2)

有关使用GraphX有效处理稀疏矩阵的示例,请参阅GraphX的SVD ++实现的源代码。

https://github.com/apache/spark/blob/branch-1.6/graphx/src/main/scala/org/apache/spark/graphx/lib/SVDPlusPlus.scala

基本上,它只使用aggregateMessages(),因此邻接矩阵中每个非零条目的一条消息被发送到相邻的顶点 - 从而避免考虑(处理)邻接矩阵的零值条目。

编辑(附加信息):

首先,您必须计划将要存储在每个顶点的内容,以及您最后如何收集此信息以生成M(i,j)。请注意分母中的两个范数,| A(:,i)|和| A(:,j)|反复使用。如果图中有n个顶点(即,如果A是nxn矩阵),那么即使有n 2 M(i,j)' s。

一个好的计划是每个顶点i存储两个向量(例如在两个Array [Double] s的Tuple2中):| A(:,i)|和[,...,](称之为Vi)。然后在最后,您将通过从graph.vertices()中提取此信息并将其组合以生成M来计算M.

| A(:,i)的|简单。对于每个顶点i,这只是入站边的数量。 (要看到这一点,请考虑A对邻接矩阵的意义并绘制图表。)

Vi有点棘手,但并不过分。首先,对于每个顶点,我们需要提出一个向量而不仅仅是像| A(:,i)|那样的单个数字。并且长度为n的向量的每个分量最多需要n个输入。

回想邻接矩阵背后的含义,计算Vi的第j个分量(也就是n个产品的总和),只要某个顶点k对两个边都有一个边,我们只需要加1我和j。因此,您可以采用的方法是连续两次使用aggregateMessages:沿边缘向后传输相邻顶点。使用一些非常松散的术语:首先从j个顶点到k个顶点,然后从k个顶点到i个顶点。这样,每个顶点都知道两个跃点内的所有邻居(如果A是稀疏的,那么每个顶点可以累积那么多信息)。这将允许您计算Vi。