0
|
1 // File: main_hierarchy.cpp
|
|
2 // -- output community structure handling (number of levels, communities of one level)
|
|
3 //-----------------------------------------------------------------------------
|
|
4 // Community detection
|
|
5 // Based on the article "Fast unfolding of community hierarchies in large networks"
|
|
6 // Copyright (C) 2008 V. Blondel, J.-L. Guillaume, R. Lambiotte, E. Lefebvre
|
|
7 //
|
|
8 // This program must not be distributed without agreement of the above mentionned authors.
|
|
9 //-----------------------------------------------------------------------------
|
|
10 // Author : E. Lefebvre, adapted by J.-L. Guillaume
|
|
11 // Email : jean-loup.guillaume@lip6.fr
|
|
12 // Location : Paris, France
|
|
13 // Time : February 2008
|
|
14 //-----------------------------------------------------------------------------
|
|
15 // see readme.txt for more details
|
|
16
|
|
17 #include <stdlib.h>
|
|
18 #include <stdio.h>
|
|
19 #include <iostream>
|
|
20 #include <iomanip>
|
|
21 #include <fstream>
|
|
22 #include <vector>
|
|
23 #include <map>
|
|
24 #include <set>
|
|
25 #include <algorithm>
|
|
26
|
|
27 using namespace std;
|
|
28
|
|
29 int display_level = -1;
|
|
30 char *filename = NULL;
|
|
31
|
|
32 void
|
|
33 usage(char *prog_name, const char *more) {
|
|
34 cerr << more;
|
|
35 cerr << "usage: " << prog_name << " input_file [options]" << endl << endl;
|
|
36 cerr << "input_file: read the community tree from this file." << endl;
|
|
37 cerr << "-l xx\t display the community structure for the level xx." << endl;
|
|
38 cerr << "\t outputs the community for each node." << endl;
|
|
39 cerr << "\t xx must belong to [-1,N] if N is the number of levels." << endl;
|
|
40 cerr << "-n\t displays the number of levels and the size of each level." << endl;
|
|
41 cerr << "\t equivalent to -l -1." << endl;
|
|
42 cerr << "-h\tshow this usage message." << endl;
|
|
43 exit(0);
|
|
44 }
|
|
45
|
|
46 void
|
|
47 parse_args(int argc, char **argv) {
|
|
48 if (argc<2)
|
|
49 usage(argv[0], "Bad arguments number\n");
|
|
50
|
|
51 for (int i = 1; i < argc; i++) {
|
|
52 if(argv[i][0] == '-') {
|
|
53 switch(argv[i][1]) {
|
|
54 case 'l':
|
|
55 display_level = atoi(argv[i+1]);
|
|
56 i++;
|
|
57 break;
|
|
58 case 'n':
|
|
59 display_level = -1;
|
|
60 break;
|
|
61 default:
|
|
62 usage(argv[0], "Unknown option\n");
|
|
63 }
|
|
64 } else {
|
|
65 if (filename==NULL)
|
|
66 filename = argv[i];
|
|
67 else
|
|
68 usage(argv[0], "More than one filename\n");
|
|
69 }
|
|
70 }
|
|
71 if (filename==NULL)
|
|
72 usage(argv[0], "No input file has been provided.\n");
|
|
73 }
|
|
74 int
|
|
75 main(int argc, char **argv) {
|
|
76 parse_args(argc, argv);
|
|
77
|
|
78 vector<vector<int> >levels;
|
|
79
|
|
80 ifstream finput;
|
|
81 finput.open(filename,fstream::in);
|
|
82
|
|
83 int l=-1;
|
|
84 while (!finput.eof()) {
|
|
85 int node, nodecomm;
|
|
86 finput >> node >> nodecomm;
|
|
87
|
|
88 if (finput) {
|
|
89 if (node==0) {
|
|
90 l++;
|
|
91 levels.resize(l+1);
|
|
92 }
|
|
93 levels[l].push_back(nodecomm);
|
|
94 }
|
|
95 }
|
|
96
|
|
97 if (display_level==-1) {
|
|
98 cout << "Number of levels: " << levels.size() << endl;
|
|
99 for (unsigned int i=0 ; i<levels.size();i++)
|
|
100 cout << "level " << i << ": " << levels[i].size() << " nodes" << endl;
|
|
101 } else if (display_level<0 || (unsigned)display_level>=levels.size()) {
|
|
102 cerr << "Incorrect level\n";
|
|
103 } else {
|
|
104 vector<int> n2c(levels[0].size());
|
|
105
|
|
106 for (unsigned int i=0 ; i<levels[0].size() ; i++)
|
|
107 n2c[i]=i;
|
|
108
|
|
109 for (l=0 ; l<display_level ; l++)
|
|
110 for (unsigned int node=0 ; node<levels[0].size() ; node++)
|
|
111 n2c[node] = levels[l][n2c[node]];
|
|
112
|
|
113 for (unsigned int node=0 ; node<levels[0].size() ; node++)
|
|
114 cout << node << " " << n2c[node] << endl;
|
|
115 }
|
|
116 }
|