幾乎BGL中的任何圖形算法都需要一個映射:vertex - > int,它爲範圍[0,num_vertices(g))內的每個頂點分配一個唯一的整數。這種映射被稱爲「vertex_index」,通常可以作爲property_map訪問。說到這一點,我可以假設你的頂點已經是整數或者與一些整數相關聯(例如你的unordered_map在「mapped_type」中有一些額外的字段)。如果您的輸入頂點以連續緊密陣列存儲,例如更好(對於性能和內存),例如std :: vector,那麼索引是很自然的。
如果頂點與[整數]相關聯,那麼記憶緊密圖的最佳選擇是「Compressed Sparse Row Graph」。該圖是不可變的,因此您需要在生成圖之前填充邊容器。
正如ravenspoint所解釋的那樣,您最好的選擇是爲每個線程配備其自己的本地容器結果,並僅在將本地結果合併到最終容器時鎖定中央容器。這種策略通過TBB模板tbb::parallel_reduce實現無鎖。所以,你的圖表建設完整的代碼可以看看下面大致爲:
#include "tbb/blocked_range2d.h"
#include "tbb/parallel_reduce.h"
#include "boost/graph/compressed_sparse_row_graph.hpp"
typedef something vertex; //e.g.something is integer giving index of a real data
class EdgeBuilder
{
public:
typedef std::pair<int,int> edge;
typedef std::vector<edge> Edges;
typedef ActualStorage Input;
EdgeBuilder(const Input & input):_input(input){} //OPTIONAL: reserve some space in _edges
EdgeBuilder(EdgeBuilder& parent, tbb::split): _input(parent.input){} // reserve something
void operator()(const const tbb::blocked_range2d<size_t>& r)
{
for(size_t i=r.rows().begin(); i!=r.rows().end(); ++i){
for(size_t j=r.cols().begin(); j!=r.cols().end(); ++j) {
//I assume you provide some function to compute existence
if (my_func_edge_exist(_input,i, j))
m_edges.push_back(edge(i,j));
}
}
}
//merges local results from two TBB threads
void join(EdgeBuilder& rhs)
{
m_edges.insert(m_edges.end(), rhs.m_edges.begin(), rhs.m_edges.end());
}
Edges _edges; //for a given interval of vertices
const Input & _input;
};
//full flow:
boost::compressed_sparse_row_graph<>* build_graph(const Storage & vertices)
{
EdgeBuilder builder(vertices);
tbb::blocked_range2d<size_t,size_t> range(0,vertices.size(), 100, //row grain size
0,vertices.size(), 100); //col grain size
tbb::parallel_reduce(range, builder);
boost::compressed_sparse_row_graph<>
theGraph = new boost::compressed_sparse_row_graph<>
(boost::edges_are_unsorted_multi_pass_t,
builder._edges.begin(), builder._edges.end(),
vertices.size());
return theGraph;
}
AFAIK BGL是,將線程不安全的,如果需要,它的東西可以通過圖書館用戶添加(要付出代價的其他人是太高)。這就是說,如果我記得有一個該庫的並行版本(檢查出來)。預分配是**總是**一件好事(即使不使用線程),但並非嚴格必要,您可以在循環的每次迭代中進行並行處理,然後(同步)將結果放在一起。我無法想象更多沒有任何代碼,但是是的......我想這是可行的。 –
我們不知道你的問題空間,但我的直覺告訴我,優化圖形創建爲'
N可能高達50M,K <50(通常可以是5-10)。我無法想象使它小於'O(N^2)',因爲我需要在兩個字符串上應用一個函數,使得'f:string x string - > unsigned int'。 (圖中的每個節點表示一個字符串)任何提示,像往常一樣,不只是歡迎! – senseiwa