Преобразование математической задачи в симуляцию дискретного события - PullRequest
3 голосов
/ 27 февраля 2010

Я пытаюсь внедрить эпидемическую модель SIR . По сути, я понимаю модель так, что на каждом временном шаге она говорит нам, сколько узлов заражено и сколько узлов восстановлено. Сейчас я пытаюсь преобразовать это в симуляцию дискретного события, и в какой-то момент я запутался.

Модель обычно решается по методу Эйлера. Теперь, когда я преобразую его в симуляцию дискретного события, я делаю что-то вроде этого (цифры используются для ясности):

Initialize 100 members
At every time step t,
  //Determine how many get infected
  for i = 1 to 100
     let i pass a message to its neighbors
     When the neighbor receives the message from an infected member, it generates a random number and if it is less than beta*(infected/total), where beta is the infection rate, then the member gets infected
     Update the count for infected, recovered, susceptible

  //Determine how many are recovered
  for i = 1 to 100
      Generate a random number from a uniform distribution and check if it is less than gamma*infected. If it is, then this member is recovered.
      Update the count for infected, recovered, susceptible

Мне было интересно, верен ли вышеупомянутый подход. Есть предложения?

Ответы [ 3 ]

4 голосов
/ 27 февраля 2010

Выглядит довольно неплохо для начала, за исключением того, что для первого цикла вы должны помнить, что только восприимчивые люди могут заразиться, а для второго - вылечиться могут только инфицированные люди. Я также считаю, что вероятности перехода по каждому событию (восприимчивое получение сообщения от зараженного соседа, возможно, зараженное выздоровление) не зависит от текущего числа зараженных людей - они постоянны (я думаю, что вы ' вводит в заблуждение вероятности «массового эффекта» применительно к каждому отдельному эпизоду за один шаг времени - они этого не делают).

Немного тоньше то, как вы делаете первый цикл (для меня это не очевидно из модели SIR): я думаю, что вы хотите определить все "сообщения" сначала , , затем , которые одни вызывают переходы восприимчивые -> зараженные - то есть две петли, а не одна - потому что человек, который только что заразился на этом временном шаге, не может заразить других на этом же временном шаге , но только в будущем; Кроме того, переход заражен -> выздоровление невозможен для человека, который только что заразился на этом шаге, поэтому вам придется расположить петли немного по-другому!

Рассмотрите возможность моделирования каждого человека с двумя атрибутами «состояния»:

-- nummsgs, number of "messages" received this time step
-- compartment (susceptible, infected or recovered)

а также фиксированный набор соседей. Тогда:

for each individual:
    if individual.compartment != infected:
        continue
    for each neighbor of the individual:
        neighbor.nummsgs += 1
    if (random number says so):
        individual.compartment = recovered

for each individual:
    if individual.compartment != susceptible:
        continue
    maybe (depending on random number & nummsgs):
        individual.compartment = infected

for each individual:
    individual.nummsgs = 0

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

2 голосов
/ 01 марта 2010

Во-первых, этот подход обычно называется не моделированием дискретных событий, а моделированием по времени. Строго говоря, это не является неправильным, но на практике термин «дискретное событие» используется для моделирования, когда время между событиями является переменным. Например, если каждый зараженный узел будет генерировать сообщение «заражать» случайному соседу один раз в случайное время.

Во-вторых, ваш код пропускает приоритет или вес сообщений. Что, если узел получает и заражает, и восстанавливает сообщения? Должна ли вероятность восстановления быть одинаковой для изолированного узла и узла в середине зараженного большого двоичного объекта? Это привело бы к некоторому дрожанию внутренних узлов между инфицированными и здоровыми состояниями.

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

Наконец, проблема тесно связана со знаменитой «Игрой жизни». Взгляните на различные реализации.

2 голосов
/ 27 февраля 2010

Я вижу здесь как минимум две проблемы, обе из которых связаны с одной и той же первопричиной.

1) Если вы вводите некую структуру соседства, то beta*(infected/total) должно быть просто beta.

2) Линия, в которой gamma*infected яблок только для инфицированных, и вам не нужно gamma*infected - это должно быть просто gamma.

Может быть, есть еще проблемы - трудно сказать по псевдокоду, как есть. Вы можете немного его уточнить, и я посмотрю еще раз.

...