最近要做社会网络的社区发现,发现用BGL能减少不少代码量。经过一番调研发现BGL封装的很牛叉,Dijkstra等算法统统具备,奈何自己对泛型编程不太熟,
遇到问题还是很纠结。Primer泛型编程、算法部分和STL源码分析接下来有时间一定要读下。
下面仅以邻接链表和自定义节点为例
typedef adjacency_list<listS,vecS,undirectedS,Node,property<edge_weight_t,int> > Graph;
typedef graph_traits<Graph>::vertex_descriptor VertexDescriptor;
typedef graph_traits<Graph>::edge_descriptor EdgeDescriptor;
typedef graph_traits<Graph>::edge_iterator EdgeIterator;
typedef graph_traits<Graph>::vertex_iterator VertexIterator;
typedef std::pair<Node,Node> Edge;
类型声明。其中Node为自定义类型,property分为内部属性和外部属性,这样声明是内部属性,将随着Graph的生命周期存在,在做社区发现时基本不需要边的权重。
添加边和顶点分两种方式:
1.先添加点,再添加边
Graph g;
for (int i=0; i<vertice_num; ++i)
{
Node onenode;
add_vertex(onenode,g);
}
// 索引属性映射, 可获得顶点的索引属性
property_map<Graph,vertex_index_t>::type index = get(vertex_bundle,g);
// 遍历顶点
pair<VertexIterator,VertexIterator> vrange = vertices(g);
for (VertexIterator Iter=vrange.first; Iter!=vrange.second; ++Iter)
{
cout << index[*Iter] << ". " << g[*Iter].m_sName << endl;
}
// 添加边
VertexIterator Iter=vrange.first;
add_edge(*Iter,*(Iter+2),1,g);
//遍历边
EdgeIterator ei,ei_end;
for (tie(ei,ei_end)=edges(g); ei!=ei_end; ++ei)
{
cout << g[source(*ei,g)].m_sName << "-->" << g[target(*ei,g)].m_sName << endl;
}
2.直接添加边同时就包含了顶点
Graph g(vertice_num);
vector<Node> v_Nodes;
for (int i=0; i<vertice_num; ++i)
{
Node onenode;
onenode.m_sName = "1";
v_Nodes.push_back(onenode);
}
Edge edgearry[] = {Edge(v_Nodes[2],v_Nodes[0]),Edge(v_Nodes[2],v_Nodes[1]),Edge(v_Nodes[2],v_Nodes[3]),Edge(v_Nodes[2],v_Nodes[4]),
Edge(v_Nodes[6],v_Nodes[4]),Edge(v_Nodes[6],v_Nodes[5]),Edge(v_Nodes[6],v_Nodes[7]),Edge(v_Nodes[6],v_Nodes[8]),Edge(v_Nodes[7],v_Nodes[9])};
int edgenum = sizeof(edgearry)/sizeof(edgearry[0] );
for (int i=0; i<edgenum; ++i)
{
add_edge(edgearry[i].first,edgearry[i].second,1,g);
}
//Graph g(edgearry,edgearry+edgenum,vertice_num);
property_map<Graph,vertex_index_t>::type index = get(vertex_bundle,g);
pair<VertexIterator,VertexIterator> vrange = vertices(g);
for (VertexIterator Iter=vrange.first; Iter!=vrange.second; ++Iter)
{
cout << index[*Iter] << ". " << g[*Iter].m_sName << endl;
}
EdgeIterator ei,ei_end;
for (tie(ei,ei_end)=edges(g); ei!=ei_end; ++ei)
{
cout << g[source(*ei,g)].m_sName << "-->" << g[target(*ei,g)].m_sName << endl;
}
其中add_edge(edgearry[i].first,edgearry[i].second,1,g);
自定义类型编译不过去,不懂了,求助大牛啊?
参考资料:
http://www.boost.org/doc/libs/1_51_0/libs/graph/doc/table_of_contents.html
http://blog.csdn.net/jjqtony/article/details/1555965
http://hongel.blog.hexun.com/33672526_d.html