Boost logo

Boost :

From: Yu Huang (yuhuang_at_[hidden])
Date: 2005-09-07 16:17:10


Date: Wed, 7 Sep 2005 09:14:15 -0500 From: Douglas Gregor
<doug.gregor_at_[hidden]> Subject: Re: [boost] [BGL]
brandes_betweenness_centrality failed on medium-size graphs To:
boost_at_[hidden] Message-ID:
<18767AEB-146E-494D-BBE9-BD4437E1A4D5_at_[hidden]> Content-Type:
text/plain; charset=US-ASCII; delsp=yes; format=flowed On Sep 7, 2005,
at 2:11 AM, Yu Huang wrote:

>> 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).
>
>

Make sure to compile with full optimization (e.g., -O3 on GCC),
because it makes a *huge* difference in the performance.

>> 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).
>
>

I'm guessing that you will need to renumber the edges after removing
an edge.

[snip]

>> vector<double> edge_centrality(no_of_edges);
>> EdgeCentralityMap ec_map(edge_centrality.begin(),
>> get(edge_index, graph));
>
>

At this point, we need to be 100% sure that no_of_edges > the index
of every edge in the graph, otherwise we'll be reading/writing past
the end of the edge_centrality vector.

>> //"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
>
>
I believe this is the problem. When you remove an edge, num_edges

(graph) is reduced by one. However, there may still exist an edge

with edge_index=num_edges(graph). There are two ways to fix the problem:

   1) After calling remove_edge, loop over the edges in the graph and

reindex them to be sure they are in the range [0, num_edges(graph))

after removal.

   2) Allocate the edge_centrality vector for the total number of

edges *outside* of the cut_by_betweenness_centrality function, then

pass in a reference to the vector (or its property map). That way,

even without changing the edge indices you'll still have enough space

in the vector, even though its usage will be sparse.

#1 is the smallest fix, whereas #2 might result in slightly faster code.

     Doug

Yeah! Both of them worked out. My final option is 2 as Doug said it's faster.
I almost gave up when i saw the "glibc detected" last night.

Thanks!
Yu


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