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

标签 ruby-on-rails ruby algorithm

我需要在 Ruby on Rails 中实现无向图 G = (V,E) 并考虑构建一个Vertex 和一个Edge 模型,其中Vertex有_多条边

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

您是否知道任何有助于实现此类图表的 gem 或库(对重新发明轮子不感兴趣 ;-))?

最佳答案

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

您可能必须实现自己的 Vertex、Edge ActiveRecord 支持的模型(请参阅 Rails 安装的 rails/activerecord 中的 vertex.rbedge.rb/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 也不由多条有向边连接。)

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

  1. 使用 ActiveRecord 关系(例如 vertex1.edges.first.sink.edges),在上述模型之上编写您的应用程序所需的最少量图形逻辑。 ..);这导致对数据库进行大量往返
  2. 导入RGL;从数据库中选择所有顶点和边到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,但如果图形 (Edge.find(:all) ) 很大——此时您可能会想到进一步的方法来限制您实际需要的数据量,例如只关心 red 顶点的连接:

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

关于ruby-on-rails - 如何在 Ruby on Rails 中实现无向图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/578084/

相关文章:

javascript - 如何使用 webpacker 使 Rails 6 项目中的页面可以访问 javascript 函数?

ruby - 为什么 Ruby 不返回没有 "return"的数组?

ruby-on-rails - 验证具有特定值的动态创建的对象是否存在

ruby-on-rails - 揭秘 Ruby ERB 代码

ruby - Watir Webdriver : Iterating table and storing its content in an array

javascript - 如何将笔记的多个修订合并为一个版本?

java - 你怎么能以最小的时间复杂度找到总和等于 k ​​的最长子集(powerset)的长度?

algorithm - 将整数数组转换为数字,就像位数组一样

ruby-on-rails - 如何按照 json api 规范使用 rswag 创建?

ruby-on-rails - Rails 解决方案记录每个用户操作,以后可以查询