Я пытался научить себя оптимизировать python и, возможно, распараллелить мою проблему. Ссылки, которые я использовал, перечислены в моем вопросе на http://www.python -forum.org / pythonforum / viewtopic.php? F = 18 & t = 28855
Однако мое приложение, основанное на модуле networkx, по-прежнему очень плохо масштабируется с размером сети, что, я думаю, является в основном ошибкой моих петель, а не специфичной для networkx. Имея небольшой опыт и сосредоточенность на выполнении этой единственной работы, я был бы очень признателен, если бы вы могли просмотреть мой код и точно определить, как вместо этого должны быть сформулированы циклы или какой-то другой прием. Подойдет любой краткий комментарий, я постараюсь взять его оттуда.
Вот ключевые и грязные вещи, которые, как я ожидаю, станут узкими местами:
Эта часть проецирует двудольный граф двудольного (двудольного) графа в соседа по клетке.
# Dictionary for edge attributes in projected graph:
# 0: overlap_length
# 1: overlap_start
# 2: overlap_end
# 3: cell
# 4: level
def time_overlap_projected_graph_parallel(B, nodes):
G=nx.MultiGraph()
G.add_nodes_from((n,B.node[n]) for n in nodes)
for u in nodes:
unbrs = set(B[u])
nbrs2 = set((n for nbr in unbrs for n in B[nbr])) - set([u])
for v in nbrs2:
for mutual_cell in set(B[u]) & set(B[v]):
for uspell in B.get_edge_data(u,mutual_cell).values():
ustart = uspell[1]
uend = uspell[2]
for vspell in B.get_edge_data(v,mutual_cell).values():
vstart = vspell[1]
vend = vspell[2]
if uend > vstart and vend > ustart:
ostart = max(ustart,vstart)
oend = min(uend,vend)
olen = (oend-ostart+1)/86400
ocell = mutual_cell
if (v not in G[u] or ostart not in [ edict[1] for edict in G[u][v].values() ]):
G.add_edges_from([(u,v,{0: olen,1: ostart,2: oend,3: ocell})])
return G
Эта часть проясняет предыдущий результат путем объединения нескольких связей (заклинаний в одной ячейке) между одними и теми же людьми.
# Dictionary for edge attributes in consolidated graph:
# 5: total_overlap
# 6: first_overlap
# 7: last_overlap
# 8: cell_list
# 9: spell_list
def consolidated_g_parallel(B):
G = nx.Graph()
G.add_nodes_from(B)
for n in B.nodes_iter():
for m in B.neighbors_iter(n):
omin = 2000000000.0
omax = 0.0
otot = 0.0
cells = []
spells = []
for ed in B.get_edge_data(m,n).values():
omin = min(omin,ed[1])
omax = max(omax,ed[2])
otot += ed[0]
cells.append(ed[3])
spells.append((ed[1],ed[2]))
G.add_edges_from([(n,m,{5: otot,6: omin,7: omax,8: cells,9: spells})])
return G
При этом создается новый граф, в котором все ссылки более высокого порядка (скажем, сокамерники по соседству, по крайней мере, до порядка, установленного параметром) предыдущего результата становятся прямыми ссылками, которые требуют некоторой грубой работы из-за важная хронология ссылок.
def consolidated_mdg_parallel(B):
print('number of self-loops',B.number_of_selfloops())
G = B.to_directed()
for u,v,d in G.edges(data=True):
d[4]=1
for n in G.nodes_iter():
sinks = nx.algorithms.boundary.node_boundary(B,[n])
nsink = list(sinks)
nsink.append(n)
sources = nx.algorithms.boundary.node_boundary(B,nsink)
while len(sinks) > 0 and len(sources) > 0 :
for u in sources:
for v in nx.algorithms.boundary.node_boundary(B,[u],sinks):
for edata in G[u][v].values():
for ed in G[v][n].values():
if edata[1] <= ed[2]:
oend = min(edata[2],ed[2])
ostart = max(edata[1],ed[1])
otot = min(ed[0],edata[0])
lvl = edata[4] + 1
G.add_edges_from([(u,n,{0: otot,1: ostart,2: oend,3: {},4: lvl})])
nsink.extend(sources)
sinks = list(set(sources)&set(G.predecessors(n)))
sources = nx.algorithms.boundary.node_boundary(B,nsink)
H = nx.MultiDiGraph()
for n in G.nodes_iter():
for m in G.neighbors_iter(n):
omin = 2000000000.0
omax = 0.0
otot = 0.0
for lvl in range(1,maxorder):
for ed in G.get_edge_data(n,m).values():
if ed[4] == lvl:
otot += ed[0]
if otot > 0:
H.add_edges_from([(n,m,{0: otot,4: lvl})])
otot = 0.0
# print('Higher-order link added!')
return H
Эта часть (конечно, не функция) записывает отдельные текстовые файлы для каждого из возможных порядков ссылок с перечисленными краями.
empty = ['nothing']
for i in range(1,maxorder):
empty.append(set(J.nodes()))
# Write simple adjacency representation for spmat --- note losing track of length of spells and chronology!
for i in range(1,maxorder):
targets[i].write('0 '+str(J.number_of_nodes())+' SHAPE KEY')
for e in J.edges_iter(data=True):
# (u,n,{0: otot,1: ostart,2: oend,3: {},4: lvl})
print(e)
if e[2][4] < maxorder:
targets[e[2][4]].write('\n{} {} {}'.format(str(e[1]),str(e[0]),str(1/e[2][0])))
try:
empty[e[2][4]].remove(e[1])
except:
pass
for i in range(1,maxorder):
for n in list(empty[i]):
targets[i].write('\n'+str(n))
targets[i].close()