在Boost图库中选择随机进出邻居的有效方法?

时间:2017-02-25 14:16:49

标签: c++ boost boost-graph

我需要使用Boost Graph Library从我的图中的给定顶点中选择一个随机的out-neighbor或in-neighbor。我从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是否会在<!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <meta charset="UTF-8"> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&v=3.21.5a&libraries=drawing&signed_in=true&libraries=places,drawing"></script> <style type="text/css"> #map, html, body { padding: 0; margin: 0; height: 90%; } </style> <script type="text/javascript"> function initialize() { map = new google.maps.Map(document.getElementById('map'), { zoom: 5, center: new google.maps.LatLng(41.0257978,21.293566), mapTypeId: google.maps.MapTypeId.SATELLITE, disableDefaultUI: true, zoomControl: false }); var myIcon = new google.maps.MarkerImage('data:image/svg+xml;utf-8, \ <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> \ <path fill="red" stroke="white" stroke-width="1.5" d="M3.5 3.5h25v25h-25z" ></path> \ </svg>', null, null, null, new google.maps.Size(21,30)); google.maps.event.addListener(map, 'click', function(e) { var myLatLng = {lat: e.latLng.lat(), lng: e.latLng.lng()}; var marker = new google.maps.Marker({ position: myLatLng, map: map, icon:myIcon }); }); } google.maps.event.addDomListener(window, 'load', initialize); </script> </head> <body> <div id="map">A</div> </body> </html> 的值<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="90px" height="90px" viewBox="-260 352 90 90" style="enable-background:new -260 352 90 90;" xml:space="preserve"> <style type="text/css"> .st0{fill:#2DB450;} .st1{fill:#FFFFFF;} </style> <g transform="translate(40 -93)"> <circle class="st0" cx="-255" cy="490" r="45"/> <path class="st1" d="M-245.9,492.1h4.2l-13.5-27.1l-13.6,27.1h4.2l-9.4,16.7h13.5v6.2h10.5v-6.2h13.5L-245.9,492.1z M-265.4,490 l10.2-20.3l10.1,20.3H-265.4z M-252.1,512.9h-6.2v-4.1h6.2V512.9z M-270.4,506.7l8.2-14.6h14l8.2,14.6H-270.4z"/> </g> </svg> 处于恒定时间内工作?如果没有,有效的方法吗?

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

2 个答案:

答案 0 :(得分:3)

如果您想确保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返回的迭代器是否是随机访问。

答案 1 :(得分:0)

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

map.removeLayer(base map layer name here);
map.addLayer(bike lane layer name here);

std::advance(ei,i);

现在它在ei+=i; 中的常量时间内进行,用于进出边缘的迭代器。但是,前者在i中需要时间线性。

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