在Ruby中编写“类似Excel”的影响力网络的最佳方法?

时间:2011-06-29 08:32:06

标签: ruby artificial-intelligence artificial-life

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

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

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

感谢您的帮助!

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

3 个答案:

答案 0 :(得分:3)

这听起来像观察者模式的好情况。这是红宝石中的一个样本:

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

答案 1 :(得分:1)

这听起来类似于经常使用的Twitter范例,其中一个用户的更新被推送给所有它的粉丝。要有效地执行此操作,您应该为给定的人存储两个列表:一个列出他跟随的人,另一个列出跟随他的人。您可以对节点列表执行相同操作。当节点更改时,您可以快速查找受此节点影响的节点。当一段关系消失时,你需要前进&#39;列表以了解从哪些列表中删除&#39;相反的关系。

您可以存储这些列表二维数组,或者像Redis一样存储。我不太了解EventMachine如何适应。

答案 2 :(得分:0)

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

有几种方法可以与Ruby的Neo4J进行交互: