This function implements the multi-level modularity optimization algorithm
for finding community structure, see VD Blondel, J-L Guillaume, R Lambiotte
and E Lefebvre: Fast unfolding of community hierarchies in large networks,
http://arxiv.org/abs/arXiv:0803.0476 for the details.

It is based on the modularity measure and a hierarchial approach.
Initially, each vertex is assigned to a community on its own. In every step,
vertices are re-assigned to communities in a local, greedy way: each vertex
is moved to the community with which it achieves the highest contribution to
modularity. When no vertices can be reassigned, each community is considered
a vertex on its own, and the process starts again with the merged
communities. The process stops when there is only a single vertex left or
when the modularity cannot be increased any more in a step.

This function was contributed by Tom Gregorovic.