在Ruby中使用RGL处理有向图

在Ruby中使用RGL处理有向图,ruby,rgl,Ruby,Rgl,我已经使用RGL在Ruby中实现了一个有向图,只是很难弄清楚对于给定的节点,如何只找到具有传入连接的节点和具有传出连接的节点。也许我遗漏了一些简单的东西。看起来我有: 属性 [RW]来源 [RW]目标 这有用吗?我不太确定我是否理解你的问题。我刚刚遇到了这个问题。使用可能有效,但这可能不是最优雅的方法: require 'rgl/adjacency' require 'rgl/bidirectional' class RGL::DirectedAdjacencyGraph def in

我已经使用RGL在Ruby中实现了一个有向图,只是很难弄清楚对于给定的节点,如何只找到具有传入连接的节点和具有传出连接的节点。也许我遗漏了一些简单的东西。

看起来我有:

属性
[RW]来源
[RW]目标


这有用吗?我不太确定我是否理解你的问题。

我刚刚遇到了这个问题。使用可能有效,但这可能不是最优雅的方法:

require 'rgl/adjacency'
require 'rgl/bidirectional'

class RGL::DirectedAdjacencyGraph
    def in_degree(v)
    rdg = self.reverse
    rdg.adjacent_vertices(v).size
  end

  def out_degree(v)
    self.adjacent_vertices(v).size
  end
end

dg=RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]

p dg.in_degree(2)
#=> 2
p dg.out_degree(2)
#=> 1

p dg.in_degree(1)
#=> 0
p dg.out_degree(3)
#=> 0
更长的答案是,它似乎还没有实现

它的工作方式是通过在有向图类中包含RGL::双向模块,这将为您提供所有重要的each_in_neighbor方法。因此,类似的方法应该有效(但不能):

我还没有深入研究代码以了解这将需要多少工作,但根据您的需要,这可能是一个更好的选择

编辑:我忘了提到,度内节点无法访问源属性和目标属性。但另一种方法可能是从图中收集所有感兴趣的边,并对它们进行比较,以查看其中是否有任何一条将您感兴趣的节点作为目标

RGL::DirectedAdjacencyGraph仅有效地实现传出连接。如果您还希望有效地访问传入边,那么应该高效地实现RGL::BidirectionalGraph定义的概念。这应该通过在特定的有向图实现中实现方法RGL::BidirectionalGraph#each_in_neighbor来完成

假设您也将每个顶点的in邻居存储在一个列表中,就像DirectedAdjacencyGraph对out邻居所做的那样。然后该方法可以如下所示:

# Iterator providing access to the in-edges (for directed graphs) or incident
# edges (for undirected graphs) of vertex _v_. For both directed and
# undirected graphs, the target of an out-edge is required to be vertex _v_
# and the source is required to be a vertex that is adjacent to _v_.
def each_in_neighbor (v, &block)
  in_neighbors = (@vertice_dict_for_in_neighbors[v] or
                  raise NoVertexError, "No vertex #{v}.")
  in_neighbors.each(&block)
end

使用这种方法,在插入或删除边和顶点时,您必须管理两个顶点字典。

我认为RGL应该拥有自己的标记,所以我为您创建了一个。
# Iterator providing access to the in-edges (for directed graphs) or incident
# edges (for undirected graphs) of vertex _v_. For both directed and
# undirected graphs, the target of an out-edge is required to be vertex _v_
# and the source is required to be a vertex that is adjacent to _v_.
def each_in_neighbor (v, &block)
  in_neighbors = (@vertice_dict_for_in_neighbors[v] or
                  raise NoVertexError, "No vertex #{v}.")
  in_neighbors.each(&block)
end