1

我有一个节点网络,每个节点都会影响其他一些节点的状态(想象一个 Excel 电子表格,其单元格值通过公式取决于其他单元格)。

我想知道在 Ruby 中实现这个的最干净的方法是什么?

当然,我可以每个节点有一个进程,但是如果节点数量增加,它将如何执行?而且,我确信有相应的库,但我找不到最新的库。

谢谢你的帮助 !

更新:听起来 EventMachine 可能会完成这项工作......但它似乎更适合少数“节点”

4

3 回答 3

3

对于观察者模式来说,这听起来不错。这是 ruby​​ 中的一个示例:

require 'observer'

class Node
  attr_accessor :id
  @@current_node_id = 0
  def initialize
    @@current_node_id += 1
    id = @@current_node_id
  end
  include Observable

  attr_reader :value


  protected
  def value=(new_value)
    return if @value == new_value
    old_value = @value
    @value = new_value
    changed
    notify_observers(id, old_value, @value)
  end
end


class ValueNode < Node
  def initialize(initial_value)
    super()
    @value = initial_value
  end

  def value=(new_value)
    super(new_value)
  end
end


class SumNode < Node
  def initialize(*nodes)
    super()
    @value = nodes.map(&:value).inject(0, &:+)
    nodes.each do |node|
      node.add_observer(self)
    end
  end


  def update(id, old_value, new_value)
    self.value = self.value - old_value + new_value
  end
end


def test
  v1 = ValueNode.new 4
  v2 = ValueNode.new 8
  sum = SumNode.new(v1, v2)
  sum2 = SumNode.new(v1, sum)
  v2.value = 10
  p sum.value
  p sum2.value
end


test()

请注意,SumNode每次请求时不会重新计算 的值 - 而是在更新其值节点之一时更新它。这以递归方式工作,因此内部SumNodes也触发更新。由于通知包含id节点的唯一性,因此可以编写更复杂Node的类型,例如包含公式的类型。

有关Observable 的更多详细信息,请参见http://www.ruby-doc.org/stdlib/libdoc/observer/rdoc/index.html

于 2011-06-29T12:06:10.393 回答
1

这听起来类似于经常使用的 Twitter 范例,其中一个用户的更新被推送给它的所有追随者。为了有效地做到这一点,你应该为给定的人存储两个列表:一个是他关注的人,一个是关注他的人。您可以对节点列表执行相同的操作。当一个节点发生变化时,您可以快速查找受该节点影响的节点。当关系消失时,您将需要“转发”列表来了解要从哪些列表中“删除”反向关系。

您可以将这些列表存储在二维数组中,或者存储在 Redis 之类的东西中。我真的不明白 EventMachine 将如何适应。

于 2011-06-29T12:09:47.013 回答
0

如果您有依赖关系的网络图并且希望它们可扩展,那么图数据库是最好的解决方案。Neo4J是一种流行的、强大的数据库,用于跟踪此类依赖关系。

有几种方法可以通过 Ruby 与 Neo4J 交互:

  • 您可以使用 JRuby 及其 java 接口。
  • 使用它的 REST API
  • 使用 neo4j.rb 或其他Ruby 接口库之一。
于 2011-06-29T12:31:56.453 回答