Судя по вашему примеру, каждый узел определяется идентификатором позиции (число перед :
), и два узла с разными присоединенными базами идентичны для целей расчета длины пути.Если это правильно, нет необходимости изменять алгоритм, и вы можете получить свой результат, манипулируя метками вершин.
По сути, отбросьте все после точки с запятой в edge_df
, вычислите самый длинный путь и добавьте основание.метки из ваших исходных данных.
edge_df_pos = pd.DataFrame(
{
"edge1": edge_df.edge1.str.partition(":")[0],
"edge2": edge_df.edge2.str.partition(":")[0],
"weight": edge_df.weight,
}
)
vert_labels = dict()
for col in ("edge1", "edge2"):
verts, lbls = edge_df[col].str.partition(":")[[0, 2]].values.T
for vert, lbl in zip(verts, lbls):
vert_labels.setdefault(vert, set()).add(lbl)
G_pos = nx.from_pandas_edgelist(
edge_df_pos,
source="edge1",
target="edge2",
edge_attr=["weight"],
create_using=nx.OrderedDiGraph(),
)
longest_path_pos = nx.dag_longest_path(G_pos)
longest_path_df = pd.DataFrame([[node, vert_labels[node]] for node in longest_path_pos])
Результат
# 0 1
# 0 115252161 {T}
# 1 115252162 {A, T}
# 2 115252163 {G}
# 3 115252164 {C}
# 4 115252165 {A}
# 5 115252166 {G, C}
# 6 115252167 {A}
# 7 115252168 {A}
# 8 115252169 {A}
Если моя интерпретация неверна, я сомневаюсь, что существует простое расширение алгоритма, основанного на топологической сортировке.Проблема в том, что граф может допускать несколько топологических сортировок.Если вы напечатаете dist
, как определено в dag_longest_path
в вашем примере, вы получите что-то вроде этого:
{'115252161:T': (0, '115252161:T'),
'115252162:A': (1, '115252161:T'),
'115252162:T': (0, '115252162:T'),
'115252163:G': (2, '115252162:A'),
'115252164:C': (3, '115252163:G'),
'115252165:A': (4, '115252164:C'),
'115252166:C': (5, '115252165:A'),
'115252166:G': (5, '115252165:A'),
'115252167:A': (6, '115252166:C'),
'115252168:A': (7, '115252167:A'),
'115252169:A': (8, '115252168:A')}
Обратите внимание, что '115252162:T'
находится в третьей строке и больше нигде.Следовательно, dist
не может провести различие между вашим примером и другим примером, где '115252162:T'
встречается как непересекающийся компонент.Поэтому не должно быть возможности восстановить любые пути через '115252162:T'
, просто используя данные в dist
.