annotate louvain/community.cpp @ 0:1d1b9e1b2e2f draft

Uploaded
author petr-novak
date Thu, 19 Dec 2019 10:24:45 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
1 // File: community.h
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
2 // -- community detection source file
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
3 //-----------------------------------------------------------------------------
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
4 // Community detection
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
5 // Based on the article "Fast unfolding of community hierarchies in large networks"
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
6 // Copyright (C) 2008 V. Blondel, J.-L. Guillaume, R. Lambiotte, E. Lefebvre
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
7 //
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
8 // This program must not be distributed without agreement of the above mentionned authors.
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
9 //-----------------------------------------------------------------------------
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
10 // Author : E. Lefebvre, adapted by J.-L. Guillaume
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
11 // Email : jean-loup.guillaume@lip6.fr
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
12 // Location : Paris, France
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
13 // Time : February 2008
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
14 //-----------------------------------------------------------------------------
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
15 // see readme.txt for more details
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
16
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
17 #include "community.h"
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
18
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
19 using namespace std;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
20
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
21 Community::Community(char * filename, char * filename_w, int type, int nbp, double minm) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
22 g = Graph(filename, filename_w, type);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
23 size = g.nb_nodes;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
24
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
25 neigh_weight.resize(size,-1);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
26 neigh_pos.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
27 neigh_last=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
28
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
29 n2c.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
30 in.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
31 tot.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
32
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
33 for (int i=0 ; i<size ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
34 n2c[i] = i;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
35 tot[i] = g.weighted_degree(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
36 in[i] = g.nb_selfloops(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
37 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
38
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
39 nb_pass = nbp;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
40 min_modularity = minm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
41 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
42
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
43 Community::Community(Graph gc, int nbp, double minm) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
44 g = gc;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
45 size = g.nb_nodes;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
46
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
47 neigh_weight.resize(size,-1);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
48 neigh_pos.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
49 neigh_last=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
50
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
51 n2c.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
52 in.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
53 tot.resize(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
54
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
55 for (int i=0 ; i<size ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
56 n2c[i] = i;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
57 in[i] = g.nb_selfloops(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
58 tot[i] = g.weighted_degree(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
59 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
60
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
61 nb_pass = nbp;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
62 min_modularity = minm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
63 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
64
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
65 void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
66 Community::init_partition(char * filename) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
67 ifstream finput;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
68 finput.open(filename,fstream::in);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
69
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
70 // read partition
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
71 while (!finput.eof()) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
72 unsigned int node, comm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
73 finput >> node >> comm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
74
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
75 if (finput) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
76 int old_comm = n2c[node];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
77 neigh_comm(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
78
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
79 remove(node, old_comm, neigh_weight[old_comm]);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
80
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
81 unsigned int i=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
82 for ( i=0 ; i<neigh_last ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
83 unsigned int best_comm = neigh_pos[i];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
84 float best_nblinks = neigh_weight[neigh_pos[i]];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
85 if (best_comm==comm) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
86 insert(node, best_comm, best_nblinks);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
87 break;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
88 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
89 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
90 if (i==neigh_last)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
91 insert(node, comm, 0);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
92 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
93 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
94 finput.close();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
95 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
96
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
97 // inline void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
98 // Community::remove(int node, int comm, double dnodecomm) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
99 // assert(node>=0 && node<size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
100
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
101 // tot[comm] -= g.weighted_degree(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
102 // in[comm] -= 2*dnodecomm + g.nb_selfloops(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
103 // n2c[node] = -1;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
104 // }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
105
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
106 // inline void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
107 // Community::insert(int node, int comm, double dnodecomm) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
108 // assert(node>=0 && node<size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
109
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
110 // tot[comm] += g.weighted_degree(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
111 // in[comm] += 2*dnodecomm + g.nb_selfloops(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
112 // n2c[node]=comm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
113 // }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
114
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
115 void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
116 Community::display() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
117 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
118 cerr << " " << i << "/" << n2c[i] << "/" << in[i] << "/" << tot[i] ;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
119 cerr << endl;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
120 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
121
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
122
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
123 double
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
124 Community::modularity() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
125 double q = 0.;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
126 double m2 = (double)g.total_weight;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
127
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
128 for (int i=0 ; i<size ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
129 if (tot[i]>0)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
130 q += (double)in[i]/m2 - ((double)tot[i]/m2)*((double)tot[i]/m2);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
131 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
132
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
133 return q;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
134 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
135
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
136 void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
137 Community::neigh_comm(unsigned int node) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
138 for (unsigned int i=0 ; i<neigh_last ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
139 neigh_weight[neigh_pos[i]]=-1;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
140 neigh_last=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
141
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
142 pair<vector<unsigned int>::iterator, vector<float>::iterator> p = g.neighbors(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
143
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
144 unsigned int deg = g.nb_neighbors(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
145
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
146 neigh_pos[0]=n2c[node];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
147 neigh_weight[neigh_pos[0]]=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
148 neigh_last=1;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
149
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
150 for (unsigned int i=0 ; i<deg ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
151 unsigned int neigh = *(p.first+i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
152 unsigned int neigh_comm = n2c[neigh];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
153 double neigh_w = (g.weights.size()==0)?1.:*(p.second+i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
154
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
155 if (neigh!=node) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
156 if (neigh_weight[neigh_comm]==-1) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
157 neigh_weight[neigh_comm]=0.;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
158 neigh_pos[neigh_last++]=neigh_comm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
159 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
160 neigh_weight[neigh_comm]+=neigh_w;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
161 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
162 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
163 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
164
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
165 void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
166 Community::partition2graph() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
167 vector<int> renumber(size, -1);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
168 for (int node=0 ; node<size ; node++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
169 renumber[n2c[node]]++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
170 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
171
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
172 int final=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
173 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
174 if (renumber[i]!=-1)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
175 renumber[i]=final++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
176
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
177
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
178 for (int i=0 ; i<size ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
179 pair<vector<unsigned int>::iterator, vector<float>::iterator> p = g.neighbors(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
180
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
181 int deg = g.nb_neighbors(i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
182 for (int j=0 ; j<deg ; j++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
183 int neigh = *(p.first+j);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
184 cout << renumber[n2c[i]] << " " << renumber[n2c[neigh]] << endl;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
185 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
186 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
187 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
188
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
189 void
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
190 Community::display_partition() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
191 vector<int> renumber(size, -1);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
192 for (int node=0 ; node<size ; node++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
193 renumber[n2c[node]]++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
194 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
195
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
196 int final=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
197 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
198 if (renumber[i]!=-1)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
199 renumber[i]=final++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
200
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
201 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
202 cout << i << " " << renumber[n2c[i]] << endl;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
203 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
204
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
205
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
206 Graph
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
207 Community::partition2graph_binary() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
208 // Renumber communities
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
209 vector<int> renumber(size, -1);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
210 for (int node=0 ; node<size ; node++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
211 renumber[n2c[node]]++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
212 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
213
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
214 int final=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
215 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
216 if (renumber[i]!=-1)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
217 renumber[i]=final++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
218
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
219 // Compute communities
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
220 vector<vector<int> > comm_nodes(final);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
221 for (int node=0 ; node<size ; node++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
222 comm_nodes[renumber[n2c[node]]].push_back(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
223 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
224
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
225 // Compute weighted graph
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
226 Graph g2;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
227 g2.nb_nodes = comm_nodes.size();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
228 g2.degrees.resize(comm_nodes.size());
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
229
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
230 int comm_deg = comm_nodes.size();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
231 for (int comm=0 ; comm<comm_deg ; comm++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
232 map<int,float> m;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
233 map<int,float>::iterator it;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
234
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
235 int comm_size = comm_nodes[comm].size();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
236 for (int node=0 ; node<comm_size ; node++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
237 pair<vector<unsigned int>::iterator, vector<float>::iterator> p = g.neighbors(comm_nodes[comm][node]);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
238 int deg = g.nb_neighbors(comm_nodes[comm][node]);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
239 for (int i=0 ; i<deg ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
240 int neigh = *(p.first+i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
241 int neigh_comm = renumber[n2c[neigh]];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
242 double neigh_weight = (g.weights.size()==0)?1.:*(p.second+i);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
243
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
244 it = m.find(neigh_comm);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
245 if (it==m.end())
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
246 m.insert(make_pair(neigh_comm, neigh_weight));
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
247 else
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
248 it->second+=neigh_weight;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
249 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
250 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
251 g2.degrees[comm]=(comm==0)?m.size():g2.degrees[comm-1]+m.size();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
252 g2.nb_links+=m.size();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
253
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
254
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
255 for (it = m.begin() ; it!=m.end() ; it++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
256 g2.total_weight += it->second;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
257 g2.links.push_back(it->first);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
258 g2.weights.push_back(it->second);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
259 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
260 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
261
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
262 return g2;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
263 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
264
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
265
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
266 bool
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
267 Community::one_level() {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
268 bool improvement=false ;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
269 int nb_moves;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
270 int nb_pass_done = 0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
271 double new_mod = modularity();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
272 double cur_mod = new_mod;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
273
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
274 vector<int> random_order(size);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
275 for (int i=0 ; i<size ; i++)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
276 random_order[i]=i;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
277 for (int i=0 ; i<size-1 ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
278 int rand_pos = rand()%(size-i)+i;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
279 int tmp = random_order[i];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
280 random_order[i] = random_order[rand_pos];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
281 random_order[rand_pos] = tmp;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
282 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
283
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
284 // repeat while
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
285 // there is an improvement of modularity
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
286 // or there is an improvement of modularity greater than a given epsilon
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
287 // or a predefined number of pass have been done
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
288 do {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
289 cur_mod = new_mod;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
290 nb_moves = 0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
291 nb_pass_done++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
292
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
293 // for each node: remove the node from its community and insert it in the best community
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
294 for (int node_tmp=0 ; node_tmp<size ; node_tmp++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
295 // int node = node_tmp;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
296 int node = random_order[node_tmp];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
297 int node_comm = n2c[node];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
298 double w_degree = g.weighted_degree(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
299
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
300 // computation of all neighboring communities of current node
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
301 neigh_comm(node);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
302 // remove node from its current community
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
303 remove(node, node_comm, neigh_weight[node_comm]);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
304
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
305 // compute the nearest community for node
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
306 // default choice for future insertion is the former community
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
307 int best_comm = node_comm;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
308 double best_nblinks = 0.;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
309 double best_increase = 0.;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
310 for (unsigned int i=0 ; i<neigh_last ; i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
311 double increase = modularity_gain(node, neigh_pos[i], neigh_weight[neigh_pos[i]], w_degree);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
312 if (increase>best_increase) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
313 best_comm = neigh_pos[i];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
314 best_nblinks = neigh_weight[neigh_pos[i]];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
315 best_increase = increase;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
316 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
317 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
318
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
319 // insert node in the nearest community
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
320 insert(node, best_comm, best_nblinks);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
321
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
322 if (best_comm!=node_comm)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
323 nb_moves++;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
324 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
325
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
326 double total_tot=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
327 double total_in=0;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
328 for (unsigned int i=0 ; i<tot.size() ;i++) {
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
329 total_tot+=tot[i];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
330 total_in+=in[i];
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
331 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
332
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
333 new_mod = modularity();
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
334 if (nb_moves>0)
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
335 improvement=true;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
336
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
337 } while (nb_moves>0 && new_mod-cur_mod>min_modularity);
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
338
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
339 return improvement;
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
340 }
1d1b9e1b2e2f Uploaded
petr-novak
parents:
diff changeset
341