Я создал помеченный график:
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
Item, Link > UnGraph;
Мои ярлыки uint64_t, Я хочу иметь свои собственные идентификаторы на графике.
Если я добавляю узел, все в порядке, у меня есть только узлы с моими метками.
m_g.add_vertex(nodeId, Item(nodeId));
Я хочу проверить, есть ли метка на моем графике:
auto BUnGraph::exists( nid source ) const -> bool
{
if( m_g.vertex(source) == BUnGraph::null_vertex() )
return false;
else
return true;
}
Но метод:
vertex(source)
дает мне ложные результаты и возвращает построенный по умолчанию vertex_descriptor, когда узел не находится на графике вместо null_vertex () в зависимости от метки …
Я выделил метод в Boost:
labeled_graph.hpp
/** @name Find Labeled Vertex */
//@{
// Tag dispatch for sequential maps (i.e., vectors).
template <typename Container, typename Graph, typename Label>
typename graph_traits<Graph>::vertex_descriptor
find_labeled_vertex(Container const& c, Graph const&, Label const& l,
random_access_container_tag)
{ return l < c.size() ? c[l] : graph_traits<Graph>::null_vertex(); }
и проверил внутреннюю карту.
Если я добавлю один узел в график, map.size () == 42. Вместо 1!
Если я добавлю 5 узлов size () == 248.
В зависимости от идентификатора размер карты равен: максимальное значение метки * 2 + 2
Поэтому любой номер метки, уступающий map.size (), даст ложные результаты.
В чем дело ?
РЕДАКТИРОВАТЬ: я поместил метку, как 60000000, на моем графике только один узел. Мой компьютер исчерпал память …
Я нашел строку, ответственную за это:
/**
* Choose the default map instance. If Label is an unsigned integral type
* the we can use a vector to store the information.
*/
template <typename Label, typename Vertex>
struct choose_default_map {
typedef typename mpl::if_<
is_unsigned<Label>,
std::vector<Vertex>,
std::map<Label, Vertex> // TODO: Should use unordered_map?
>::type type;
};
Если тип без знака, поэтому uint8_t, 16, 32, 64 будет использовать вектор. Я не могу найти хороший вариант использования для этого поведения. Это очень опасно.
Итак, единственное решение, которое я нашел, это использовать с этого момента int64_t вместо uint64_t.
Других решений пока нет …