У меня есть три списка узлов. источники, раковины и трубы. есть ориентированный взвешенный граф от источников к трубам и стокам. Источники подключаются только к трубам, а трубы только к раковинам. Но источники напрямую не связаны с раковинами. Трубы имеют нулевую сумму, что означает, что сумма весов, приходящих на каждую трубу от источников, равна сумме краев, идущих от этой трубы к раковинам.
Я хотел бы добавить минимальное количество ребер к этому графу от стоков обратно к источникам, чтобы сток и источники также стали нулевыми. Я знаю, что эта проблема np-complete. Мне интересно посмотреть, есть ли какое-нибудь хорошее полиномиальное приближение к этой проблеме, которое сработало бы в реальной жизни.
Проще говоря: у меня есть список стоков и источников. Каждый приемник имеет отрицательное число, а каждый источник имеет положительное число, так что сумма всех чисел в узлах графа равна нулю (пока нет ребер). Я хотел бы добавить минимальное количество ребер к этому графу, чтобы сумма весов ребер, выходящих / входящих в каждый узел, становилась равной количеству на этом узле.
Вот пример кода для проверки, суммирует ли один график другой график:
from functools import reduce
from collections import Counter
source_edges = {
"a0": {"p0": 1, "p2": 5},
"a1": {"p0": 2},
"a2": {"p1": 3}
}
sink_edges = {
"b0": {"p0": 1},
"b1": {"p0": 1, "p1": 1},
"b2": {"p0": 1, "p1": 2, "p2": 5},
}
res = {
"a0": {"b0": 1, "b2": 5},
"a1": {"b1": 2},
"a2": {"b2": 3}
}
sink_degs1 = {k: sum(v.values()) for k, v in sink_edges.items()}
sink_degs2 = dict(reduce(lambda x, y: x + y, (Counter(v) for v in res.values())))
source_degs1 ={k: sum(v.values()) for k, v in res.items()}
source_degs2 ={k: sum(v.values()) for k, v in source_edges.items()}
if sink_degs1 == sink_degs2 and source_degs1 == source_degs2:
print('res summerizes the graph')
else:
print('res does not summerize this graph')
И визуализация этого графика: