сделать большой процесс на графе с параллельным Python - PullRequest
1 голос
/ 24 октября 2019

Я работаю над графиками и большим набором данных сложных сетей. я запускаю алгоритм SIR на них с библиотекой ndlib. но каждая итерация занимает что-то вроде 1Sec, а выполнение кода занимает 10-12 часов. мне было интересно, есть ли способ сделать его распараллеленным? код как внизу

эта строка кода является основной:

sir = model.infected_SIR_MODEL(it, infectionList, False)

Есть ли какой-нибудь простой способ заставить его работать в многопоточном или распараллеленном режиме?

count = 500
for i in numpy.arange(1, count, 1):

    for it in model.get_nodes():

        sir = model.infected_SIR_MODEL(it, infectionList, False)

каждая итерация:

 for u in self.graph.nodes():

            u_status = self.status[u]
            eventp = np.random.random_sample()
            neighbors = self.graph.neighbors(u)
            if isinstance(self.graph, nx.DiGraph):
                neighbors = self.graph.predecessors(u)

            if u_status == 0:
                infected_neighbors = len([v for v in neighbors if self.status[v] == 1])
                if eventp < self.BetaList[u] * infected_neighbors:
                    actual_status[u] = 1
            elif u_status == 1:
                if eventp < self.params['model']['gamma']:
                    actual_status[u] = 2

1 Ответ

2 голосов
/ 24 октября 2019

Итак, если итерации независимы, то я не вижу смысла итерации по count=500. В любом случае вам может быть интересна многопроцессорная библиотека .

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

import multiprocessing as mp


# if everything is independent (eg. "infectionList" is static and does not change during the iterations)

def worker(model, infectionList):
    sirs = []
    for it in model.get_nodes():
        sir = model.infected_SIR_MODEL(it, infectionList, False)
        sirs.append(sir)
    return sirs

count = 500
infectionList = []
model = "YOUR MODEL INSTANCE"

data = [(model, infectionList) for _ in range(1, count+1)]
with mp.Pool() as pool:
    results = pool.starmap(worker, data)

Второе предлагаемое решение, если в каждой итерации обновляется «fectionList »или что-то еще«i»:

def worker2(model, it, infectionList):
    sir = model.infected_SIR_MODEL(it, infectionList, False)
    return sir

with mp.Pool() as pool:
    for i in range(1, count+1):
        data = [(model, it, infectionList) for it in model.get_nodes()]
        results = pool.starmap(worker2, data)

        # process results, update something go to next iteration....

Изменить: Обновлен ответ для более четкого разделения предложений.

...