Я пытаюсь разработать структуру данных для следующей ситуации.
Структура графика
Я планирую иметь граф узлов с невзвешенными направленными ребрами: Graph = [Node]
Каждый узел имеет:
- Некоторое внутреннее (постоянное) состояние TBD
- Очередь входящих сообщений
- Тип сообщения, которое он может отправить, определяется функцией, которая принимает текущее состояние узла (с возможностью отказа).
- Список ребер
Node { nodeState :: NodeState, inbox :: Queue NodeMessage, nodeMessage :: (NodeState -> Maybe NodeMessage), connections::[NodeEdge] }
Каждое ребро — это промежуточный этап захвата ожидающих сообщений для целевого узла.
NodeEdge { pendingMessage:: Maybe NodeMessage, targetNode :: Node }
Передача сообщений
Передача сообщений происходит поэтапно и не является параллельной (хотя очереди могут обрабатываться параллельно, чтобы сократить время вычислений).
- Фаза 1: проверьте папку «Входящие» каждого узла, обработайте все сообщения и обновите
NodeState
, если это необходимо. - Фаза 2: Запустите на каждом узле
nodeMessage
, если это приведет кJust NodeMessage
, отправьте NodeMessage на каждое соединение ([NodeEdge]
) - Фаза 3: проверьте каждый край узла, если у него есть сообщение, добавьте его в очередь сообщений целевого узла.
Монат/ST
Мой первоначальный план состоял в том, чтобы присвоить каждому узлу идентификатор (возможно, простой Int) и сохранить каждый узел в узле Map Int. Я раньше не пробовал ST Monad, но подумал, что могу использовать что-то вроде ST s (M.Map Int Node)
. Для любой заданной фазы активность отправки сообщения каждым узлом может быть обработана за O (k log N).
С другой стороны, если бы узлы/ребра могли обновлять изменяемое состояние своих ребер/узлов, то любая отдельная очередь могла бы быть обработана за O(k).
Хотя метод ST/Map кажется довольно интуитивным, возможность изменения всего графа мне не по плечу.
Любые предложения/советы/рекомендуемое чтение?
data NodeEdge f = NodeEdge (Maybe NodeMessage) (f (Node f))
и разрешивf==Identity
для неизменяемых графов иf==STRef s
для изменяемых графов. Но если вас беспокоит производительность, вам следует просто использовать более эффективное представление (что-то вроде списка/матрицы смежности сIntSet
в качестве списка). - person user2407038   schedule 11.09.2014