在 Ruby 中使用 RGL 处理有向图

发布于 2024-08-20 02:46:01 字数 84 浏览 9 评论 0原文

我使用 RGL 在 Ruby 中实现了一个有向图,只是很难弄清楚如何对于给定节点仅查找具有传入连接的节点和具有传出连接的节点。也许我错过了一些简单的事情。

I've implemented a directed graph in Ruby using RGL, just having difficulty figuring out how to, for a given node, find only the nodes with incoming connections and the nodes with outgoing connections. Perhaps I'm missing something simple.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

软糖 2024-08-27 02:46:01

我刚刚遇到这个问题。使用反向方法可能会起作用,尽管它可能不是最优雅的方法:

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::Bi Direction 模块包含在有向图类中,这将为您提供所有重要的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]

我还没有深入研究代码来看看这会需要多少工作,但这可能是一个更好的选择,具体取决于您的需求。

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

I just ran into this problem. Using the reverse method might work, though it might not be the most elegant approach:

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

The longer answer is that it doesn't appear to be implemented yet.

The way it's supposed to work is by including the RGL::Bidirectional module with with your directed graph class, this will give you the all important each_in_neighbor method. So something like this should work (but doesn't):

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]

I haven't dug into the code to see how much work this would be, but that might be a better option depending upon your needs.

Edit: I forgot to mention that the source and target attributes are not accessible to an in-degree node. But an alternate approach could be to collect all the edges of interest from the graph and compare them to see if any of them have your node of interest as a target.

吹梦到西洲 2024-08-27 02:46:01

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

假设您将每个顶点的内邻居也存储在一个列表中,就像 DirectedAdjacencyGraph 为外邻居所做的那样。那么该方法可以是这样的:

# 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::DirectedAdjacencyGraph only implements outgoing connections efficiently. If you also want to have efficient access to the incoming edges you should implement the concept defined by RGL::BidirectionalGraph as efficiently. That should be done implementing the method RGL::BidirectionalGraph#each_in_neighbor in your specific directed graph implementation.

Suppose you store the in-neighbors for each vertex also in a list like DirectedAdjacencyGraph does for the out-neighbors. Then the method could like this:

# 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

Using this approach you have to manage two vertex dictionaries when inserting or removing edges and vertice.

雨后彩虹 2024-08-27 02:46:01

看起来有向边有:

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

这有帮助吗?我不太确定我理解你的问题。

It looks like Directed Edges have:

Attributes
[RW] source
[RW] target

Does that help? I'm not quite sure I understand your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文