2 #ifndef ANDRES_GRAPH_MULTICUT_LP_HXX
3 #define ANDRES_GRAPH_MULTICUT_LP_HXX
12 #include "andres/graph/complete-graph.hxx"
13 #include "andres/graph/shortest-paths.hxx"
20 template<
typename RELAX,
typename GRAPH,
typename ECA>
22 std::vector<double>
lp(
const GRAPH& graph,
const ECA& edgeCosts, std::size_t numberOfIterations = std::numeric_limits<std::size_t>::max())
26 bool operator()()
const
32 return lp<RELAX>(graph, edgeCosts, visitor, numberOfIterations);
35 template<
typename RELAX,
typename GRAPH,
typename ECA,
typename VIS>
37 std::vector<double>
lp(
const GRAPH& graph,
const ECA& edgeCosts, VIS& visitor, std::size_t numberOfIterations = std::numeric_limits<std::size_t>::max())
39 const double tolerance = std::numeric_limits<float>::epsilon();
43 std::deque<std::size_t> path;
44 std::vector<double> vars(graph.numberOfEdges());
45 std::vector<double> variables(graph.numberOfEdges());
46 std::vector<double> coefficients(graph.numberOfEdges());
47 std::vector<double> distances(graph.numberOfVertices());
48 std::vector<std::size_t> parents(graph.numberOfVertices());
50 auto addCycleInequalities = [&] ()
52 for (std::size_t i = 0; i < vars.size(); ++i)
53 vars[i] = std::max(.0, lp.variableValue(i));
58 std::size_t counter = 0;
60 for (ptrdiff_t edge = 0; edge < graph.numberOfEdges(); ++edge)
62 auto v0 = graph.vertexOfEdge(edge, 0);
63 auto v1 = graph.vertexOfEdge(edge, 1);
69 if (vars[edge] > distance + tolerance)
72 auto sz = path.size();
74 for (std::size_t j = 0; j < sz - 1; ++j)
76 variables[j] =
static_cast<double>(graph.findEdge(path[j], path[j + 1]).second);
77 coefficients[j] = 1.0;
80 variables[sz-1] =
static_cast<double>(edge);
81 coefficients[sz-1] = -1.0;
83 lp.addConstraint(variables.begin(), variables.begin() + sz, coefficients.begin(), .0, std::numeric_limits<double>::infinity());
92 lp.initModel(graph.numberOfEdges(), edgeCosts.data());
94 for (std::size_t i = 0; numberOfIterations == 0 || i < numberOfIterations; ++i)
101 if (addCycleInequalities() == 0)
105 std::vector<double> edge_values(graph.numberOfEdges());
107 for (
size_t i = 0; i < graph.numberOfEdges(); ++i)
108 edge_values[i] = lp.variableValue(i);
117 #endif // #ifndef ANDRES_GRAPH_MULTICUT_LP_HXX