Лучший способ запрограммировать "Ruby-подобную" сеть влияния в Ruby? - PullRequest
1 голос
/ 29 июня 2011

У меня есть сеть узлов, каждый узел влияет на состояние некоторых других узлов (представьте электронную таблицу Excel со значениями ячеек, зависящими от других ячеек с помощью формул).

Мне интересно, какой самый чистый способреализовать это в Ruby?

Конечно, у меня может быть один процесс на узел, но как он будет работать, если число узлов увеличится?И я уверен, что для этого есть библиотеки, но я не могу найти новейшую.

Спасибо за вашу помощь!

Обновление: Похоже, что EventMachine может подойтиработа ... но она кажется более приспособленной к небольшому количеству "узлов"

Ответы [ 3 ]

3 голосов
/ 29 июня 2011

Звучит как хорошая ситуация для наблюдателя.Вот пример этого в 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 типы, например, содержащие формулы.

См. http://www.ruby -doc.org / stdlib / libdoc / наблюдатель / rdoc / index.html для получения дополнительной информации о Observable

1 голос
/ 29 июня 2011

Это похоже на часто используемую парадигму Twitter, где обновления одного пользователя рассылаются всем его подписчикам. Чтобы сделать это эффективно, вы должны хранить два списка для данного человека: один с людьми, за которыми он следует, и один с людьми, которые следуют за ним. Вы можете сделать то же самое для списка узлов. Когда узел изменяется, вы можете быстро найти узлы, на которые влияет этот узел. Когда связь исчезнет, ​​вам понадобится «прямой» список, чтобы узнать, из каких списков «удалить» обратную связь.

Вы можете хранить в этих списках двумерные массивы или что-то вроде Redis. Я не очень понимаю, как вписывается EventMachine.

0 голосов
/ 29 июня 2011

Если у вас есть сетевой график зависимостей, и вы хотите, чтобы они масштабировались, лучше всего будет использовать базу данных графиков. Neo4J - это популярная и мощная база данных для отслеживания этого типа зависимостей.

Существует несколько способов взаимодействия с Neo4J из Ruby:

  • Вы можете использовать JRubyи его интерфейс Java.
  • Используйте его REST API
  • Используйте neo4j.rb или одну из других библиотек интерфейса Ruby .
...