c++ - 更改相邻顶点的值并删除自循环

标签 c++ algorithm boost boost-graph

试着写一个Karger’s algorithm与 boost::图表

示例(第一列为顶点,其他为相邻顶点):

  • 1 2 3
  • 2 1 3 4
  • 3 1 2 4
  • 4 2 3

假设我 merge 2比1,我得到结果

  • 1 2 3 2 1 1 3 4
  • 2 1 3 4
  • 3 1 2 4
  • 4 2 3

第一个问题:如何更改顶点 1 的相邻顶点(“2”到“1”)?

我天真的解决方案

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
        }
    }
}

显然,我不能通过这种方式将相邻顶点的值设置为“1”

“change_adjacent_vertices_value”后我想要的结果

  • 1 1 3 1 1 1 3 4
  • 2 1 3 4
  • 3 1 2 4
  • 4 2 3

第二个问题:如何弹出相邻的顶点?

假设我想从顶点1弹出连续的1 我期待的结果

  • 1 1 3 1 3 4
  • 2 1 3 4
  • 3 1 2 4
  • 4 2 3

可以使用像“pop_adjacent_vertex”这样的函数吗?

最佳答案

首先,在大多数情况下,图顶点描述符只是一个整数或指针。这意味着您的代码中的分配不会更改图表。

相反,您应该使用来自可变图概念的 API:http://www.boost.org/doc/libs/1_55_0/libs/graph/doc/MutableGraph.html

在您的情况下,代码可能如下所示:

///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
}

为避免混淆,我建议使用图形,其中在删除边或顶点时顶点和边描述符不会失效。

它导致以下测试示例:

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));;
}

结果:

Before merging 
0 <--> 2 1 
1 <--> 3 0 
2 <--> 0 
3 <--> 1 
After merging 
0 <--> 2 2 
2 <--> 0 3 0 
3 <--> 2 

关于c++ - 更改相邻顶点的值并删除自循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23976339/

相关文章:

c++ - asio 计时器什么时候超出范围?

c++ - 如何在我的 C++ 程序中显示 Windows 的 "DLL not found"错误?

algorithm - 将k个未排序的列表合并为一个并排序,然后将它们分成k个排序的列表?

java - 我们可以通过多少种方式在 6 次传球/投篮中至少得分 6?

c++ - 将 Boost.Spirit.X3 解析器拆分为多个 TU

c++ - boost asio steady_timer 上的多个递归 async_wait

c++ - 如何使用 boost::asio 来抽象文件描述符?

c++ - 将结构 vector 传递给函数

c++ - 拥有一个与其类型同名的成员变量是否合法?

php - 计算文本中的词频?