我有一个节点网络,每个节点都会影响其他节点的状态(想象一下Excel电子表格,单元格值取决于其他单元格通过公式)。
我想知道在Ruby中实现这个的最简洁方法是什么?
当然,每个节点可以有一个进程,但如果节点数增加,它将如何执行?而且,我确信有这样的库,但我找不到最新的库。
感谢您的帮助!
更新:听起来像EventMachine可能会完成这项工作......但似乎更适合少数“节点”
答案 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进行交互: