【问题标题】:Random walks in directed graphs/networks有向图/网络中的随机游走
【发布时间】:2012-02-03 11:03:24
【问题描述】:

我有一个(在实践中)多达 50,000 个顶点的加权图。给定一个顶点,我想根据所有相邻边的相对权重随机选择一个相邻顶点。

我应该如何将此图表存储在内存中,以便进行有效的选择?什么是最好的算法?它可以像每个顶点的键值存储一样简单,但这可能不适合最有效的算法。我还需要能够更新网络。

请注意,我一次只想迈出一个“步骤”。


更正式地:给定一个加权的、有向的、可能完全的图,让 W(a,b) 为边 a->b 的权重,让 Wa 是来自 a 的所有边的总和。给定一个输入顶点v,我想随机选择一个顶点,其中选择顶点x的可能性是W(v,x) / Wv

示例

W(v,a) = 2, W(v,b) = 1, W(v,c) = 1.

给定输入 v,该函数应以 0.5 的概率返回 a,以 0.25 的概率返回 bc .

【问题讨论】:

  • 最合适的表示可能取决于图的稀疏程度。另外,“容易[进行选择]”是指“高性能”还是“需要很少的代码”?
  • @aix 图可能是完整的(如前所述),但通常会有些稀疏(每个节点可能有 25% 的可能出边?)。我进行了编辑以明确表示我想要高效的性能而不是简单的代码。

标签: c algorithm data-structures graph


【解决方案1】:

如果您担心生成随机游走的性能,您可以使用alias method 构建一个非常适合您选择随机传出边的要求的数据结构。开销只是你必须为每个有向边分配一个概率权重和一个所谓的别名边。

因此,对于每个音符,您都有一个传出边向量以及权重和别名边。然后您可以在恒定时间内选择随机边(仅数据结构的生成是相对于总边数或节点边数的线性时间)。在示例中,边由->[NODE] 表示,节点v 对应于上面给出的示例:

Node v
    ->a (p=1,   alias= ...)
    ->b (p=3/4, alias= ->a)
    ->c (p=3/4, alias= ->a)

Node a
    ->c (p=1/2, alias= ->b)
    ->b (p=1,   alias= ...)

...

如果您想选择一个出边(即下一个节点),您只需从区间 [0,1) 生成一个随机数 r uniform。

然后你会得到no=floor(N[v] * r)pv=frac(N[v] * r) 其中N[v] 是传出边的数量。 IE。您以完全相同的概率选择每条边(即节点v 示例中的 1/3)。

然后你将这条边的分配概率p 与生成的值pv 进行比较。如果pv 小于,则保持之前选择的边缘,否则选择其别名边缘。

如果我们有来自随机数生成器的r=0.6,我们有

no = floor(0.6*3) = 1 
pv = frac(0.6*3) = 0.8

因此我们选择第二个出边(注意索引从零开始),即

->b (p=3/4, alias= ->a)

并切换到别名边缘->a,因为p=3/4 < pv

对于节点v的例子我们因此

  • 1/3*3/4 的概率选择边缘b(即无论何时no=1pv<3/4
  • 1/3*3/4 的概率选择边缘c(即无论何时no=2pv<3/4
  • 1/3 + 1/3*1/4 + 1/3*1/4 的概率选择边缘a(即无论何时no=0pv>=3/4

【讨论】:

  • @jmilloy 我调整了示例以匹配您给定的数字。查看我的编辑。
  • 这看起来像是答案;你能简单谈谈更新网络需要什么 - 改变一条边的权重吗?
  • 如果您更改来自特定节点的所有边的权重中的任何一个(因为总权重发生变化),则必须更新所有传出边。
  • 因此,如果我更新更多边的频率比选择节点的频率高,这可能会带来太多开销,不值得。
  • 是的,你是对的。但这将是一个非常奇怪的案例,阅读次数少于更改次数。另外,您可以累积更改并一起更新所有边缘。
【解决方案2】:

理论上绝对最有效的做法是为每个节点存储连接节点及其权重的平衡二叉树(红黑树,或 BTree,或跳过列表都适合)的道德等价物,以及每边的总重量。然后你可以从 0 到 1 中选择一个随机数,乘以连接节点的总权重,然后进行二分查找。

但是,像这样遍历二叉树涉及很多选择,这些选择往往会造成流水线停顿。这是非常昂贵的。因此,在实践中,如果您使用一种高效的语言(例如 C++)进行编程,如果每个节点的连接边少于几百条,那么您将进入的边的线性列表(带有预先计算的总和)循环可能会更快。

【讨论】:

  • 不进行树搜索会更有效(例如,请参阅我的答案中链接的文章)。
  • @Howard:我假设了浮点权重,在这种情况下,别名方法无法给出正确的答案。对于整数权重,或具有合理小公分母的有理数,您是正确的。
  • 与整数或有理数无关。别名方法也适用于浮点权重。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2021-07-29
相关资源
最近更新 更多