Try to write a Karger’s algorithm with boost::graph
example (first column is vertice, other are adjacent vertices):
assume I merge 2 to 1, I get the result
first question : How could I change the adjacent vertices("2" to "1") of vertice 1?
my naive solution
template<typename Vertex, typename Graph>
void change_adjacent_vertices_value(Vertex input, Vertex value, Graph &g)
{
for (auto it = boost::adjacent_vertices(input, g);
it.first != it.second; ++it.first){
if(*it.first == value){
*(it.first) = input; //error C2106: '=' : left operand must be l-value
}
}
}
Apparently, I can't set the value of the adjacent vertices to "1" by this way
The result I want after "change_adjacent_vertices_value"
second question : How could I pop out the adjacent vertices?
Assume I want to pop out the consecutive 1 from the vertice 1 The result I expected
any function like "pop_adjacent_vertex" could use?
First of all, in most cases the graph vertex descriptor is simply an integer or a pointer. It means the assignments like in your code would not change the graph.
Instead you should use API from the concept of Mutable Graph: http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/MutableGraph.html
In your case the code can look like:
///adds all edges from src to target and removes the vertex src from the graph
template<typename Vertex, typename Graph>
void merge_vertices(Vertex src, Vertex tgt, Graph &g)
{
for (auto it = boost::out_edges(src, g);
it.first != it.second; ++it.first)
{
Vertex u = target(*it.first,g);
add_edge(u,tgt,g);
//Note, if edges have properties, you should extract and copy them as well
}
clear_vertex(src,g); //removes all edges to/from "src"
remove_vertex(src,g); //removes vertex src itself
}
To avoid confusion I would recommend using graph where vertex and edge descriptors are not invalidated when you remove an edge or vertex.
It leads to the following test example:
typedef boost::adjacency_list<boost::listS,
boost::listS, boost::undirectedS > graph_t;
typedef boost::graph_traits<graph_t>::vertex_descriptor vertex_t;
int main(int, char**)
{
typedef std::map<vertex_t, size_t> IndexMap;
IndexMap mapIndex;
graph_t g;
vertex_t v0 = add_vertex(g);
mapIndex[v0]=0;
vertex_t v1 = add_vertex(g);
mapIndex[v1]=1;
vertex_t v2 = add_vertex(g);
mapIndex[v2]=2;
vertex_t v3 = add_vertex(g);
mapIndex[v3]=3;
add_edge(v0,v2,g);
add_edge(v1,v3,g);
add_edge(v1,v0,g);
std::cout << "Before merging " << std::endl;
boost::print_graph(g, boost::make_assoc_property_map(mapIndex));
merge_vertices(v1,v2,g);
std::cout << "After merging "<< std::endl;
boost::print_graph(g, boost::make_assoc_property_map(mapIndex));;
}
Result:
Before merging
0 <--> 2 1
1 <--> 3 0
2 <--> 0
3 <--> 1
After merging
0 <--> 2 2
2 <--> 0 3 0
3 <--> 2