// File: /workspace/github_cpp_makefile_star2_O1/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 $0xd8, %rsp
movq %rsi, %r14
movq %rdi, %r12
movq 0x18(%rdi), %rsi
addq $0x18, %rsi
leaq -0xa8(%rbp), %rdi
callq 0x4b16
leaq 0x18(%r14), %rsi
leaq -0x90(%rbp), %rdi
callq 0x4b16
movq 0x18(%r12), %rsi
addq $0x60, %rsi
leaq -0x78(%rbp), %rdi
callq 0x4b96
addq $0x60, %r14
leaq -0xc0(%rbp), %rdi
movq %r14, %rsi
callq 0x4b96
movq -0xa8(%rbp), %r15
movq -0xa0(%rbp), %r14
movq %r14, %rbx
subq %r15, %rbx
sarq $0x3, %rbx
movq -0x78(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0xf8(%rbp)
cmpq %r15, %r14
je 0x4027
bsrq %rbx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x16a(%rip), %rcx      # 0x3ea0
movq %r15, %rdi
movq %r14, %rsi
callq 0x4c16
leaq -0x17c(%rip), %rdx      # 0x3ea0
movq %r15, %rdi
movq %r14, %rsi
callq 0x4d41
movq -0x90(%rbp), %r14
movq -0x88(%rbp), %r15
cmpq %r15, %r14
je 0x4075
movq %r15, %rax
subq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x1b8(%rip), %rcx      # 0x3ea0
movq %r14, %rdi
movq %r15, %rsi
callq 0x4c16
leaq -0x1ca(%rip), %rdx      # 0x3ea0
movq %r14, %rdi
movq %r15, %rsi
callq 0x4d41
movq -0x78(%rbp), %r14
movq -0x70(%rbp), %r15
cmpq %r15, %r14
je 0x40bd
movq %r15, %rax
subq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x1f6(%rip), %rcx      # 0x3eaa
movq %r14, %rdi
movq %r15, %rsi
callq 0x5100
leaq -0x208(%rip), %rdx      # 0x3eaa
movq %r14, %rdi
movq %r15, %rsi
callq 0x522b
movq -0xc0(%rbp), %r14
movq -0xb8(%rbp), %r15
cmpq %r15, %r14
je 0x410b
movq %r15, %rax
subq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x244(%rip), %rcx      # 0x3eaa
movq %r14, %rdi
movq %r15, %rsi
callq 0x5100
leaq -0x256(%rip), %rdx      # 0x3eaa
movq %r14, %rdi
movq %r15, %rsi
callq 0x522b
movq %rbx, -0xe0(%rbp)
movq -0xa8(%rbp), %rax
movq -0xa0(%rbp), %rcx
movq -0x8(%rcx), %rdi
subq %rax, %rcx
sarq $0x3, %rcx
movq -0x90(%rbp), %rdx
movq -0x88(%rbp), %rsi
movq -0x8(%rsi), %r8
movq %rdx, -0x30(%rbp)
subq %rdx, %rsi
sarq $0x3, %rsi
movq -0x78(%rbp), %rdx
movq -0x70(%rbp), %r9
movq -0x8(%r9), %r10
movq %r9, %rbx
movq %rdx, -0x48(%rbp)
subq %rdx, %rbx
sarq $0x3, %rbx
movq -0xc0(%rbp), %rdx
movq -0xb8(%rbp), %r9
movq -0x8(%r9), %r11
movq %r9, %r15
movq %rdx, -0x58(%rbp)
subq %rdx, %r15
sarq $0x3, %r15
movl 0x1c(%r10), %r9d
movl 0x1c(%r11), %edx
movq %rax, %r11
movl 0x4(%r8), %r8d
cmpl %edx, %r9d
cmovgl %r9d, %edx
movl 0x4(%rdi), %edi
cmpl %edx, %r8d
cmovgl %r8d, %edx
cmpl %edx, %edi
cmovgl %edi, %edx
movl %edx, -0x60(%rbp)
movq %r12, -0xd8(%rbp)
movq 0x18(%r12), %rdi
movq 0x38(%rdi), %r8
movq 0x50(%rdi), %r14
subq 0x30(%rdi), %r8
shrq $0x3, %r8
subq 0x48(%rdi), %r14
shrq $0x3, %r14
addl %r8d, %r14d
movq %rbx, -0x40(%rbp)
movq %rbx, %xmm1
movq 0x2e9e(%rip), %xmm3     # 0x7080
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x2ea2(%rip), %xmm4     # 0x7090
subpd %xmm4, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movq %r15, -0x38(%rbp)
movq %r15, %xmm2
punpckldq %xmm3, %xmm2    # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
subpd %xmm4, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
movq %rcx, %xmm5
punpckldq %xmm3, %xmm5    # xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1]
subpd %xmm4, %xmm5
movapd %xmm5, %xmm2
unpckhpd %xmm5, %xmm2            # xmm2 = xmm2[1],xmm5[1]
addsd %xmm5, %xmm2
movq %rsi, %xmm5
punpckldq %xmm3, %xmm5    # xmm5 = xmm5[0],xmm3[0],xmm5[1],xmm3[1]
subpd %xmm4, %xmm5
movapd %xmm5, %xmm3
unpckhpd %xmm5, %xmm3            # xmm3 = xmm3[1],xmm5[1]
addsd %xmm5, %xmm3
xorl %r15d, %r15d
xorpd %xmm8, %xmm8
movsd 0x2dfb(%rip), %xmm4     # 0x7058
movapd 0x2e0b(%rip), %xmm5     # 0x7070
xorpd %xmm9, %xmm9
xorpd %xmm10, %xmm10
xorpd %xmm11, %xmm11
movl %r14d, %ebx
xorl %r12d, %r12d
xorl %r13d, %r13d
movq %rax, -0x50(%rbp)
movslq %r14d, %r8
movslq %ebx, %r9
movslq %r15d, %rdi
cmpq %r8, %rcx
je 0x4294
cmpq %r9, %rsi
jne 0x42ab
cmpq %rdi, -0x40(%rbp)
je 0x4483
movslq %r12d, %r10
cmpq %r10, -0x38(%rbp)
je 0x4483
cmpq %r8, %rcx
je 0x42b5
cmpq %r9, %rsi
jne 0x432e
movq -0x48(%rbp), %rax
movq (%rax,%rdi,8), %r11
leaq 0x1c(%r11), %rdx
movslq %r12d, %r10
movq -0x58(%rbp), %rax
movq (%rax,%r10,8), %r10
movl 0x1c(%r10), %eax
addq $0x1c, %r10
cmpl 0x1c(%r11), %eax
movq -0x50(%rbp), %r11
cmovgeq %rdx, %r10
movl (%r10), %r10d
movl %r14d, %eax
subl %r13d, %eax
cltq
movq (%r11,%rax,8), %rax
cmpl %r10d, 0x4(%rax)
je 0x430a
movl %ebx, %eax
subl %r13d, %eax
cltq
movq -0x30(%rbp), %rdx
movq (%rdx,%rax,8), %rax
cmpl %r10d, 0x4(%rax)
jne 0x4362
movq (%r11,%r8,8), %rax
movq -0x30(%rbp), %rdx
movq (%rdx,%r9,8), %rdx
movl 0x4(%rdx), %edx
cmpl %edx, 0x4(%rax)
jne 0x4323
incl %r14d
jmp 0x432a
addsd %xmm4, %xmm9
jle 0x439c
incl %ebx
jmp 0x439f
cmpq %rdi, -0x40(%rbp)
je 0x4341
movslq %r12d, %r10
cmpq %r10, -0x38(%rbp)
jne 0x43ec
movq (%r11,%r8,8), %rax
leaq 0x4(%rax), %rdx
movq -0x30(%rbp), %r10
movq (%r10,%r9,8), %r10
movl 0x4(%r10), %r11d
addq $0x4, %r10
cmpl 0x4(%rax), %r11d
jmp 0x42d8
movq -0x48(%rbp), %rax
movq (%rax,%rdi,8), %rdi
movslq %r12d, %rax
movq -0x58(%rbp), %rdx
movq (%rdx,%rax,8), %r8
movl 0x1c(%r8), %eax
cmpl %eax, 0x1c(%rdi)
jne 0x43e0
movsd 0x10(%rdi), %xmm6
subsd 0x10(%r8), %xmm6
andpd %xmm5, %xmm6
addsd %xmm6, %xmm10
addsd %xmm4, %xmm11
incl %r15d
jmp 0x43e7
incl %r14d
movslq %r14d, %rax
cmpq %rax, %rcx
jne 0x43b4
xorps %xmm6, %xmm6
cvtsi2sd %ebx, %xmm6
movapd %xmm3, %xmm7
jmp 0x43cc
movslq %ebx, %rax
cmpq %rax, %rsi
jne 0x4479
xorps %xmm6, %xmm6
cvtsi2sd %r14d, %xmm6
movapd %xmm2, %xmm7
subsd %xmm6, %xmm7
addsd %xmm7, %xmm8
movl $0x1, %r13d
jmp 0x4479
addsd %xmm4, %xmm9
jle 0x4441
incl %r12d
jmp 0x4444
movq -0x48(%rbp), %rax
movq (%rax,%rdi,8), %rax
movq -0x58(%rbp), %rdx
movq (%rdx,%r10,8), %rdx
movl 0x1c(%rdx), %r10d
cmpl 0x1c(%rax), %r10d
leaq 0x1c(%rdx), %r10
cmovgeq %rax, %rdx
leaq 0x1c(%rax), %rax
cmovgeq %rax, %r10
movq -0x30(%rbp), %rax
movq (%rax,%r9,8), %rax
movl 0x1c(%rdx), %edx
cmpl 0x4(%rax), %edx
leaq 0x4(%rax), %rax
cmovgeq %rax, %r10
movq (%r11,%r8,8), %rax
movl (%r10), %edx
cmpl 0x4(%rax), %edx
leaq 0x4(%rax), %rax
cmovgeq %rax, %r10
jmp 0x42e0
incl %r15d
movslq %r15d, %rax
cmpq %rax, -0x40(%rbp)
jne 0x445b
xorps %xmm6, %xmm6
cvtsi2sd %r12d, %xmm6
movapd %xmm1, %xmm7
jmp 0x4470
movslq %r12d, %rax
cmpq %rax, -0x38(%rbp)
jne 0x4479
xorps %xmm6, %xmm6
cvtsi2sd %r15d, %xmm6
movapd %xmm0, %xmm7
subsd %xmm6, %xmm7
addsd %xmm7, %xmm8
cmpl -0x60(%rbp), %r10d
jl 0x4281
movsd %xmm11, -0x60(%rbp)
movsd %xmm10, -0x40(%rbp)
movsd %xmm9, -0x48(%rbp)
movsd %xmm8, -0x30(%rbp)
movq -0xd8(%rbp), %rax
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd 0x28(%rax), %xmm0
movsd %xmm0, -0xd0(%rbp)
movsd 0x30(%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x50(%rbp)
movq -0x58(%rbp), %rdi
testq %rdi, %rdi
je 0x44e8
movq -0xb0(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x78(%rbp), %rdi
testq %rdi, %rdi
movq -0xe0(%rbp), %rbx
je 0x4504
movq -0x68(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x451c
movq -0x80(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0xa8(%rbp), %rdi
testq %rdi, %rdi
je 0x4537
movq -0x98(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movsd -0x40(%rbp), %xmm0
divsd -0x60(%rbp), %xmm0
movsd -0x38(%rbp), %xmm3
mulsd %xmm0, %xmm3
movq -0x100(%rbp), %rax
subq -0xe8(%rbp), %rax
sarq $0x3, %rax
addq %rbx, %rax
movq -0xf8(%rbp), %rcx
subq -0xf0(%rbp), %rcx
sarq $0x2, %rcx
cmpq %rcx, %rax
cmovaq %rax, %rcx
movsd -0x30(%rbp), %xmm2
mulsd -0xc8(%rbp), %xmm2
movq %rcx, %xmm0
punpckldq 0x2aee(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x2af6(%rip), %xmm0     # 0x7090
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
divsd %xmm1, %xmm2
movsd -0x48(%rbp), %xmm0
mulsd -0xd0(%rbp), %xmm0
divsd %xmm1, %xmm0
addsd %xmm2, %xmm0
addsd %xmm3, %xmm0
ucomisd -0x50(%rbp), %xmm0
setbe %al
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x460a
movq %rax, %rbx
jmp 0x461f
movq %rax, %rbx
jmp 0x4637
movq %rax, %rbx
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x460a
movq -0xb0(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x78(%rbp), %rdi
testq %rdi, %rdi
je 0x461f
movq -0x68(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x4637
movq -0x80(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0xa8(%rbp), %rdi
testq %rdi, %rdi
je 0x4652
movq -0x98(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq %rbx, %rdi
callq 0x11a0