【发布时间】:2011-12-15 00:09:39
【问题描述】:
我正在尝试使用“智能剪刀”来实现交互式图像分割。因此,我必须从每个顶点代表一个像素的图像创建一个有向图。然后每个顶点通过两条边连接到它的每个邻居:一条出边和一条入边。这是因为边缘 (a,b) 的成本可能与 (b,a) 的成本不同。我正在使用大小为 512*512 像素的图像,因此我需要创建一个具有 262144 个顶点和 2091012 个边的图形。目前,我正在使用以下图表:
typedef property<vertex_index_t, int,
property<vertex_distance_t, double,
property<x_t, int,
property<y_t, int
>>>> VertexProperty;
typedef property<edge_weight_t, double> EdgeProperty;
// define MyGraph
typedef adjacency_list<
vecS, // container used for the out-edges (list)
vecS, // container used for the vertices (vector)
directedS, // directed edges (not sure if this is the right choice for incidenceGraph)
VertexProperty,
EdgeProperty
> MyGraph;
我正在使用一个额外的类 Graph(抱歉命名没有灵感):
class Graph
{
private:
MyGraph *graph;
property_map<MyGraph, vertex_index_t>::type indexmap;
property_map<MyGraph, vertex_distance_t>::type distancemap;
property_map<MyGraph, edge_weight_t>::type weightmap;
property_map<MyGraph, x_t>::type xmap;
property_map<MyGraph, y_t>::type ymap;
std::vector<MyGraph::vertex_descriptor> predecessors;
public:
Graph();
~Graph();
};
创建具有 262144 个顶点的新图非常快,但插入边需要 10 秒,这对于所需的应用程序来说太慢了。现在,我通过以下方式插入边缘:
tie(vertexIt, vertexEnd) = vertices(*graph);
for(; vertexIt != vertexEnd; vertexIt++){
vertexID = *vertexIt;
x = vertexID % 512;
y = (vertexID - x) / 512;
xmap[vertexID] = x;
ymap[vertexID] = y;
if(y > 0){
if(x > 0){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y-1)+(x-1)], *graph); // upper left neighbour
}
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y-1)+(x)], *graph); // upper
if(x < 511){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y-1)+(x+1)], *graph); // upper right
}
}
if(x < 511){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y)+(x+1)], *graph); // right
}
if(y < 511){
if(x > 0){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y+1)+(x-1)], *graph); // lower left
}
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y+1)+(x)], *graph); // lower
if(x < 511){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y+1)+(x+1)], *graph); // lower right
}
}
if(x > 0){
tie(edgeID, ok) = add_edge(vertexID, indexmap[IRES2D*(y)+(x-1)], *graph); // left
}
}
我能做些什么来提高程序的速度吗?我在发布模式下使用 Microsoft Visual C++ 2010 Express 并进行了优化(由 Boost 推荐)。我以为我可以为顶点或边使用 listS 容器,但顶点没有问题,如果我将 listS 用于边,它会变得更慢。
【问题讨论】:
标签: performance boost graph boost-graph edges