// File: /workspace/github_cpp_makefile_star2_O2/samuel500[P]NEAT/species.cpp
// Function: Species::is_compatible(Individual*)
bool Species::is_compatible(Individual *candidate){


	double delta = 0.;

	double N;
	// cout << "comp0" << endl;

	vector<Node*> rep_nodes = rep->nodes;
	// cout << "comp1" << endl;

	vector<Node*> cand_nodes = candidate->nodes;

	vector<Connection*> rep_cons = rep->connections;
	vector<Connection*> cand_cons = candidate->connections;

	N = max(rep_nodes.size()+rep_cons.size(), cand_nodes.size()+cand_nodes.size());

	// if(N<20) N = 1;

	sort(rep_nodes.begin(), rep_nodes.end(), nodePtr_compare);
	sort(cand_nodes.begin(), cand_nodes.end(), nodePtr_compare);

	sort(rep_cons.begin(), rep_cons.end(), consPtr_compare);
	sort(cand_cons.begin(), cand_cons.end(), consPtr_compare);

	int end_mark = max(rep_nodes[rep_nodes.size()-1]->hist_marking, max(cand_nodes[cand_nodes.size()-1]->hist_marking, max(rep_cons[rep_cons.size()-1]->hist_marking, cand_cons[cand_cons.size()-1]->hist_marking)));

	double E, D, W, nW;
	E=D=W=nW=0.;

	int rep_n_cursor, cand_n_cursor, rep_c_cursor, cand_c_cursor;
	rep_n_cursor=cand_n_cursor = rep->inputs.size()+rep->outputs.size(); // exclude input and output nodes, otherwise = 0;
	rep_c_cursor=cand_c_cursor = 0;

	int marking_cursor = rep_n_cursor; 

	int offset_n = 0; // 
	do{

		// todo: deal with case of no node (also no connection?)
		if((rep_n_cursor==rep_nodes.size() || cand_n_cursor==cand_nodes.size()) && (rep_c_cursor==rep_cons.size() || cand_c_cursor==cand_cons.size())) break; 
		else if(rep_n_cursor==rep_nodes.size() || cand_n_cursor==cand_nodes.size()) marking_cursor = min(rep_cons[rep_c_cursor]->hist_marking, cand_cons[cand_c_cursor]->hist_marking); 
		else if(rep_c_cursor==rep_cons.size() || cand_c_cursor==cand_cons.size()) marking_cursor = min(rep_nodes[rep_n_cursor]->hist_marking, cand_nodes[cand_n_cursor]->hist_marking);
		else marking_cursor = min(rep_nodes[rep_n_cursor]->hist_marking, min(cand_nodes[cand_n_cursor]->hist_marking, min(rep_cons[rep_c_cursor]->hist_marking, cand_cons[cand_c_cursor]->hist_marking)));

		if(rep_nodes[rep_n_cursor - offset_n]->hist_marking==marking_cursor || cand_nodes[cand_n_cursor - offset_n]->hist_marking==marking_cursor){

			if(rep_nodes[rep_n_cursor]->hist_marking != cand_nodes[cand_n_cursor]->hist_marking){
				D += 1.;
				if(rep_nodes[rep_n_cursor]->hist_marking <= cand_nodes[cand_n_cursor]->hist_marking) rep_n_cursor++;
				else cand_n_cursor++;
			}
			else{
				rep_n_cursor++;
				cand_n_cursor++;
			}
			if(rep_n_cursor==rep_nodes.size()){
				E += cand_nodes.size()-(double)cand_n_cursor;
				offset_n = 1;
			}
			else if(cand_n_cursor==cand_nodes.size()){
				E += rep_nodes.size()-(double)rep_n_cursor;
				offset_n = 1;
			}
		}
		else{

			if(rep_cons[rep_c_cursor]->hist_marking != cand_cons[cand_c_cursor]->hist_marking){
				D++;
				if(rep_cons[rep_c_cursor]->hist_marking <= cand_cons[cand_c_cursor]->hist_marking) rep_c_cursor++;
				else cand_c_cursor++;
			}
			else{

				W += abs((rep_cons[rep_c_cursor]->weight - cand_cons[cand_c_cursor]->weight));
				nW += 1;


				rep_c_cursor++;
				cand_c_cursor++;

			}
			if(rep_c_cursor==rep_cons.size()) E += cand_cons.size()-(double)cand_c_cursor;
			else if(cand_c_cursor==cand_cons.size()) E += rep_cons.size()-(double)rep_c_cursor;

		}
	}while(marking_cursor<end_mark);

	W = W/nW;

	delta = c1*E/N + c2*D/N +c3*W;

	if(delta>max_d)return false;
	else return true;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq 0x18(%rdi), %rsi
addq $0x18, %rsi
leaq -0xc0(%rbp), %rdi
callq 0x460e
leaq 0x18(%r14), %rsi
leaq -0x90(%rbp), %rdi
callq 0x460e
movq 0x18(%rbx), %rsi
addq $0x60, %rsi
leaq -0x78(%rbp), %rdi
callq 0x4666
addq $0x60, %r14
leaq -0xa8(%rbp), %rdi
movq %r14, %rsi
callq 0x4666
movq -0xc0(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq -0x78(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0x127(%rip), %rdx      # 0x3ce0
movq %rdi, -0xd0(%rbp)
movq %rsi, -0xe8(%rbp)
callq 0x472e
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
leaq -0x14f(%rip), %rdx      # 0x3ce0
callq 0x472e
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rsi
leaq -0x159(%rip), %rdx      # 0x3cea
callq 0x4d4c
movq -0xa8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
leaq -0x173(%rip), %rdx      # 0x3cea
callq 0x4d4c
movq -0xc0(%rbp), %r14
movq -0xb8(%rbp), %rcx
movq -0x8(%rcx), %rdi
subq %r14, %rcx
sarq $0x3, %rcx
movq -0x90(%rbp), %rax
movq -0x88(%rbp), %rsi
movq -0x8(%rsi), %r8
movq %rax, -0x30(%rbp)
subq %rax, %rsi
sarq $0x3, %rsi
movq -0x78(%rbp), %rax
movq -0x70(%rbp), %r9
movq -0x8(%r9), %r10
movq %r9, %rdx
movq %rax, -0x48(%rbp)
subq %rax, %rdx
sarq $0x3, %rdx
movq -0xa8(%rbp), %rax
movq -0xa0(%rbp), %r9
movq -0x8(%r9), %r11
movq %r9, %r12
movq %rax, -0x40(%rbp)
subq %rax, %r12
sarq $0x3, %r12
movl 0x1c(%r10), %r9d
movl 0x1c(%r11), %eax
cmpl %eax, %r9d
cmovgl %r9d, %eax
movl 0x4(%r8), %r8d
cmpl %eax, %r8d
cmovgl %r8d, %eax
movl 0x4(%rdi), %edi
cmpl %eax, %edi
cmovgl %edi, %eax
movl %eax, -0x5c(%rbp)
movq %rbx, -0xc8(%rbp)
movq 0x18(%rbx), %rdi
movq 0x38(%rdi), %r8
movq 0x50(%rdi), %r15
subq 0x30(%rdi), %r8
subq 0x48(%rdi), %r15
shrq $0x3, %r8
shrq $0x3, %r15
addl %r8d, %r15d
movq %rdx, -0x50(%rbp)
movq %rdx, %xmm0
movq 0x3152(%rip), %xmm1     # 0x7080
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x3156(%rip), %xmm2     # 0x7090
subpd %xmm2, %xmm0
movapd %xmm0, %xmm3
unpckhpd %xmm0, %xmm3            # xmm3 = xmm3[1],xmm0[1]
addsd %xmm0, %xmm3
movq %r12, -0x38(%rbp)
movq %r12, %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
subpd %xmm2, %xmm0
movapd %xmm0, %xmm4
unpckhpd %xmm0, %xmm4            # xmm4 = xmm4[1],xmm0[1]
addsd %xmm0, %xmm4
movq %rcx, %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
subpd %xmm2, %xmm0
movapd %xmm0, %xmm5
unpckhpd %xmm0, %xmm5            # xmm5 = xmm5[1],xmm0[1]
addsd %xmm0, %xmm5
movq %rsi, -0x58(%rbp)
movq %rsi, %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
subpd %xmm2, %xmm0
movapd %xmm0, %xmm7
unpckhpd %xmm0, %xmm7            # xmm7 = xmm7[1],xmm0[1]
addsd %xmm0, %xmm7
xorl %esi, %esi
xorpd %xmm0, %xmm0
movsd 0x30ac(%rip), %xmm8     # 0x7058
movapd 0x30bb(%rip), %xmm9     # 0x7070
pxor %xmm1, %xmm1
xorpd %xmm2, %xmm2
xorpd %xmm6, %xmm6
movl %r15d, %r12d
xorl %r13d, %r13d
xorl %ebx, %ebx
movq %rcx, -0x100(%rbp)
movslq %r15d, %r9
movslq %r12d, %r10
cmpq %r9, %rcx
je 0x3fe1
cmpq %r10, -0x58(%rbp)
jne 0x4000
movslq %esi, %r8
cmpq %r8, -0x50(%rbp)
je 0x41be
movslq %r13d, %r11
cmpq %r11, -0x38(%rbp)
je 0x41be
cmpq %r9, %rcx
je 0x400c
movslq %esi, %r8
movslq %r13d, %r11
cmpq %r10, -0x58(%rbp)
jne 0x4029
movq -0x48(%rbp), %rax
movq (%rax,%r8,8), %rdi
addq $0x1c, %rdi
movq -0x40(%rbp), %rax
movq (%rax,%r11,8), %r8
addq $0x1c, %r8
jmp 0x40aa
cmpq %r8, -0x50(%rbp)
je 0x4035
cmpq %r11, -0x38(%rbp)
jne 0x404b
movq (%r14,%r9,8), %rdi
addq $0x4, %rdi
movq -0x30(%rbp), %rax
movq (%rax,%r10,8), %r8
addq $0x4, %r8
jmp 0x40aa
movq (%r14,%r9,8), %rdi
addq $0x4, %rdi
movq -0x30(%rbp), %rax
movq (%rax,%r10,8), %rdx
leaq 0x4(%rdx), %rax
movq %rax, -0x108(%rbp)
movq -0x48(%rbp), %rax
movq (%rax,%r8,8), %r8
movq -0x40(%rbp), %rax
movq (%rax,%r11,8), %r11
movl 0x1c(%r11), %eax
addq $0x1c, %r11
movq %r14, %rcx
movl 0x1c(%r8), %r14d
addq $0x1c, %r8
cmpl %r14d, %eax
cmovll %eax, %r14d
cmovlq %r11, %r8
cmpl 0x4(%rdx), %r14d
movq %rcx, %r14
movq -0x100(%rbp), %rcx
cmovgeq -0x108(%rbp), %r8
movl (%r8), %eax
movl (%rdi), %edi
cmpl %edi, %eax
cmovll %eax, %edi
movl %r15d, %eax
subl %ebx, %eax
cltq
movq (%r14,%rax,8), %rax
cmpl %edi, 0x4(%rax)
je 0x40d8
movl %r12d, %eax
subl %ebx, %eax
cltq
movq -0x30(%rbp), %rdx
movq (%rdx,%rax,8), %rax
cmpl %edi, 0x4(%rax)
jne 0x40fd
movq (%r14,%r9,8), %rax
movq -0x30(%rbp), %rdx
movq (%rdx,%r10,8), %rdx
movl 0x4(%rdx), %edx
cmpl %edx, 0x4(%rax)
jne 0x40f1
incl %r15d
jmp 0x40f8
addsd %xmm8, %xmm1
jle 0x413c
incl %r12d
jmp 0x413f
movslq %esi, %rax
movq -0x48(%rbp), %rdx
movq (%rdx,%rax,8), %r8
movslq %r13d, %rax
movq -0x40(%rbp), %rdx
movq (%rdx,%rax,8), %r9
movl 0x1c(%r9), %eax
cmpl %eax, 0x1c(%r8)
jne 0x4175
movsd 0x10(%r8), %xmm10
subsd 0x10(%r9), %xmm10
andpd %xmm9, %xmm10
addsd %xmm10, %xmm2
addsd %xmm8, %xmm6
incl %esi
jmp 0x417c
incl %r15d
movslq %r15d, %rax
cmpq %rax, %rcx
jne 0x4153
cvtsi2sd %r12d, %xmm10
movapd %xmm7, %xmm11
jmp 0x4166
movslq %r12d, %rax
cmpq %rax, -0x58(%rbp)
jne 0x41b5
cvtsi2sd %r15d, %xmm10
movapd %xmm5, %xmm11
subsd %xmm10, %xmm11
addsd %xmm11, %xmm0
pushq $0x1
popq %rbx
jmp 0x41b5
addsd %xmm8, %xmm1
jle 0x4181
incl %r13d
jmp 0x4183
incl %esi
movslq %esi, %rax
cmpq %rax, -0x50(%rbp)
jne 0x4198
cvtsi2sd %r13d, %xmm10
movapd %xmm4, %xmm11
jmp 0x41ab
movslq %r13d, %rax
cmpq %rax, -0x38(%rbp)
jne 0x41b5
cvtsi2sd %esi, %xmm10
movapd %xmm3, %xmm11
subsd %xmm10, %xmm11
addsd %xmm11, %xmm0
cmpl -0x5c(%rbp), %edi
jl 0x3fd0
divsd %xmm6, %xmm2
movq -0xe8(%rbp), %rcx
subq -0xd0(%rbp), %rcx
sarq $0x3, %rcx
movq -0xf8(%rbp), %rax
subq -0xd8(%rbp), %rax
sarq $0x3, %rax
addq %rcx, %rax
movq -0xf0(%rbp), %rcx
subq -0xe0(%rbp), %rcx
sarq $0x2, %rcx
cmpq %rcx, %rax
cmovaq %rax, %rcx
movq %rcx, %xmm3
punpckldq 0x2e71(%rip), %xmm3 # xmm3 = xmm3[0],mem[0],xmm3[1],mem[1]
subpd 0x2e79(%rip), %xmm3     # 0x7090
movapd %xmm3, %xmm4
unpckhpd %xmm3, %xmm4            # xmm4 = xmm4[1],xmm3[1]
movq -0xc8(%rbp), %rax
mulsd 0x20(%rax), %xmm0
addsd %xmm3, %xmm4
divsd %xmm4, %xmm0
mulsd 0x28(%rax), %xmm1
divsd %xmm4, %xmm1
addsd %xmm0, %xmm1
mulsd 0x30(%rax), %xmm2
addsd %xmm1, %xmm2
ucomisd 0x38(%rax), %xmm2
setbe %bl
leaq -0xa8(%rbp), %rdi
callq 0x2584
leaq -0x78(%rbp), %rdi
callq 0x2584
leaq -0x90(%rbp), %rdi
callq 0x2546
leaq -0xc0(%rbp), %rdi
callq 0x2546
movl %ebx, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x42b0
movq %rax, %rbx
jmp 0x42b9
movq %rax, %rbx
jmp 0x42c5
movq %rax, %rbx
leaq -0xa8(%rbp), %rdi
callq 0x2584
leaq -0x78(%rbp), %rdi
callq 0x2584
leaq -0x90(%rbp), %rdi
callq 0x2546
leaq -0xc0(%rbp), %rdi
callq 0x2546
movq %rbx, %rdi
callq 0x1180
nop