我试图模仿细菌的生长。比如说,每个物种进行一次反应,将物质A转化为物质B并获得(或失去)能量。
如果我使用少量物质,我可以手动检查无限生成周期(例如A => B => C => A路径具有正能量增益)。如果我使用10种物质,那么事情就会变得复杂。
import numpy as np
import pandas as pd
def add_symmetry(df):
for i in df.index:
for j in df.columns:
if df.loc[i,j]!=0:
df.loc[j,i] = -1*(df.loc[i,j])
return(df)
names = [_ for _ in 'ABCDEFGHJK']
en_df = pd.DataFrame(np.zeros((10,10)), index=names, columns=names)
en_df.loc['A','F'] = 1.9
en_df.loc['F','B'] = 0.8
en_df.loc['B', 'G'] = 4.6
en_df.loc['G','C'] = 1.5
en_df.loc['C','A'] = -9.4
# cycle2
en_df.loc['D','H'] = -5
en_df.loc['H','E'] = 2
en_df.loc['E','J'] = 1.1
en_df.loc['K','E'] = 1.2
en_df.loc['G','H'] = -1
en_df = add_symmetry(en_df)
A B C D E F G H J K
A 0.0 0.0 9.4 0.0 0.0 1.9 0.0 0.0 0.0 0.0
B 0.0 0.0 0.0 0.0 0.0 -0.8 4.6 0.0 0.0 0.0
C -9.4 0.0 0.0 0.0 0.0 0.0 -1.5 0.0 0.0 0.0
D 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -5.0 0.0 0.0
E 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -2.0 1.1 -1.2
F -1.9 0.8 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
G 0.0 -4.6 1.5 0.0 0.0 0.0 0.0 -1.0 0.0 0.0
H 0.0 0.0 0.0 5.0 2.0 0.0 1.0 0.0 0.0 0.0
J 0.0 0.0 0.0 0.0 -1.1 0.0 0.0 0.0 0.0 0.0
K 0.0 0.0 0.0 0.0 1.2 0.0 0.0 0.0 0.0 0.0
这给了我一个对称矩阵,总共45个中有10个反应。我想自动填写其余部分,以便没有正的和周期 E.g:
A=>F is +1.9 energy units
F=>B is +0.8 eu
A => B is (1.9 + 0.8 - 0.1) = 2.6 eu
剩下的等
有没有一种简单的方法可以做到这一点,还是我需要为每个零单元实现最佳路径搜索算法?
答案 0 :(得分:0)
到目前为止,我的解决方案看起来像这样
import copy
import networkx as nx
import numpy as np
import pandas as pd
from collections import deque
def add_symmetry(df):
for i in df.index:
for j in df.columns:
if df.loc[i,j]!=0:
df.loc[j,i] = -1*(df.loc[i,j])
return(df)
def from_pd_df(df):
gr = nx.DiGraph()
for i in df.index:
for j in df.columns:
if df.loc[i, j] != 0:
gr.add_edge(i, j, weight=df.loc[i, j])
return(gr)
def fill_zeros(df):
temp = copy.copy(df)
# Deal only with positive energies
# Substitute maximal path problem with a minimal path one
temp[temp<0] = 0
temp = -1*temp
gr = from_pd_df(temp)
for i in temp.index:
try:
p = nx.bellman_ford(gr, i, weight = 'weight')
except nx.NetworkXUnbounded:
print('{} is involved in an infinite cycle'.format(i))
return(None)
# If a previously implicit path exists, save it ti temp
for j in p[1]:
if df.loc[i,j] == 0:
temp.loc[i,j] = p[1][j]
temp.loc[j, i] = -1*p[1][j]
# Revert back to maximal path problem
temp = -1*temp
# Add reverse reaction
temp = add_symmetry(temp)
return(temp)
>> Define the matrix
en_df = add_symmetry(en_df)
x = fill_zeros(en_df)