The goal of this assignment is to implement the Louvain algorithm for hierarchical partitioning of weighted, undirected graphs and apply it to connectomes. You can find a complete description of this algorithm on pages 3 and 4 of Fast unfolding of communities in large networks. Feel free to refer to the textbook as well. Note that the matrix entry \(A_{ij}\) in the paper represents the weight of the edge between node \(i\) and \(j\). Equation (2) in the paper computes the change in modularity when an isolated node \(i\) is added to a module \(C\). You will have to figure out the analogue of this equation for the case when node \(i\) becomes isolated by its removal from its community. Do not examine any other source, especially any code that implements all or part of the algorithm. It an important experience for you to take the care and trouble to implement and test the algorithm yourself. You can use any programming language you want. Feel free to use matrix or graph libraries that already implement helpful classes and functions, e.g., to read and store graphs. Work on this assignment individually.
Implementing the algorithm in stages will be helpful. First, you will need a function to compute the modularity of any partition of the nodes. Then you may want to implement a function to implement the first phase of the algorithm, i.e., that finds a high-modularity partition of the current graph. This function could use a naive way to compute the modularity. Once you have debugged and tested this version, you can make it more efficient, by implementing equation (2) and its analogue to compute the change in modularity efficiently. Finally, you can implement the second phase of the algorithm and use it to compute a hierarchical decomposition of the network.
Remember to test your code. I do not mean writing unit tests, although you are free to do so. By testing, I mean running the code on simple graphs for which you know the correct answer.
Your software should print out
Apply your implementation to the following brain connectomes:
Modularity maximisation challenge. I will award a gift certificate to the student who achieves a consistently-higher modularity, say at least 10% larger, than all the other students. To this end, you can extend the Louvain algorithm by implementing your own heuristics and optimisations, e.g., ideas we discussed in class such as splitting a partition, allowing some swaps that allow the modularity to decrease, or consider pairs of nodes \(i\) and \(j\) that are in the same module but are connected by an edge in the graph. There are literally dozens of ideas you can try, so do not go overboard. Keep in mind the admonition in Figure 9.2.1 of the textbook about the degeneracy of modularity maximisation. I reserve the right to request code, split this award, change the criterion for success, or make no award.
Turn in a typeset (not handwritten) report listing your results for the graphs in order from 1 to 6. Your report can essentially be a nicely-formatted PDF file containing the output of your code. Of course, it will be helpful for me if you use section headings and names to distinguish the results for each connectome from the others. Mention any difficulties you encountered and how you addressed them. Were there any surprises, i.e., results or trends you did not expect? I am also curious to find out what you learnt from this assignment. Of course, if you took upon the modularity maximisation challenge, describe how you modified the Louvain algorithm.