Работа с большим графиком networkx и веб-сервером Flask - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь создать веб-приложение Flask, которое может запрашивать график NetworkX, чтобы возвращать кратчайшие пути (используя алгоритм Дейкстры, плюс алгоритм Йена для k-кратчайших путей).

Вот мойпример кода (без обработки ошибок и т. д. и только показ реализации Dijkstra), который возвращает путь, если вы отправляете запрос GET на localhost:3000/d?source=a&target=b:

import csv
import json
import networkx as nx
from flask import Flask, request

app = Flask(__name__)
G = nx.Graph()

@app.route('/d')
def dijkstra():

  global G

  source = request.args['source'].lower().strip()
  target = request.args['target'].lower().strip()

  path = nx.dijkstra_path(G, source, target, weight='weight')

  return json.dumps(path)


if __name__ == '__main__':

  global G

  with open('nodes.csv', 'rb') as f:
    reader = csv.reader(f)
    node_list = list(reader)

  for i in nodes:
    G.add_node(i[0])

  with open('edges.csv', 'rb') as f:
    reader = csv.reader(f)
    edge_list = list(reader)

  for i in edges:
    G.add_edge(i[0], i[1], weight=i[2])

  app.run(host='0.0.0.0', port=3000, use_reloader=False)

График очень большой (один миллион узлов, двадцать миллионов ребер), поэтому в настоящее время я заполняю его из CSV при загрузке приложения, а не собираю его для каждого запроса.Это займет около пяти минут при локальном запуске на моем MacBook Pro (3 ГГц, 16 ГБ ОЗУ).Поиск занимает различное количество времени, но обычно составляет около пятнадцати секунд, а производительность, как правило, снижается после определенного использования, то есть мне приходится перезапускать приложение.

Вопрос первый: медленно и довольно много памяти, есть ли способ сохранить этот график, чтобы мне не приходилось каждый раз генерировать его, а затем держать его в памяти?

Вопрос второй: Яподходить к нему правильно, используя G в качестве глобальной переменной?

Я не работал с такими большими графами раньше, поэтому я знаю, что моя реализация, вероятно, далека от идеальной, и был бы благодарен за любыемысли о том, как сделать это лучше / надежнее!

1 Ответ

0 голосов
/ 11 мая 2018

Вы пытались использовать кэши, доступные на Маркете?

Создать фоновый скрипт, который обновляет эти кэши или соленья, и ваш запрос только загружает и отправляет данные внутри него.

РЕДАКТИРОВАТЬ Как OP также нашел метод Builtin Pickles для NetworkX введите здесь описание ссылки

Чтобы сравнить скорость травления и непосредственное отношение к CSV Проверьте эту ссылку

Редактировать 2 Когда вы выбираете всю структуру данных, вы ограничены системной оперативной памятью.Однако вы можете сделать это порциями.

streaming-pickle может быть решением для травления объектов, размер которых превышает объем памяти на борту.Поскольку проблемы возникают при удалении ресурсов, но вы можете использовать этот подход и для преодоления этого.

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

Это один большой адский вопрос: D зависит от того, что вам действительно нужно.

...