2 #ifndef ANDRES_GRAPH_MULTICUT_GREEDY_ADDITIVE_HXX
3 #define ANDRES_GRAPH_MULTICUT_GREEDY_ADDITIVE_HXX
12 #include "andres/partition.hxx"
21 template<
typename GRAPH,
typename EVA,
typename ELA>
24 EVA
const& edge_values,
31 DynamicGraph(
size_t n) :
35 bool edgeExists(
size_t a,
size_t b)
const
37 return !vertices_[a].empty() && vertices_[a].find(b) != vertices_[a].end();
40 std::map<size_t, typename EVA::value_type>
const& getAdjacentVertices(
size_t v)
const
45 typename EVA::value_type getEdgeWeight(
size_t a,
size_t b)
const
47 return vertices_[a].at(b);
50 void removeVertex(
size_t v)
52 for (
auto& p : vertices_[v])
53 vertices_[p.first].erase(v);
58 void updateEdgeWeight(
size_t a,
size_t b,
typename EVA::value_type w)
65 std::vector<std::map<size_t, typename EVA::value_type>> vertices_;
70 Edge(
size_t _a,
size_t _b,
typename EVA::value_type _w)
84 typename EVA::value_type w;
86 bool operator <(Edge
const& other)
const
92 std::vector<std::map<size_t, size_t>> edge_editions(graph.numberOfVertices());
93 DynamicGraph original_graph_cp(graph.numberOfVertices());
94 std::priority_queue<Edge> Q;
96 for (
size_t i = 0; i < graph.numberOfEdges(); ++i)
98 auto a = graph.vertexOfEdge(i, 0);
99 auto b = graph.vertexOfEdge(i, 1);
101 original_graph_cp.updateEdgeWeight(a, b, edge_values[i]);
103 auto e = Edge(a, b, edge_values[i]);
104 e.edition = ++edge_editions[e.a][e.b];
109 andres::Partition<size_t> partition(graph.numberOfVertices());
116 if (!original_graph_cp.edgeExists(edge.a, edge.b) || edge.edition < edge_editions[edge.a][edge.b])
119 if (edge.w <
typename EVA::value_type())
122 auto stable_vertex = edge.a;
123 auto merge_vertex = edge.b;
125 if (original_graph_cp.getAdjacentVertices(stable_vertex).size() < original_graph_cp.getAdjacentVertices(merge_vertex).size())
126 std::swap(stable_vertex, merge_vertex);
128 partition.merge(stable_vertex, merge_vertex);
130 for (
auto& p : original_graph_cp.getAdjacentVertices(merge_vertex))
132 if (p.first == stable_vertex)
135 original_graph_cp.updateEdgeWeight(stable_vertex, p.first, p.second);
137 auto e = Edge(stable_vertex, p.first, original_graph_cp.getEdgeWeight(stable_vertex, p.first));
138 e.edition = ++edge_editions[e.a][e.b];
143 original_graph_cp.removeVertex(merge_vertex);
146 for (
size_t i = 0; i < graph.numberOfEdges(); ++i)
147 edge_labels[i] = partition.find(graph.vertexOfEdge(i, 0)) == partition.find(graph.vertexOfEdge(i, 1)) ? 0 : 1;
154 #endif // #ifndef ANDRES_GRAPH_MULTICUT_GREEDY_ADDITIVE_HXX