提升标记图,错误的内部地图大小

时间:2012-12-07 14:17:04

标签: c++ boost boost-graph

我创建了一个带标签的图表:

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
Item, Link > UnGraph;

我的标签是 uint64_t ,我想在图表上有自己的ID。

如果我添加一个节点,一切都很好,我只有带有我的标签的节点。

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)

给出了错误的结果,当节点不在图形中而不是null_vertex()时,返回一个默认构造的vertex_descriptor,具体取决于标签...

我在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。

根据ID,地图大小等于:最大标签值* 2 + 2 因此,任何低于map.size()的标签号都会给出错误的结果。

发生了什么事?

编辑:我在我的图表中放了一个像60000000的标签,只有一个节点。我的电脑内存不足......

1 个答案:

答案 0 :(得分:3)

我找到了这条线的责任:

/**
 * 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。