Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 37c4034

Browse files
authored
Multithreading of Projection
1 parent dbf8c81 commit 37c4034

File tree

7 files changed

+154
-81
lines changed

7 files changed

+154
-81
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ NAME = comsim
44
all: $(NAME)
55

66
$(NAME): node.o main.o graph.o projection.o community.o
7-
g++ node.o main.o graph.o projection.o community.o -o $(NAME) $(STD)
7+
g++ node.o main.o graph.o projection.o community.o -o $(NAME) $(STD) -lpthread
88

99
main.o : main.cpp
1010
g++ -c main.cpp $(STD) -O5

community.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ void Community::aggregate(Graph*& graph_projection, unordered_set<unsigned int>&
142142
for(auto& index_com : map_community[graph_projection->list_nodes[index+i+1]->index])
143143
{
144144
map_similar_community_tmp->emplace(make_pair(index_com, 0.0));
145-
/*if(map_similar_community_tmp->find(index_com) == map_similar_community_tmp->end())
146-
map_similar_community_tmp->insert(make_pair(index_com, 0.0));*/
147145
map_similar_community_tmp->at(index_com) += node->neighbor_weights[i];
148146
}
149147
}

community.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ class Community
1010
Graph* main_graph;
1111
unsigned int index_community;
1212
unsigned int depth_best;
13-
1413
public:
1514
unordered_map<unsigned int, vector<unsigned int>> map_community;
1615
unordered_map<unsigned int, unordered_map<unsigned int, float>*> map_similar_community;

libs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <unistd.h>
1212
#include <sys/time.h>
1313
#include <sys/resource.h>
14+
#include <pthread.h>
1415

1516
#include <ctime>
1617
#include <iostream>

main.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,20 @@ void usage()
4848
cerr << "\"./comsim uni_network_links 1 cm 3 > detected_communities\" executes ComSim with cn similarity index between nodes at distance 1 on a unipartite network and it allows each node to be part of 3 cycles." << endl;
4949
}
5050

51-
Projection* select_similarity(string similarity_index)
51+
Projection* select_similarity(string similarity_index, Graph*& in_graph)
5252
{
5353
if(similarity_index == "cn")
54-
return new CommonNeighbors();
54+
return new CommonNeighbors(in_graph);
5555
else if(similarity_index == "ji")
56-
return new JaccardIndex();
56+
return new JaccardIndex(in_graph);
5757
else if(similarity_index == "aa")
58-
return new AdamicAdar();
58+
return new AdamicAdar(in_graph);
5959
else if(similarity_index == "ra")
60-
return new ResourceAllocator();
60+
return new ResourceAllocator(in_graph);
6161
else if(similarity_index == "lhn")
62-
return new LHN1();
62+
return new LHN1(in_graph);
6363
else if(similarity_index == "pan")
64-
return new PA_Neighbor();
64+
return new PA_Neighbor(in_graph);
6565
}
6666

6767
int main(int argc, const char* argv[])
@@ -123,9 +123,9 @@ int main(int argc, const char* argv[])
123123

124124
g = main_graph;
125125

126-
p = select_similarity(similarity_index);
126+
p = select_similarity(similarity_index, g);
127127
cerr << endl << "Projecting graph (distance : " << distance << ") ..." << endl;
128-
p->project(g, distance);
128+
p->project(distance);
129129

130130
if(p->graph_projection->size_list_nodes > 0)
131131
{

projection.cpp

Lines changed: 108 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "projection.h"
22

3-
Projection::Projection()
3+
Projection::Projection(Graph*& in_graph)
44
{
55
graph_projection = new Graph();
6+
this->in_graph = in_graph;
7+
nb_threads = 5;
68
}
79

810
Projection::~Projection()
@@ -11,50 +13,106 @@ Projection::~Projection()
1113
delete graph_projection;
1214
}
1315

14-
void Projection::project(Graph*& in_graph, unsigned int distance)
16+
void* projection_main_thread(void* main_struct_args)
1517
{
16-
unsigned int d, index;
17-
vector<Node*> list_distance_neighbors;
18-
float projection_weight;
19-
Node* node;
18+
projection_thread_args* main_args = static_cast<projection_thread_args*>(main_struct_args);
19+
20+
pthread_t thread;
21+
unsigned int index, size_list_nodes;
22+
size_list_nodes = main_args->p->in_graph->size_list_nodes;
23+
24+
projection_thread_args args;
25+
args.p = main_args->p;
26+
args.map_node = main_args->map_node;
27+
args.map_neighbor = main_args->map_neighbor;
28+
args.distance = main_args->distance;
29+
30+
pthread_mutex_lock(&projection_main_mutex);
31+
if(main_args->index == size_list_nodes)
32+
{
33+
pthread_mutex_unlock(&projection_main_mutex);
34+
return NULL;
35+
}
36+
pthread_mutex_unlock(&projection_main_mutex);
2037

21-
unordered_map<unsigned int, Node*> map_node;
22-
unordered_map<unsigned int, set<pair<unsigned int, float>, comp_pair>> map_neighbor;
38+
do
39+
{
40+
pthread_mutex_lock(&projection_main_mutex);
41+
args.index = main_args->index;
42+
main_args->index += main_args->p->in_graph->list_nodes[main_args->index]->nb_neighbors + 1;
43+
pthread_mutex_unlock(&projection_main_mutex);
44+
45+
pthread_create(&thread, NULL, &compute_projection_thread, &args);
46+
pthread_join(thread, NULL);
47+
48+
pthread_mutex_lock(&projection_main_mutex);
49+
index = main_args->index;
50+
pthread_mutex_unlock(&projection_main_mutex);
51+
52+
53+
} while(index < size_list_nodes);
54+
}
55+
56+
void* compute_projection_thread(void* struct_args)
57+
{
58+
projection_thread_args* args = static_cast<projection_thread_args*>(struct_args);
59+
2360
pair<unordered_map<unsigned int, set<pair<unsigned int, float>, comp_pair>>::iterator, bool> it_map;
2461
vector<unsigned int> shuffle;
25-
26-
index = 0;
27-
while(index < in_graph->size_list_nodes)
28-
{
29-
list_distance_neighbors = get_neighbors(in_graph, index, distance);
62+
unordered_map<unsigned int, Node*> map_node;
63+
unordered_map<unsigned int, set<pair<unsigned int, float>, comp_pair>> map_neighbor;
3064

31-
node = new Node();
32-
node->id = in_graph->list_nodes[index]->id;
33-
node->main_index = in_graph->list_nodes[index]->main_index;
34-
map_node[index] = node;
65+
vector<Node*> list_distance_neighbors = args->p->get_neighbors(args->index, args->distance);
66+
float projection_weight;
3567

36-
for(auto& n : list_distance_neighbors)
37-
shuffle.push_back(n->index);
38-
random_shuffle(shuffle.begin(), shuffle.end());
68+
Node* node = new Node();
69+
node->id = args->p->in_graph->list_nodes[args->index]->id;
70+
node->main_index = args->p->in_graph->list_nodes[args->index]->main_index;
3971

40-
it_map = map_neighbor.emplace(index, set<pair<unsigned int, float>, comp_pair>());
72+
for(auto& n : list_distance_neighbors)
73+
shuffle.push_back(n->index);
74+
random_shuffle(shuffle.begin(), shuffle.end());
4175

42-
for(auto& index_neighbor : shuffle)
43-
{
44-
projection_weight = similarity_projection(in_graph, index, index_neighbor);
76+
it_map = map_neighbor.emplace(args->index, set<pair<unsigned int, float>, comp_pair>());
77+
78+
for(auto& index_neighbor : shuffle)
79+
{
80+
projection_weight = args->p->similarity_projection(args->index, index_neighbor);
4581

46-
if(projection_weight > 0.0)
47-
it_map.first->second.insert(make_pair(index_neighbor, projection_weight));
48-
}
49-
50-
index += in_graph->list_nodes[index]->nb_neighbors + 1;
51-
shuffle.clear();
82+
if(projection_weight > 0.0)
83+
it_map.first->second.insert(make_pair(index_neighbor, projection_weight));
5284
}
5385

86+
pthread_mutex_lock(&compute_projection_mutex);
87+
args->map_node->emplace(make_pair(args->index, node));
88+
args->map_neighbor->insert(map_neighbor.begin(), map_neighbor.end());
89+
pthread_mutex_unlock(&compute_projection_mutex);
90+
}
91+
92+
void Projection::project(unsigned int distance)
93+
{
94+
unordered_map<unsigned int, Node*> map_node;
95+
unordered_map<unsigned int, set<pair<unsigned int, float>, comp_pair>> map_neighbor;
96+
97+
pthread_t threads[nb_threads];
98+
projection_thread_args main_args;
99+
main_args.index = 0;
100+
main_args.p = this;
101+
main_args.map_node = &map_node;
102+
main_args.map_neighbor = &map_neighbor;
103+
main_args.distance = distance;
104+
105+
unsigned int i;
106+
for(i=0; i<nb_threads; i++)
107+
pthread_create(&threads[i], NULL, &projection_main_thread, &main_args);
108+
109+
for(i=0; i<nb_threads; i++)
110+
pthread_join(threads[i], NULL);
111+
54112
graph_projection->create_graph(map_node, map_neighbor);
55113
}
56114

57-
vector<Node*> Projection::get_neighbors(Graph*& in_graph, unsigned int index, unsigned int distance) const
115+
vector<Node*> Projection::get_neighbors(unsigned int& index, unsigned int& distance) const
58116
{
59117
vector<Node*> list_neighbors, hist_list_neighbors, list_distance_neighbors;
60118
unsigned int i, d = 0;
@@ -84,7 +142,7 @@ vector<Node*> Projection::get_neighbors(Graph*& in_graph, unsigned int index, un
84142
return list_neighbors;
85143
}
86144

87-
set<Node*> Projection::get_intersection(Graph*& in_graph, Node* node1, Node* node2) const
145+
set<Node*> Projection::get_intersection(Node*& node1, Node*& node2) const
88146
{
89147
vector<Node*> set_node1, set_node2;
90148
set<Node*> intersection;
@@ -104,15 +162,15 @@ set<Node*> Projection::get_intersection(Graph*& in_graph, Node* node1, Node* nod
104162

105163
/*********************** SIMILARITY MEASURES ***********************/
106164

107-
CommonNeighbors::CommonNeighbors() : Projection()
165+
CommonNeighbors::CommonNeighbors(Graph*& in_graph) : Projection(in_graph)
108166
{}
109167

110-
float CommonNeighbors::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
168+
float CommonNeighbors::similarity_projection(unsigned int& index1, unsigned int& index2)
111169
{
112170
Node* node1 = in_graph->list_nodes[index1];
113171
Node* node2 = in_graph->list_nodes[index2];
114172

115-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
173+
set<Node*> intersection = get_intersection(node1, node2);
116174

117175
float projection_weight = 0.0;
118176
unsigned int cpt, index;
@@ -142,15 +200,15 @@ float CommonNeighbors::similarity_projection(Graph*& in_graph, unsigned int inde
142200
return projection_weight;
143201
}
144202

145-
JaccardIndex::JaccardIndex() : Projection()
203+
JaccardIndex::JaccardIndex(Graph*& in_graph) : Projection(in_graph)
146204
{}
147205

148-
float JaccardIndex::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
206+
float JaccardIndex::similarity_projection(unsigned int& index1, unsigned int& index2)
149207
{
150208
Node* node1 = in_graph->list_nodes[index1];
151209
Node* node2 = in_graph->list_nodes[index2];
152210

153-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
211+
set<Node*> intersection = get_intersection(node1, node2);
154212

155213
float projection_weight, sum_weight;
156214
projection_weight = sum_weight = 0.0;
@@ -181,15 +239,15 @@ float JaccardIndex::similarity_projection(Graph*& in_graph, unsigned int index1,
181239
return 1.0 * projection_weight / sum_weight;
182240
}
183241

184-
AdamicAdar::AdamicAdar() : Projection()
242+
AdamicAdar::AdamicAdar(Graph*& in_graph) : Projection(in_graph)
185243
{}
186244

187-
float AdamicAdar::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
245+
float AdamicAdar::similarity_projection(unsigned int& index1, unsigned int& index2)
188246
{
189247
Node* node1 = in_graph->list_nodes[index1];
190248
Node* node2 = in_graph->list_nodes[index2];
191249

192-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
250+
set<Node*> intersection = get_intersection(node1, node2);
193251

194252
float projection_weight, sum_weight;
195253
projection_weight = 0.0;
@@ -205,15 +263,15 @@ float AdamicAdar::similarity_projection(Graph*& in_graph, unsigned int index1, u
205263
return projection_weight;
206264
}
207265

208-
ResourceAllocator::ResourceAllocator() : Projection()
266+
ResourceAllocator::ResourceAllocator(Graph*& in_graph) : Projection(in_graph)
209267
{}
210268

211-
float ResourceAllocator::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
269+
float ResourceAllocator::similarity_projection(unsigned int& index1, unsigned int& index2)
212270
{
213271
Node* node1 = in_graph->list_nodes[index1];
214272
Node* node2 = in_graph->list_nodes[index2];
215273

216-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
274+
set<Node*> intersection = get_intersection(node1, node2);
217275

218276
float projection_weight, sum_weight;
219277
projection_weight = 0.0;
@@ -229,15 +287,15 @@ float ResourceAllocator::similarity_projection(Graph*& in_graph, unsigned int in
229287
return projection_weight;
230288
}
231289

232-
LHN1::LHN1() : Projection()
290+
LHN1::LHN1(Graph*& in_graph) : Projection(in_graph)
233291
{}
234292

235-
float LHN1::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
293+
float LHN1::similarity_projection(unsigned int& index1, unsigned int& index2)
236294
{
237295
Node* node1 = in_graph->list_nodes[index1];
238296
Node* node2 = in_graph->list_nodes[index2];
239297

240-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
298+
set<Node*> intersection = get_intersection(node1, node2);
241299

242300
float projection_weight, sum_weight1, sum_weight2;
243301
projection_weight = sum_weight1 = sum_weight2 = 0.0;
@@ -268,15 +326,15 @@ float LHN1::similarity_projection(Graph*& in_graph, unsigned int index1, unsigne
268326
return 1.0 * projection_weight / (sum_weight1 * sum_weight2);
269327
}
270328

271-
PA_Neighbor::PA_Neighbor() : Projection()
329+
PA_Neighbor::PA_Neighbor(Graph*& in_graph) : Projection(in_graph)
272330
{}
273331

274-
float PA_Neighbor::similarity_projection(Graph*& in_graph, unsigned int index1, unsigned int index2)
332+
float PA_Neighbor::similarity_projection(unsigned int& index1, unsigned int& index2)
275333
{
276334
Node* node1 = in_graph->list_nodes[index1];
277335
Node* node2 = in_graph->list_nodes[index2];
278336

279-
set<Node*> intersection = get_intersection(in_graph, node1, node2);
337+
set<Node*> intersection = get_intersection(node1, node2);
280338

281339
float projection_weight, sum_weight;
282340
projection_weight = 1.0;

0 commit comments

Comments
 (0)