Установить начальный узел для распространения вируса в сети

Я работаю над поиском влиятельных узлов в сложных сетях с использованием R-программирования. Я хочу использовать степень центральности, которая означает количество соседей, которое имеет узел в графе. У меня есть график и степень централизации каждого узла. Теперь я хочу знать, сколько узлов будет заражено за указанное время, когда мы начнем распространять вирус с каждого узла. согласно моим исследованиям, я должен использовать эпидемическую модель SIR(восприимчивый, зараженный, выздоровевший), которую я нашел в пакете "igraph", проблема в том, что я не могу указать начальный узел. Кажется, что эта функция работает на основе уравнений SIR:

s'= -(beta)SI
I' = (beta)SI - (gamma)I
R' = (gamma)I

где бета - параметр заражения, а гамма - параметр восстановления. вот код SIR igraph:

function (graph, beta, gamma, no.sim = 100) 
{
if (!is_igraph(graph)) {
    stop("Not a graph object")
}
beta <- as.numeric(beta)
gamma <- as.numeric(gamma)
no.sim <- as.integer(no.sim)
on.exit(.Call("R_igraph_finalizer", PACKAGE = "igraph"))
res <- .Call("R_igraph_sir", graph, beta, gamma, no.sim, 
    PACKAGE = "igraph")
class(res) <- "sir"
res
}

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

1 ответ

Решение

Похоже, что вы хотели бы иметь модель SIR, в которой вы можете установить изначально зараженный узел, установив обезьяны с помощью существующего кода R. Поскольку пакет R скомпилирован из кода C, это может быть сложно, в зависимости от вашего опыта программирования, и в общем случае не рекомендуется использовать monkeypatching, иначе ничего, потому что вы потеряете свой код в момент обновления вашего igraph пакет.

Вместо этого вы можете относительно легко реализовать это самостоятельно, используя igraph пакет. Ниже приведена непроверенная реализация в python, которую следует легко перенести на R.

Первый шаг заражает любой узел в графе, смежный с зараженным узлом, с вероятностью beta

После стадии заражения любой зараженный узел может быть удален с графа с вероятностью gamma

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

infected_nodes = []
# Set the infection rate
beta = 0.1
# Set the removal rate
gamma = 0.1
# Set how many timesteps you want to pass through
n_timesteps = 100
# Start from the node you have chosen using edge centrality
infected_nodes.append(chosen_node)
for _ in n_timesteps:
    # Infection stage
    for node in infected_nodes:
        for neighbor in igraph.neighborhood(graph, node):
            # random.random simply returns a number between [0,1)
            if random.random() < beta:
                infected_nodes.append(neighbor)
    # Removal stage
    infected_survivors = []
    for node in infected_nodes:
        if random.random() < gamma:
            graph = igraph.delete_vertices(graph, node)
        else:
            infected_survivors.append(node)
    infected_nodes = infected_survivors

Некоторые абердабеи:

  • Это предполагает, что каждый узел посещает всех своих соседей на каждом временном шаге. Если вы хотите, чтобы каждый узел мог заражать n Соседи за ход вам нужно будет взять размер n случайная выборка соседей вместо итерации по всем из них.
  • На этапе удаления можно удалить вновь зараженные узлы, что означает, что существует вероятность того, что узел не сможет заразить своих соседей. Если это нереально в вашем случае, вам придется хранить вновь зараженные узлы в отдельном массиве и добавлять их к зараженным узлам в начале стадии заражения.
  • Это, очевидно, будет медленнее, чем реализация C, предоставляемая пакетом R
Другие вопросы по тегам