【问题标题】:Efficient way to choose random in or out neighbours of a given vertex in Boost Graph Library?在Boost Graph Library中选择给定顶点的随机进出邻居的有效方法?
【发布时间】:2017-02-25 14:16:48
【问题描述】:

我需要使用 Boost Graph Library 从我的图中的给定顶点中选择一个随机的外邻或内邻。我从 RNG 收到索引 i 并且需要选择第 i 个出边(它们可以按任何顺序排列,只需要在调用之间保持一致)。为此,我像这样使用std::advance

typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
Graph g; // Given graph
int i;
int v; // Given vertex
//
// Code to generate random index (guaranteed to be valid) and store it in i
//
typename graph_traits < graph_t >::in_edge_iterator ei, ei_end;
tie(ei,ei_end) = in_edges(v,g);
std::advance(ei,i);
// Now ei points to the ith out edge, and is ready to use
// Return the corresponding in-neighbor
return source(*ei,g);

现在这工作正常,我得到了正确的输出。但是我需要知道这是否有效,即std::advance 会在恒定时间内工作,而不管i 的值如何,因为我使用vecS 来存储邻接列表?如果没有,有没有有效的方法?

我应该提一下,我只需要选择一个随机的内邻居或外邻居,所以如果你有办法在不处理边缘的情况下做到这一点,那也很好。

【问题讨论】:

    标签: c++ boost boost-graph


    【解决方案1】:

    如果你想确保advance(ei. i)o(1),你可以简单地添加一个static_assert

     static_assert( 
         std:::is_base_of<
              std::random_access_iterator_tag,
              typename std:::iterator_traits< decltype(ei) >::iterator_category
         >::value,
         "Not a random access iterator!" )
    

    如果ei 不是随机访问迭代器,这将无法编译。

    至于实际问题,拥有OutEdgeListadjacency_list 中的第一个模板参数)=vecS 足以拥有随机访问out_edges。我相信没有指定in_edges返回的迭代器是否是随机访问的。

    【讨论】:

    • 感谢您的回答。有趣的是,断言对于 both 出边和入边都失败了。考虑到边缘被明确认为是随机访问,这种情况是否应该发生?是否有另一种有效选择随机邻居的方法(不必涉及迭代边缘)?
    • 我刚刚用一个简单的基准确认了两种迭代器都不是随机访问;访问在索引中需要线性时间。即使我尝试 adjacency_iterator 似乎也是如此(断言在那里也失败了)
    • 好吧,out_edgesdocumentation 明确指出,如果您使用 vecS,则返回的迭代器应该是随机访问的......所以现在我很困惑。
    • 我刚刚尝试使用ei+=i 来查看它是否有效,令我惊讶的是它确实有效。另外,进出边缘似乎也是 O(1)。这让我认为迭代器不是基于标准的random_access_iterator,而是内部随机访问。所以断言会失败,因为我们只检查标准类型。会是这样吗?
    【解决方案2】:

    我尝试将迭代器作为指针递增,它可以工作。我换了

    std::advance(ei,i);
    

    ei+=i;
    

    它现在在i 中以恒定时间运行,用于输入和输出边缘迭代器。但是,前者在i 中需要线性时间。

    由于某种原因,尽管我可以像上面那样进行随机访问,但另一个答案中描述的检查迭代器是否随机访问失败。

    【讨论】:

      猜你喜欢
      • 2019-10-20
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      相关资源
      最近更新 更多