// File: rtackx[P]ComSim/community.cpp
// Function: Community::aggregate(Graph*&, std::unordered_set<unsigned int, std::hash<unsigned int>, std::equal_to<unsigned int>, std::allocator<unsigned int>>&)
void Community::aggregate(Graph*& graph_projection, unordered_set<unsigned int>& list_remaining_nodes)
{
	Node* node;
	unsigned int index_com_similar;
	float max_similarity;
	unordered_map<unsigned int, float> map_similar_community;
	unordered_map<unsigned int, vector<unsigned int>> map_community_tmp;
	unordered_map<unsigned int, vector<unsigned int>> map_best_similarity;
	vector<unsigned int> list_similarity;
	
	for(auto& index : list_remaining_nodes)
	{
		node = graph_projection->list_nodes[index];

		max_similarity = 0.0;
		for(auto& neighbor : node->neighbor_weights)
		{
			if(map_community.find(neighbor.first->index) != map_community.end())
			{	
				for(auto& index_com : map_community[neighbor.first->index])
				{
					map_similar_community.emplace(make_pair(index_com, 0.0));
					map_similar_community[index_com] += neighbor.second;
				}
			}
			else
			{
				if(neighbor.second >= max_similarity)
				{
					if(neighbor.second > max_similarity)
						list_similarity.clear();

					max_similarity = neighbor.second;
					list_similarity.push_back(neighbor.first->index);
				}
			}
		}

		max_similarity = 0.0;
		index_com_similar = -1;

		for(auto& e : map_similar_community)
		{
			if(e.second > max_similarity)
			{
				max_similarity = e.second;
				index_com_similar = e.first;
			}
		}
		map_similar_community.clear();
		
		if(index_com_similar == -1)
			map_best_similarity[list_similarity[rand() % list_similarity.size()]].push_back(index);
		else
		{
			map_community_tmp[index].push_back(index_com_similar);
			
			// Add neighors of "index" into community
			if(map_best_similarity.find(index) != map_best_similarity.end())
			{
				for(auto& index_neighbor : map_best_similarity[index])
					map_community_tmp[index_neighbor].push_back(index_com_similar);
			}
		}
	}
	
	// Saving modification
	for(auto& e : map_community_tmp)
	{
		for(auto& index_com : e.second)
			map_community[e.first].push_back(index_com);

		list_remaining_nodes.erase(e.first);
	}
}

// Assembly:
subq $0x2a8, %rsp            # imm = 0x2A8
movq %rdi, 0x2a0(%rsp)
movq %rsi, 0x298(%rsp)
movq %rdx, 0x290(%rsp)
movq 0x2a0(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0x248(%rsp), %rdi
callq 0x193e0
leaq 0x210(%rsp), %rdi
callq 0x18bf0
leaq 0x1d8(%rsp), %rdi
callq 0x18bf0
leaq 0x1c0(%rsp), %rdi
callq 0x18c30
movq 0x290(%rsp), %rax
movq %rax, 0x1b8(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0x193f0
movq %rax, 0x1b0(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0x19420
movq %rax, 0x1a8(%rsp)
leaq 0x1b0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x19450
testb $0x1, %al
jne 0x1832b
jmp 0x18932
leaq 0x1b0(%rsp), %rdi
callq 0x19470
movq %rax, 0x1a0(%rsp)
movq 0x298(%rsp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq 0x1a0(%rsp), %rcx
movl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, 0x288(%rsp)
xorps %xmm0, %xmm0
movss %xmm0, 0x280(%rsp)
movq 0x288(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x198(%rsp)
movq 0x198(%rsp), %rdi
callq 0x107e0
movq %rax, 0x190(%rsp)
movq 0x198(%rsp), %rdi
callq 0x10810
movq %rax, 0x188(%rsp)
leaq 0x190(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x10840
testb $0x1, %al
jne 0x183cd
jmp 0x1867b
leaq 0x190(%rsp), %rdi
callq 0x10860
movq 0x80(%rsp), %rdi
movq %rax, 0x180(%rsp)
addq $0x10, %rdi
movq 0x180(%rsp), %rax
movq (%rax), %rsi
callq 0x19320
movq %rax, 0x78(%rsp)
jmp 0x18405
movq 0x80(%rsp), %rdi
movq 0x78(%rsp), %rax
movq %rax, 0x178(%rsp)
addq $0x10, %rdi
callq 0x19350
movq %rax, 0x160(%rsp)
leaq 0x178(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x19490
testb $0x1, %al
jne 0x18449
jmp 0x185f8
movq 0x80(%rsp), %rdi
addq $0x10, %rdi
movq 0x180(%rsp), %rax
movq (%rax), %rsi
callq 0x19250
movq %rax, 0x70(%rsp)
jmp 0x1846c
movq 0x70(%rsp), %rax
movq %rax, 0x158(%rsp)
movq 0x158(%rsp), %rdi
callq 0x18dd0
movq %rax, 0x150(%rsp)
movq 0x158(%rsp), %rdi
callq 0x18e00
movq %rax, 0x148(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x18e30
testb $0x1, %al
jne 0x184c1
jmp 0x185f6
leaq 0x150(%rsp), %rdi
callq 0x18e70
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rdi
movq $0x0, 0x128(%rsp)
leaq 0x128(%rsp), %rsi
callq 0x19500
movsd %xmm0, 0x60(%rsp)
movl %eax, 0x6c(%rsp)
jmp 0x18503
movsd 0x60(%rsp), %xmm0
movl 0x6c(%rsp), %eax
movl %eax, 0x130(%rsp)
movsd %xmm0, 0x138(%rsp)
leaq 0x248(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x194b0
movb %dl, 0x57(%rsp)
movq %rax, 0x58(%rsp)
jmp 0x1853d
movb 0x57(%rsp), %al
movq 0x58(%rsp), %rcx
movq %rcx, 0x118(%rsp)
movb %al, 0x120(%rsp)
movq 0x180(%rsp), %rax
movss 0x8(%rax), %xmm0
movss %xmm0, 0x44(%rsp)
movq 0x140(%rsp), %rsi
leaq 0x248(%rsp), %rdi
callq 0x19540
movq %rax, 0x48(%rsp)
jmp 0x18584
movq 0x48(%rsp), %rax
movss 0x44(%rsp), %xmm0
addss (%rax), %xmm0
movss %xmm0, (%rax)
leaq 0x150(%rsp), %rdi
callq 0x18f10
jmp 0x184a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x170(%rsp)
movl %eax, 0x16c(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x18d30
leaq 0x1d8(%rsp), %rdi
callq 0x18c20
leaq 0x210(%rsp), %rdi
callq 0x18c20
leaq 0x248(%rsp), %rdi
callq 0x19730
jmp 0x18ab7
jmp 0x18667
movq 0x180(%rsp), %rax
movss 0x8(%rax), %xmm0
ucomiss 0x280(%rsp), %xmm0
jb 0x18665
movq 0x180(%rsp), %rax
movss 0x8(%rax), %xmm0
ucomiss 0x280(%rsp), %xmm0
jbe 0x18633
leaq 0x1c0(%rsp), %rdi
callq 0x18f30
movq 0x180(%rsp), %rax
movss 0x8(%rax), %xmm0
movss %xmm0, 0x280(%rsp)
movq 0x180(%rsp), %rax
movq (%rax), %rsi
leaq 0x1c0(%rsp), %rdi
callq 0x18c80
jmp 0x18663
jmp 0x18665
jmp 0x18667
jmp 0x18669
leaq 0x190(%rsp), %rdi
callq 0x10880
jmp 0x183af
xorps %xmm0, %xmm0
movss %xmm0, 0x280(%rsp)
movl $0xffffffff, 0x284(%rsp) # imm = 0xFFFFFFFF
leaq 0x248(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x110(%rsp), %rdi
callq 0x19570
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
callq 0x195a0
movq %rax, 0x100(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x195d0
testb $0x1, %al
jne 0x186e7
jmp 0x1874b
leaq 0x108(%rsp), %rdi
callq 0x195f0
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rax
movss 0x4(%rax), %xmm0
ucomiss 0x280(%rsp), %xmm0
jbe 0x1873a
movq 0xf8(%rsp), %rax
movss 0x4(%rax), %xmm0
movss %xmm0, 0x280(%rsp)
movq 0xf8(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x284(%rsp)
jmp 0x1873c
leaq 0x108(%rsp), %rdi
callq 0x19610
jmp 0x186cc
leaq 0x248(%rsp), %rdi
callq 0x19640
cmpl $-0x1, 0x284(%rsp)
jne 0x187ca
callq 0x30a0
cltq
movq %rax, 0x30(%rsp)
leaq 0x1c0(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x18cf0
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movq 0x30(%rsp), %rax
xorl %edx, %edx
divq %rcx
movq %rdx, %rsi
callq 0x18f50
movq %rax, %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x19250
movq %rax, 0x38(%rsp)
jmp 0x187b1
movq 0x38(%rsp), %rdi
movq 0x1a0(%rsp), %rsi
callq 0x18c80
jmp 0x187c5
jmp 0x1891e
movq 0x1a0(%rsp), %rsi
leaq 0x210(%rsp), %rdi
callq 0x19250
movq %rax, 0x20(%rsp)
jmp 0x187e6
movq 0x20(%rsp), %rdi
leaq 0x284(%rsp), %rsi
callq 0x18c80
jmp 0x187fa
movq 0x1a0(%rsp), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x19320
movq %rax, 0x18(%rsp)
jmp 0x18816
movq 0x18(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0x1d8(%rsp), %rdi
callq 0x19350
movq %rax, 0xe8(%rsp)
leaq 0xf0(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x19490
testb $0x1, %al
jne 0x18856
jmp 0x1891c
movq 0x1a0(%rsp), %rsi
leaq 0x1d8(%rsp), %rdi
callq 0x19250
movq %rax, 0x10(%rsp)
jmp 0x18872
movq 0x10(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x18dd0
movq %rax, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x18e00
movq %rax, 0xd0(%rsp)
leaq 0xd8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x18e30
testb $0x1, %al
jne 0x188c4
jmp 0x1891a
leaq 0xd8(%rsp), %rdi
callq 0x18e70
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rsi
leaq 0x210(%rsp), %rdi
callq 0x19250
movq %rax, 0x8(%rsp)
jmp 0x188f5
movq 0x8(%rsp), %rdi
leaq 0x284(%rsp), %rsi
callq 0x18c80
jmp 0x18909
jmp 0x1890b
leaq 0xd8(%rsp), %rdi
callq 0x18f10
jmp 0x188a9
jmp 0x1891c
jmp 0x1891e
jmp 0x18920
leaq 0x1b0(%rsp), %rdi
callq 0x19650
jmp 0x1830d
leaq 0x210(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x19680
movq %rax, 0xb8(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x19350
movq %rax, 0xb0(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x19490
testb $0x1, %al
jne 0x1898a
jmp 0x18a7b
leaq 0xb8(%rsp), %rdi
callq 0x196b0
movq %rax, 0xa8(%rsp)
movq 0xa8(%rsp), %rax
addq $0x8, %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x18dd0
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x18e00
movq %rax, 0x90(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x18e30
testb $0x1, %al
jne 0x189f8
jmp 0x18a50
leaq 0x98(%rsp), %rdi
callq 0x18e70
movq 0x80(%rsp), %rdi
movq %rax, 0x88(%rsp)
addq $0x10, %rdi
movq 0xa8(%rsp), %rsi
callq 0x19250
movq %rax, (%rsp)
jmp 0x18a2c
movq (%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x18c80
jmp 0x18a3f
jmp 0x18a41
leaq 0x98(%rsp), %rdi
callq 0x18f10
jmp 0x189dd
movq 0x290(%rsp), %rdi
movq 0xa8(%rsp), %rsi
callq 0x196d0
jmp 0x18a67
jmp 0x18a69
leaq 0xb8(%rsp), %rdi
callq 0x19700
jmp 0x1896c
leaq 0x1c0(%rsp), %rdi
callq 0x18d30
leaq 0x1d8(%rsp), %rdi
callq 0x18c20
leaq 0x210(%rsp), %rdi
callq 0x18c20
leaq 0x248(%rsp), %rdi
callq 0x19730
addq $0x2a8, %rsp            # imm = 0x2A8
retq
movq 0x170(%rsp), %rdi
callq 0x3400
nopw %cs:(%rax,%rax)