Boost logo

Boost :

From: Yu Huang (yuhuang_at_[hidden])
Date: 2005-09-07 02:11:52


Hi all,

I coded a program recursively cutting graphs based on
brandes_betweenness_centrality.

But the weird thing is that it succeeds on small graphs(<=8 vertices,
<=15 edges) and large graphs(~3500 vertices, ~138,000edges). But failed
on medium-size (~37-200 vertices, ~42-350 edges).

The failed output is like this:

no_of_vertices: 203
no_of_edges: 368
connectivity: 0.0179486
running brandes_betweenness_centrality... *** glibc detected *** double
free or corruption (out): 0x080942d8 ***
Aborted

Actually, I can't say the it succeeds on large graph. I stopped it after
~45 brandes_betweenness_centrality() calls(because it took too long,
over-night). But on medium-size ones, the first
brandes_betweenness_centrality() is always ok. But failed quickly,
mostly 2nd loop, some 3rd, even 5th. Only 0x080942d8 changed from run to
run. Others remain same(Am i stupid to say this? of course it won't change).

Well, i paste my core function here. The main idea is I remove the edge
with max centrality and form a vector of clusters(graphs) from the
ancestor graph's components (if after cut, the ancestor has >=2
components, otherwise keep cutting on the ancestor graph).

void ClusterByEBC::cut_by_betweenness_centrality(Graph &graph, const int
&size_cutoff, const float &conn_cutoff)
/*
*09-04-05
* cut the graph with the edge of maximum betweenness_centrality
*/
{
    int no_of_vertices = num_vertices(graph);
    int no_of_edges = num_edges(graph);
    #ifdef DEBUG
        std::cerr<<"no_of_vertices: "<<no_of_vertices<<std::endl;
        std::cerr<<"no_of_edges: "<<no_of_edges<<std::endl;
    #endif
    if (no_of_vertices>=size_cutoff)
    {
        float connectivity =
2.0*no_of_edges/(no_of_vertices*(no_of_vertices-1));
        #ifdef DEBUG
            std::cerr<<"connectivity: "<<connectivity<<std::endl;
        #endif
        if (connectivity>=conn_cutoff)
        {
            #ifdef DEBUG
                std::cerr<<"good subgraph "<<std::endl;
            #endif
            good_subgraph_vector.push_back(graph);
        }
        else
        {
            vector<double> edge_centrality(no_of_edges);
            EdgeCentralityMap ec_map(edge_centrality.begin(),
get(edge_index, graph));
                //"make_iterator_property_map(edge_centrality.begin(),
get(edge_index, subgraph), double())" also works.
            indirect_cmp<EdgeCentralityMap, std::less<centrality_type> >
cmp(ec_map);
            #ifdef DEBUG
                std::cerr<<"running brandes_betweenness_centrality... ";
            #endif
            brandes_betweenness_centrality(graph,
edge_centrality_map(ec_map));
            #ifdef DEBUG
                std::cerr<<"done."<<std::endl;
            #endif
            edgeDescriptor e = *max_element(edges(graph).first,
edges(graph).second, cmp);
            centrality_type max_centrality = get(ec_map, e);
            #ifdef DEBUG
                std::cerr<<"max_centrality is "<<max_centrality<<std::endl;
            #endif
            remove_edge(e, graph);
            #ifdef DEBUG
                std::cerr<<"after removal the subgraph has
"<<num_edges(graph)<<" edges."<<std::endl;
            #endif
            std::vector<int> component(num_vertices(graph));
            int no_of_components = connected_components(graph,
&component[0]);
            if (no_of_components==1) //keep cutting
            {
                #ifdef DEBUG
                    std::cerr<<"only one component, keep cutting
"<<std::endl;
                #endif
                cut_by_betweenness_centrality(graph, size_cutoff,
conn_cutoff);
            }
            else //first get the connected_components into a
vector_sub_subgraph and cut them separately
            {
                #ifdef DEBUG
                    std::cerr<<"get the connected_components into a
vector_graph and cut them separately "<<std::endl;
                #endif
                std::vector<Graph> vector_graph =
graph_components(graph, component, no_of_components);
                std::vector<Graph>::iterator g_iterator;
               
for(g_iterator=vector_graph.begin();g_iterator!=vector_graph.end();++g_iterator)
                {
                    cut_by_betweenness_centrality(*g_iterator,
size_cutoff, conn_cutoff);
                }
            }
        }
    }
    #ifdef DEBUG
    else
        std::cerr<<"Bad graph, too
small,"<<no_of_vertices<<"vertices"<<std::endl;
    #endif
   
}

This looks like a hard issue. I searched the mailing list and found one
similar message,
http://lists.boost.org/MailArchives/ublas/2005/08/0657.php (no one replied).

Thanks,
Yu


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk