Мне нужно рассчитать min-cost-max-flow для сети потоков, используя
boost::successive_shortest_path_nonnegative_weights()
функция доступна в BGL (v 1_60_0).
Как указано в документация,
направленный граф G = (V, E), представляющий сеть, должен быть расширен, чтобы включить обратное ребро для каждого ребра в E. То есть входной граф должен быть Gin = (V, {E U ET}). […] Cap аргумента CapacityEdgeMap должен отобразить каждое ребро в E на положительное число, а каждое ребро в ET на 0. WeightMap должен отобразить каждое ребро от E до неотрицательного числа, а каждое ребро от ET до -weight от его перевернутый край.
У меня есть простая функция, которая для каждого ребра, добавленного к графику, добавляет обратное ребро с емкостью и весом, как указано выше:
void add_edge_and_reverse(vertex_desc& source, vertex_desc& target, Edge& edge, flow_network_t& fn, boost::associative_property_map<std::map<edge_desc, edge_desc>>& rev_map)
{
std::pair<edge_desc, bool> e = boost::add_edge(source, target, edge, fn);
Edge reverse_edge(-edge.cost, 0);
std::pair<edge_desc, bool> e_rev = boost::add_edge(target, source, reverse_edge, fn);
rev_map[e.first] = e_rev.first;
rev_map[e_rev.first] = e.first;
}
Теперь граф содержит обратные ребра, и они имеют отрицательные веса, что явно отличается от названия алгоритма, который я использую.
В результате, когда я выполняю алгоритм, я получаю эту ошибку:
ValueError: The graph may not contain an edge with negative weight.
Что я делаю неправильно?
Просто столкнулся с той же проблемой. После нескольких минут отладки я обнаружил проблему. Я использую тип поплавка для весов. Из-за этого модифицированный вес ребра (версия dijkstra для отрицательных весов) может стать немного ниже 0 для числовой ошибки.
Возможное решение может быть переписать «successive_shortest_path_nonnegative_weights.hpp», чтобы оно округляло небольшие отрицательные значения
Других решений пока нет …