当前位置:  开发笔记 > 后端 > 正文

如何在Ruby on Rails中实现无向图?

如何解决《如何在RubyonRails中实现无向图?》经验,为你挑选了1个好方法。

我需要在Ruby on Rails中实现无向图G =(V,E),并考虑构建Vertex has_many EdgesVertexEdge模型.

由于边缘恰好连接两个顶点,您将如何在Rails中强制执行此操作?

你知道任何有助于实现这种图形的宝石或图书馆(对重新发明轮子不感兴趣;-))?



1> vladr..:

不知道任何现有的库在ActiveRecord之上提供图形逻辑.

您可能需要实现自己的顶点,边ActiveRecord的支持模型(见vertex.rbedge.rb在Rails安装的rails/activerecord/test/fixtures目录),如

### From Rails: ###

# This class models an edge in a directed graph.
class Edge < ActiveRecord::Base
  belongs_to :source, :class_name => 'Vertex', :foreign_key => 'source_id'
  belongs_to :sink,   :class_name => 'Vertex', :foreign_key => 'sink_id'
end

# This class models a vertex in a directed graph.
class Vertex < ActiveRecord::Base
  has_many :sink_edges, :class_name => 'Edge', :foreign_key => 'source_id'
  has_many :sinks, :through => :sink_edges

  has_and_belongs_to_many :sources,
    :class_name => 'Vertex', :join_table => 'edges',
    :foreign_key => 'sink_id', :association_foreign_key => 'source_id'
end

为了使上述行为成为一个方向图,考虑在插入边时插入互补边.另请注意,has_and_belongs_to_many现在不鼓励使用,您可以has_many :sources ... :through => :edges改用.任何强制执行可通过验证来完成(即,顶点不具有边缘本身)和/或数据库的约束(在单一性约束/索引[source_id,sink_id]edges确保顶点V1 ---> V2不被一个以上的有向边连接和顶点V1 <--- V2也不是由一个以上的有向边连接.)

此时,您有两个选项,具体取决于图表的大小以及您希望在任何给定时间点遍历的图表数量:

    使用ActiveRecord关系(例如vertex1.edges.first.sink.edges......)在上述模型之上编写应用程序所需的最少量图形逻辑; 这导致对数据库进行大量往返

    进口RGL; 选择从DB到RGL的所有顶点和边,并使用RGL进行图遍历,例如

.

    edges = Edge.find(:all)
    dg = RGL::AdjacencyGraph.new(edges.inject([]) { |adj,edge|
      adj << edge.source_id << edge.sink_id
    })
    # have fun with dg
    # e.g. isolate a subset of vertex id's using dg, then
    # load additional info from the DB for those vertices:
    vertices = Vertex.find(vertex_ids)

上面将SQL语句的总数(在只读操作中)降为2,但如果graph(Edge.find(:all))很大,可能会对数据库或内存造成压力- 此时您可能会想到进一步限制您实际需要的数据量,例如只关心red顶点的连接:

    Edge.find(:all,
              :joins => :sources, # or sinks; indifferent since symmetric
              :conditions => [ 'vertices.red = ?', true ]
    )

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有