"堆已损坏"当使用boost :: boykov_kolmogorov_max_flow

时间:2016-06-10 12:36:08

标签: c++ boost boost-graph heap-corruption

我正在尝试使用Boost implementation of Boykov-Kolmogorov max-flow algorithm

我是这样做的:

typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS,
boost::no_property,
boost::property<boost::edge_index_t, std::size_t> > GraphType;

typedef boost::graph_traits<GraphType>::vertex_descriptor VertexDescriptor;
typedef boost::graph_traits<GraphType>::edge_descriptor EdgeDescriptor;
typedef boost::graph_traits<GraphType>::vertices_size_type VertexIndex;
typedef boost::graph_traits<GraphType>::edges_size_type EdgeIndex;

int numberOfVertices; //The number of vertices in my graph
std::vector<std::set<int>> neighbours(numberOfVertices);

// I fill the neighbours vector with information about neighbouring vertices

int sourceId = numberOfVertices;
int sinkId = sourceId + 1;

std::size_t size = 0;
for (int i = 0; i < neighbours.size(); i++) {
    size += neighbours[i].size();
}


std::vector<float> sourceWeights(numberOfVertices);
std::vector<float> sinkWeights(numberOfVertices);

for (int i = 0; i < numberOfVertices; i++) {
    sourceWeights[i] = 1.0f;
    sinkWeights[i] = 1.0f;
}

std::vector<int> groups(numberOfVertices, 0);
std::vector<float> capacity(3 * numberOfVertices + size, 0.0f);
std::vector<EdgeDescriptor> reverseEdges(3 * numberOfVertices + size);

GraphType graph;

for (int i = 0; i < numberOfVertices; i++) {
    boost::add_vertex(graph);
}

std::vector<std::pair<int, int>> edges((size - numberOfVertices) / 2);
int countEdges = 0;
for (int i = 0; i < neighbours.size(); i++) {
    for (int c : neighbours[i]) {
        if (i < c) {
            edges[countEdges] = (std::pair<int, int>(i, c));
            countEdges++;
        }
    }
}
//I create the edges as std::pair<int,int>
//in order to add them to the graph after with the corresponding weights

for (int i = 0; i < edges.size(); i++) {
    float weight = 1.0f;

    int nextEdgeId = 2 * i;

    EdgeDescriptor edge;
    bool inserted;
    boost::tie(edge, inserted) = boost::add_edge(boost::vertex(edges[i].first, graph), boost::vertex(edges[i].second, graph), nextEdgeId, graph);
    if (!inserted)
    {
        std::cerr << "Not inserted!" << std::endl;
    }
    EdgeDescriptor reverseEdge = boost::add_edge(boost::vertex(edges[i].second, graph), boost::vertex(edges[i].first, graph), nextEdgeId + 1, graph).first;

    reverseEdges[nextEdgeId] = reverseEdge;
    reverseEdges[nextEdgeId + 1] = edge;
    capacity[nextEdgeId] = weight;
    capacity[nextEdgeId + 1] = weight;
}

VertexDescriptor sourceVertex = boost::vertex(sourceId, graph);
VertexDescriptor sinkVertex = boost::vertex(sinkId, graph);

for (int i = 0; i < numberOfVertices; i++) {
    int nextEdgeId = 2 * edges.size() + 4 * i;

    EdgeDescriptor edge;
    bool inserted;
    boost::tie(edge, inserted) = boost::add_edge(boost::vertex(i, graph), sourceVertex, nextEdgeId, graph);
    if (!inserted)
    {
        std::cerr << "Not inserted!" << std::endl;
    }
    EdgeDescriptor reverseEdge = boost::add_edge(sourceVertex, boost::vertex(i, graph), nextEdgeId + 1, graph).first;

    reverseEdges[nextEdgeId] = reverseEdge;
    reverseEdges[nextEdgeId + 1] = edge;
    capacity[nextEdgeId] = sourceWeights[i];
    capacity[nextEdgeId + 1] = sourceWeights[i];


    int nextEdgeId2 = nextEdgeId + 2;

    EdgeDescriptor edge2;
    bool inserted2;
    boost::tie(edge2, inserted2) = boost::add_edge(boost::vertex(i, graph), sinkVertex, nextEdgeId2, graph);
    if (!inserted2)
    {
        std::cerr << "Not inserted!" << std::endl;
    }
    EdgeDescriptor reverseEdge2 = boost::add_edge(sinkVertex, boost::vertex(i, graph), nextEdgeId2 + 1, graph).first;

    reverseEdges[nextEdgeId2] = reverseEdge2;
    reverseEdges[nextEdgeId2 + 1] = edge2;
    capacity[nextEdgeId2] = sinkWeights[i];
    capacity[nextEdgeId2 + 1] = sinkWeights[i];

}
std::vector<float> residual_capacity(boost::num_edges(graph), 0.0f);

//I launch the algorithm by using all the vectors I defined previously

boost::boykov_kolmogorov_max_flow(graph,
    boost::make_iterator_property_map(&capacity[0], boost::get(boost::edge_index, graph)),
    boost::make_iterator_property_map(&residual_capacity[0], boost::get(boost::edge_index, graph)),
    boost::make_iterator_property_map(&reverseEdges[0], boost::get(boost::edge_index, graph)),
    boost::make_iterator_property_map(&groups[0], boost::get(boost::vertex_index, graph)),
    boost::get(boost::vertex_index, graph),
    sourceVertex,
    sinkVertex);

我在几张图片上使用此代码(大约100张)。对图像进行了大量的预处理,以提取将充当我的图形顶点的集群以及这些集群之间的连接信息。

代码在大多数图像上运行良好。当我启动我的程序时,它完美地运行了10个图像,然后,在第11个图像上,没有明显的原因,它与消息崩溃

  

Program.exe中0x00007FF9B52DE6FC(ntdll.dll)的未处理异常:0xC0000374:堆已损坏(参数:0x00007FF9B53322B0)。

如果我只在第11张图片上运行它,它也会直接崩溃。

调用堆栈非常长(感谢所有这些模板的Boost)所以我不会在这里发布它,但是在调用boost::boykov_kolmogorov_max_flow时应用程序失败了。如果我删除调用此函数的行,程序将在所有图像上完美运行(即使是第11个)。

我在装有64Gb RAM的Windows 10 64位计算机上运行Visual Studio 2013中的程序。

所以我的问题是,这个堆损坏错误的原因可能只出现在某些图像上(在这种情况下,只是意味着不同数量的顶点和邻居信息,因为我将权重设置为1.0到处) ?

0 个答案:

没有答案