2 #ifndef ANDRES_GRAPH_MULTICUT_LIFTED_GREEDY_ADDITIVE_HXX
3 #define ANDRES_GRAPH_MULTICUT_LIFTED_GREEDY_ADDITIVE_HXX
12 #include "andres/partition.hxx"
16 namespace multicut_lifted {
19 template<
typename ORIGGRAPH,
typename LIFTGRAPH,
typename EVA,
typename ELA>
21 const ORIGGRAPH& original_graph,
22 const LIFTGRAPH& lifted_graph,
23 EVA
const& edge_values,
28 DynamicGraph(
size_t n)
31 bool edgeExists(
size_t a,
size_t b)
const
33 return !vertices_[a].empty() && vertices_[a].find(b) != vertices_[a].end();
35 std::map<size_t, typename EVA::value_type>
const& getAdjacentVertices(
size_t v)
const
39 typename EVA::value_type getEdgeWeight(
size_t a,
size_t b)
const
41 return vertices_[a].at(b);
43 void removeVertex(
size_t v)
45 for (
auto& p : vertices_[v])
46 vertices_[p.first].erase(v);
50 void setEdgeWeight(
size_t a,
size_t b,
typename EVA::value_type w)
57 std::vector<std::map<size_t, typename EVA::value_type>> vertices_;
61 Edge(
size_t _a,
size_t _b,
typename EVA::value_type _w)
75 typename EVA::value_type w;
77 bool operator <(Edge
const& other)
const
78 {
return w < other.w; }
81 std::vector<std::map<size_t, size_t>> edge_editions(original_graph.numberOfVertices());
82 DynamicGraph original_graph_cp(original_graph.numberOfVertices());
83 DynamicGraph lifted_graph_cp(original_graph.numberOfVertices());
84 std::priority_queue<Edge> Q;
86 for (
size_t i = 0; i < original_graph.numberOfEdges(); ++i) {
87 auto a = original_graph.vertexOfEdge(i, 0);
88 auto b = original_graph.vertexOfEdge(i, 1);
90 original_graph_cp.setEdgeWeight(a, b, 1.);
93 for (
size_t i = 0; i < lifted_graph.numberOfEdges(); ++i) {
94 auto a = lifted_graph.vertexOfEdge(i, 0);
95 auto b = lifted_graph.vertexOfEdge(i, 1);
97 lifted_graph_cp.setEdgeWeight(a, b, edge_values[i]);
99 if (original_graph_cp.edgeExists(a, b)) {
100 auto e = Edge(a, b, edge_values[i]);
101 e.edition = ++edge_editions[e.a][e.b];
107 andres::Partition<size_t> partition(original_graph.numberOfVertices());
113 if (!original_graph_cp.edgeExists(edge.a, edge.b) || edge.edition < edge_editions[edge.a][edge.b])
116 if (edge.w <
typename EVA::value_type())
119 auto stable_vertex = edge.a;
120 auto merge_vertex = edge.b;
122 if (lifted_graph_cp.getAdjacentVertices(stable_vertex).size() < lifted_graph_cp.getAdjacentVertices(merge_vertex).size())
123 std::swap(stable_vertex, merge_vertex);
125 partition.merge(stable_vertex, merge_vertex);
127 for (
auto& p : original_graph_cp.getAdjacentVertices(merge_vertex)) {
128 if (p.first == stable_vertex)
131 original_graph_cp.setEdgeWeight(stable_vertex, p.first, 1.);
134 original_graph_cp.removeVertex(merge_vertex);
136 for (
auto& p : lifted_graph_cp.getAdjacentVertices(merge_vertex)) {
137 if (p.first == stable_vertex)
140 auto t =
typename EVA::value_type();
142 if (lifted_graph_cp.edgeExists(stable_vertex, p.first))
143 t = lifted_graph_cp.getEdgeWeight(stable_vertex, p.first);
145 lifted_graph_cp.setEdgeWeight(stable_vertex, p.first, p.second + t);
147 if (original_graph_cp.edgeExists(stable_vertex, p.first)) {
148 auto e = Edge(stable_vertex, p.first, p.second + t);
149 e.edition = ++edge_editions[e.a][e.b];
155 lifted_graph_cp.removeVertex(merge_vertex);
158 for (
size_t i = 0; i < lifted_graph.numberOfEdges(); ++i)
159 edge_labels[i] = partition.find(lifted_graph.vertexOfEdge(i, 0)) == partition.find(lifted_graph.vertexOfEdge(i, 1)) ? 0 : 1;
166 #endif // #ifndef ANDRES_GRAPH_MULTICUT_LIFTED_GREEDY_ADDITIVE_HXX