[英]Boost graph library - adjacent_vertices function not found
我正在尝试编写一个算法(贪婪地)找到图的色数。 为此,我需要能够查询给定顶点的相邻顶点。 我的功能如下:
int Network::greedy_colouring() {
// create an undirected graph with the vertices and edges of the first one
UndirectedGraph g;
copy_graph(network, g);
int vertices_amount = num_vertices(g);
// Assign the first color to first vertex
std::map<std::string, int> vertex_colouring;
vertex_pair_iterators vp = vertices(g);
vertex_colouring[g[*vp.first].name] = 0;
++vp.first; // start from second vertex
for (; vp.first != vp.second; ++vp.first)
vertex_colouring[g[*vp.first].name] = -1;
// A temporary array to store the available colors. True
// value of available[cr] would mean that the color cr is
// assigned to one of its adjacent vertices
bool available[vertices_amount];
for (int cr = 0; cr < vertices_amount; cr++)
available[cr] = false;
// Assign colors to remaining V-1 vertices
vp = vertices(g); // reset to beginning
++vp.first; // start from second vertex
for (; vp.first != vp.second; ++vp.first) {
// Process all adjacent vertices and flag their colors
// as unavailable
for (std::pair<adjacency_it, adjacency_it> neighbours = boost::adjacent_vertices(g[*vp.first], g);
neighbours.first != neighbours.second; ++neighbours.first)
if (vertex_colouring[g[*neighbours.first].name] != -1)
available[vertex_colouring[g[*neighbours.first].name]] = true;
// Find the first available color
int cr;
for (cr = 0; cr < vertices_amount; cr++)
if (available[cr] == false)
break;
vertex_colouring[g[*vp.first].name] = cr; // Assign the found color
// Reset the values back to false for the next iteration
neighbours = boost::adjacent_vertices(g[*vp.first], g); // reset to beginning
for (; neighbours.first != neighbours.second; ++neighbours.first)
if (vertex_colouring[g[*neighbours.first].name] != -1)
available[vertex_colouring[g[*neighbours.first].name]] = false;
}
// print the result and find colour number
unsigned colour_number = 0;
for (std::map<std::string, int>::iterator it = vertex_colouring.begin(); it != vertex_colouring.end(); ++it) {
std::cout << "Vertex " << it->first << " ---> Color " << it->second << std::endl;
if (it->second > colour_number)
colour_number = it->second;
}
return colour_number;
}
我得到的错误与调用:
std::pair<adjacency_it, adjacency_it> neighbours = boost::adjacent_vertices(g[*vp.first],g)
这给出了以下编译错误:“错误:没有匹配函数来调用'boost :: adjacency_iterator ...”(部分副本)。 注释掉与函数adjacency相关的代码可以编译,所以我确信这是问题代码。 函数中使用的一些typedef:
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Vertex, Edge > Graph;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge > UndirectedGraph;
typedef std::pair<Vertex ,Vertex > vert_p;
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
typedef boost::graph_traits<Graph>::in_edge_iterator in_edge_it;
typedef boost::graph_traits<Graph>::vertex_iterator vertex_iter;
typedef boost::graph_traits<Graph>::edge_iterator edge_iter;
typedef boost::property_map<Graph, boost::vertex_index_t>::type IndexMap;
typedef std::pair<vertex_iter, vertex_iter> vertex_pair_iterators;
typedef std::pair<in_edge_it, in_edge_it> edge_pair_iterators;
typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_it;
任何人都可以告诉我我做错了什么?
两个问题:
第一个参数需要是顶点描述符,而不是属性包。 更改
boost::adjacent_vertices(g[*vp.first], g)
成
boost::adjacent_vertices(*vp.first, g)
返回类型是std::pair<adjacency_iterator, adjacency_iterator>
。 但是,您将adjacency_iterator
定义为
typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_it;
什么时候需要
typedef boost::graph_traits<UndirectedGraph>::adjacency_iterator adjacency_it;
附加说明:
使用单独的迭代器而不是vp.first
和vp.second
更容易(使用boost::tie
来同时分配两者)
您的比较中有一个“有毒”的无符号值,请将其明确写为
if(it->second > static_cast<int>(colour_number))
或者在地图中查看可能的-1
值的逻辑。
保持由Vertex::name
索引的颜色映射(这是一个字符串)可能效率很低。 您应该考虑使用vertex_descriptor
索引。
现在,由于您的顶点模型使用vecS
作为VertexContainer,您实际上可以使用此描述符是[0, num_vertices(g))
范围内的整数索引这一事实。
因此,您可以使用vector<int>
(其中顶点描述符是矢量索引)替换map <>(具有错误的内存局部性)。
如果要支持其他图形模型,可以让调用者传入将顶点描述符映射到类似连续索引的
IndexMap
。 BGL中的许多算法都使用这种方法。
显然, bool[]
可能(应该)是std::bitset
甚至是std::vector<bool>
。 Boost有dynamic_bitset
,这可能是最好的。
(我需要更好地理解你的算法。也许一组“采取”的颜色会更好。并且实现为一个未分类的连续速度集合,除非你预期颜色的数量要足够大以至于有序/ hash lookup会更快(?!)。
始终使您的代码自包含:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <iostream>
struct Vertex {
std::string name;
};
struct Edge {
};
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, Vertex, Edge > Graph;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge > UndirectedGraph;
Graph network;
int greedy_colouring() {
using namespace boost;
typedef boost::graph_traits<UndirectedGraph>::vertex_descriptor vertex_descriptor;
static_assert(is_integral<vertex_descriptor>::value, "IndexMap not provided yet TODO");
typedef boost::graph_traits<UndirectedGraph>::vertex_iterator vertex_iter;
typedef boost::graph_traits<UndirectedGraph>::adjacency_iterator adjacency_it;
// create an undirected graph with the vertices and edges of the first one
UndirectedGraph g;
copy_graph(network, g);
vertex_iter vit, vend;
tie(vit, vend) = vertices(g);
size_t const vertices_amount = num_vertices(g);
std::vector<int> vertex_colouring(vertices_amount, -1);
vertex_colouring[*vit] = 0; // Assign the first color to first vertex
// A temporary array to store the available colors.
// - available[cr]: assigned to one of its adjacent vertices
std::vector<bool> available(vertices_amount, false);
for (++vit; vit!=vend; ++vit)
{
// Process all adjacent vertices and flag their colors as unavailable
adjacency_it neighbour, neighbour_end;
for (tie(neighbour, neighbour_end) = adjacent_vertices(*vit, g); neighbour != neighbour_end; ++neighbour)
if (vertex_colouring[*neighbour] != -1)
available[vertex_colouring[*neighbour]] = true;
// Find the first available color
vertex_colouring[*vit] = distance(available.begin(), std::find(available.begin(), available.end(), false));
// Reset the values back to false for the next iteration
for (tie(neighbour, neighbour_end) = adjacent_vertices(*vit, g); neighbour != neighbour_end; ++neighbour)
if (vertex_colouring[*neighbour] != -1)
available[vertex_colouring[*neighbour]] = false;
}
// print the result and find colour number
for (vertex_descriptor v = 0; v < vertices_amount; ++v)
std::cout << "Vertex " << v << " ---> Color " << vertex_colouring[v] << std::endl;
return *std::max_element(vertex_colouring.begin(), vertex_colouring.end());
}
int main() { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.