Мин-стоимость-макс-поток с boost :: successive_shortest_path_nonnegative_weights

Мне нужно рассчитать минимальную стоимость-максимальный поток для потоковой сети, используя

boost::successive_shortest_path_nonnegative_weights()

функция доступна в BGL (v 1_60_0). Как указано в документации,

ориентированный граф G = (V, E), представляющий сеть, должен быть расширен, чтобы включить обратное ребро для каждого ребра в E. То есть входной граф должен иметь вид Gin = (V, {E U ET}). [...] Ограничение аргумента CapacityEdgeMap должно отображать каждое ребро в E в положительное число, а каждое ребро в ET в 0. WeightMap должен отображать каждое ребро из E в неотрицательное число, а каждое ребро из ET в -вес его перевернутый край.

У меня есть простая функция, которая для каждого ребра, добавленного к графику, добавляет обратное ребро с емкостью и весом, как указано выше:

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.

Что я делаю неправильно?


person Filippo    schedule 02.03.2016    source источник
comment
Повозившись, я обнаружил, что у меня такая же ошибка, даже если я не добавляю обратные ребра, то есть граф не имеет отрицательных весов.   -  person Filippo    schedule 02.03.2016


Ответы (1)


Просто столкнулся с той же проблемой. Через несколько минут отладки я обнаружил проблему. Я использую плавающий тип для весов. Из-за этого модифицированный вес ребра (версия dijkstra для отрицательных весов) может стать немного ниже 0 для числовой ошибки. Возможное решение - переписать "successive_shortest_path_nonnegative_weights.hpp", чтобы округлить небольшие отрицательные значения.

person Dmitry    schedule 06.12.2016