【问题标题】:How to update the weights efficiently according to adjacency matrix?如何根据邻接矩阵有效地更新权重?
【发布时间】:2016-04-22 02:37:21
【问题描述】:

我有一个非常大的图表。节点之间有链接的地方。每条边最初的权重为 1。我必须根据转换后的邻接矩阵来更新边的权重。

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

我必须在 Graphx 中执行此操作。我该怎么做呢?

我的方法:找到每个节点的所有相邻节点,并在内部加入它们。然后更新每个节点的权重。

但我对在 Graphx 中编写高效代码有点困惑。 我该如何处理这件事?代码快照表示赞赏。

【问题讨论】:

  • 除了“给我代码”之外,您的实际问题是什么?
  • 当您提交我们的代码时,我们是否可以在您的班级中分享A
  • 为什么需要graphx?
  • @TheArchetypalPaul ,我正在实现基于纸张的子图查找算法。第一步是根据上面给定的公式将邻接矩阵更改为加权矩阵。我很困惑如何有效地编写代码来更新图的边权重。所以我的问题是你能指导我如何将邻接矩阵转换为 M 矩阵并更新权重吗?
  • 对我来说仍然听起来像是“给我代码”。你试过什么,或者你在哪里适应@MichaelMalak的答案?

标签: scala apache-spark graph spark-graphx


【解决方案1】:

有关使用 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 是一个 n x n 矩阵),那么即使有 n2 M( i,j) 将被计算。

一个好的计划是让每个顶点 i 存储两个向量(例如,在两个 Array[Double] 的 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。

【讨论】:

  • 感谢您的回复。当我想更新边的权重时,聚合消息起作用。但是我想计算公式所示的两列邻接矩阵的余弦并更新相应的权重。那么我该如何实现呢?
  • 更新了我的答案以概述可能的具体方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 2015-12-17
  • 1970-01-01
  • 2021-10-10
  • 2020-12-11
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多