我使用RGL在Ruby中实现了一个有向图,只是很难弄清楚如何为给定节点找到只有传入连接的节点和有传出连接的节点。也许我错过了一些简单的事情。
答案 0 :(得分:3)
我刚遇到这个问题。使用reverse method可能会有效,尽管它可能不是最优雅的方法:
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 :: Bidirectional模块与你的有向图类包含在一起,这将为你提供所有重要的each_in_neighbor方法。所以这样的事情应该有效(但不是):
require 'rgl/adjacency'
require 'rgl/bidirectional'
class RGL::DirectedAdjacencyGraph
include RGL::BidirectionalGraph
end
dg=RGL::DirectedAdjacencyGraph[1,2 ,2,3 ,2,4, 4,5, 6,4, 1,6]
dg.vertices
#=> [5, 6, 1, 2, 3, 4]
p dg.adjacent_vertices(2)
#=> [3, 4]
p dg.each_in_neighbor(2)
#=> NotImplementedError :(
#=> Should be: [1]
我没有深入研究代码,看看会有多少工作,但根据您的需要,这可能是更好的选择。
编辑:我忘了提到度内节点无法访问源和目标属性。但另一种方法可能是从图中收集所有感兴趣的边缘并比较它们以查看它们中是否有任何感兴趣的节点作为目标。
答案 1 :(得分:2)
RGL :: DirectedAdjacencyGraph 只能有效地实现传出连接。如果您还希望有效访问传入边缘,则应该有效地实现 RGL :: BidirectionalGraph 定义的概念。这应该在您的特定有向图实现中实现方法RGL :: BidirectionalGraph#each_in_neighbor。
假设您在 DirectedAdjacencyGraph 之类的列表中也存储了每个顶点的in-neighbors以用于out-neighbors。然后方法可以这样:
# 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
使用此方法,您必须在插入或删除边和顶点时管理两个顶点字典。
答案 2 :(得分:0)