// File: /workspace/github_cpp_makefile_star2_O3/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 0x4a70
leaq 0x18(%r14), %rsi
leaq -0x98(%rbp), %rdi
callq 0x4a70
movq 0x18(%rbx), %rsi
addq $0x60, %rsi
leaq -0x80(%rbp), %rdi
callq 0x4af0
movq %rbx, -0xa8(%rbp)
addq $0x60, %r14
leaq -0xd8(%rbp), %rdi
movq %r14, %rsi
callq 0x4af0
movq -0xc0(%rbp), %r13
movq -0xb8(%rbp), %r12
movq %r12, %rax
subq %r13, %rax
sarq $0x3, %rax
movq %rax, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x78(%rbp), %rbx
movq -0x98(%rbp), %r15
movq -0x90(%rbp), %r14
movq %r14, -0x100(%rbp)
movq %r15, -0xf8(%rbp)
cmpq %r13, %r12
je 0x3f97
bsrq -0xa0(%rbp), %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x15c(%rip), %rcx      # 0x3e10
movq %r13, %rdi
movq %r12, %rsi
callq 0x4b70
leaq -0x16e(%rip), %rdx      # 0x3e10
movq %r13, %rdi
movq %r12, %rsi
callq 0x4c9b
movq -0x98(%rbp), %r15
movq -0x90(%rbp), %r14
cmpq %r14, %r15
je 0x3fd7
movq %r14, %rax
subq %r15, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x1aa(%rip), %rcx      # 0x3e10
movq %r15, %rdi
movq %r14, %rsi
callq 0x4b70
leaq -0x1bc(%rip), %rdx      # 0x3e10
movq %r15, %rdi
movq %r14, %rsi
callq 0x4c9b
movq -0x80(%rbp), %r14
movq -0x78(%rbp), %r15
cmpq %r15, %r14
je 0x401f
movq %r15, %rax
subq %r14, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x1e8(%rip), %rcx      # 0x3e1a
movq %r14, %rdi
movq %r15, %rsi
callq 0x5033
leaq -0x1fa(%rip), %rdx      # 0x3e1a
movq %r14, %rdi
movq %r15, %rsi
callq 0x515e
movq -0xd8(%rbp), %r13
movq -0xd0(%rbp), %r15
cmpq %r15, %r13
movq %rbx, -0xe8(%rbp)
je 0x4084
movq %r15, %rax
subq %r13, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x23d(%rip), %rcx      # 0x3e1a
movq %r13, %rdi
movq %r15, %rsi
callq 0x5033
leaq -0x24f(%rip), %rdx      # 0x3e1a
movq %r13, %rdi
movq %r15, %rsi
callq 0x515e
movq -0xd8(%rbp), %r13
movq -0xd0(%rbp), %rdi
jmp 0x4087
movq %r13, %rdi
movq -0xc0(%rbp), %rdx
movq -0xb8(%rbp), %rcx
movq -0x8(%rcx), %r8
movq %rcx, %r12
subq %rdx, %r12
sarq $0x3, %r12
movq -0x98(%rbp), %rax
movq -0x90(%rbp), %rsi
movq -0x8(%rsi), %r9
movq %rsi, %rbx
movq %rax, -0x40(%rbp)
subq %rax, %rbx
sarq $0x3, %rbx
movq -0x80(%rbp), %rax
movq -0x78(%rbp), %r10
movq -0x8(%r10), %r11
movq %r10, %r14
movq %rax, -0x38(%rbp)
subq %rax, %r14
sarq $0x3, %r14
movq %rdi, %r15
subq %r13, %r15
sarq $0x3, %r15
movq -0x8(%rdi), %rdi
movl 0x1c(%r11), %r10d
movl 0x1c(%rdi), %eax
movl 0x4(%r9), %edi
cmpl %eax, %r10d
cmovgl %r10d, %eax
movl 0x4(%r8), %r8d
cmpl %eax, %edi
cmovgl %edi, %eax
cmpl %eax, %r8d
cmovgl %r8d, %eax
movl %eax, -0x68(%rbp)
movq -0xa8(%rbp), %rax
movq 0x18(%rax), %rdi
movq 0x38(%rdi), %r8
movq 0x50(%rdi), %r11
subq 0x30(%rdi), %r8
shrq $0x3, %r8
subq 0x48(%rdi), %r11
shrq $0x3, %r11
addl %r8d, %r11d
movq %r14, -0x50(%rbp)
movq %r14, %xmm1
movq 0x2f39(%rip), %xmm3     # 0x7080
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
movapd 0x2f3d(%rip), %xmm4     # 0x7090
subpd %xmm4, %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movq %r15, -0x48(%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 %r12, %rcx
movq %r12, %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 %rbx, -0x58(%rbp)
movq %rbx, %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 0x2e8f(%rip), %xmm4     # 0x7058
movapd 0x2e9f(%rip), %xmm5     # 0x7070
xorpd %xmm9, %xmm9
xorpd %xmm10, %xmm10
xorpd %xmm11, %xmm11
movl %r11d, %r12d
xorl %esi, %esi
xorl %ebx, %ebx
movq %rdx, -0x30(%rbp)
movq %r13, -0x108(%rbp)
movslq %r11d, %rdi
movslq %r12d, %r14
cmpq %rdi, %rcx
je 0x4203
cmpq %r14, -0x58(%rbp)
jne 0x4222
movslq %r15d, %r8
cmpq %r8, -0x50(%rbp)
je 0x43de
movslq %esi, %r10
cmpq %r10, -0x48(%rbp)
je 0x43de
cmpq %rdi, %rcx
je 0x422e
movslq %r15d, %r8
cmpq %r14, -0x58(%rbp)
jne 0x4245
movslq %esi, %r10
movq -0x38(%rbp), %rax
movq (%rax,%r8,8), %r9
addq $0x1c, %r9
movq (%r13,%r10,8), %r8
addq $0x1c, %r8
jmp 0x42be
cmpq %r8, -0x50(%rbp)
je 0x4254
movslq %esi, %r10
cmpq %r10, -0x48(%rbp)
jne 0x426a
movq (%rdx,%rdi,8), %r9
addq $0x4, %r9
movq -0x40(%rbp), %rax
movq (%rax,%r14,8), %r8
addq $0x4, %r8
jmp 0x42be
movq (%rdx,%rdi,8), %r9
addq $0x4, %r9
movq -0x40(%rbp), %rax
movq (%rax,%r14,8), %rdx
leaq 0x4(%rdx), %rax
movq %rax, -0x60(%rbp)
movq -0x38(%rbp), %rax
movq (%rax,%r8,8), %r8
movq (%r13,%r10,8), %r10
movl 0x1c(%r10), %eax
addq $0x1c, %r10
movl 0x1c(%r8), %r13d
addq $0x1c, %r8
cmpl %r13d, %eax
cmovll %eax, %r13d
cmovlq %r10, %r8
cmpl 0x4(%rdx), %r13d
movq -0x30(%rbp), %rdx
movq -0x108(%rbp), %r13
cmovgeq -0x60(%rbp), %r8
movl (%r8), %eax
movl (%r9), %r9d
cmpl %r9d, %eax
cmovll %eax, %r9d
movl %r11d, %eax
subl %ebx, %eax
cltq
movq (%rdx,%rax,8), %rax
cmpl %r9d, 0x4(%rax)
je 0x42f1
movl %r12d, %eax
subl %ebx, %eax
cltq
movq -0x40(%rbp), %r8
movq (%r8,%rax,8), %rax
cmpl %r9d, 0x4(%rax)
jne 0x4316
movq (%rdx,%rdi,8), %rax
movq -0x40(%rbp), %rdx
movq (%rdx,%r14,8), %rdx
movl 0x4(%rdx), %edx
cmpl %edx, 0x4(%rax)
jne 0x430a
incl %r11d
jmp 0x4311
addsd %xmm4, %xmm9
jle 0x4350
incl %r12d
jmp 0x4353
movslq %r15d, %rax
movq -0x38(%rbp), %rdi
movq (%rdi,%rax,8), %rdi
movslq %esi, %rax
movq (%r13,%rax,8), %r8
movl 0x1c(%r8), %eax
cmpl %eax, 0x1c(%rdi)
jne 0x4392
movsd 0x10(%rdi), %xmm6
subsd 0x10(%r8), %xmm6
andpd %xmm5, %xmm6
addsd %xmm6, %xmm10
addsd %xmm4, %xmm11
incl %r15d
jmp 0x4399
incl %r11d
movq -0x30(%rbp), %rdx
movslq %r11d, %rax
cmpq %rax, %rcx
jne 0x436d
xorps %xmm6, %xmm6
cvtsi2sd %r12d, %xmm6
movapd %xmm3, %xmm7
jmp 0x4382
movslq %r12d, %rax
cmpq %rax, -0x58(%rbp)
jne 0x43d4
xorps %xmm6, %xmm6
cvtsi2sd %r11d, %xmm6
movapd %xmm2, %xmm7
subsd %xmm6, %xmm7
addsd %xmm7, %xmm8
movl $0x1, %ebx
jmp 0x43d4
addsd %xmm4, %xmm9
jle 0x439d
incl %esi
jmp 0x43a0
incl %r15d
movslq %r15d, %rax
cmpq %rax, -0x50(%rbp)
jne 0x43b6
xorps %xmm6, %xmm6
cvtsi2sd %esi, %xmm6
movapd %xmm1, %xmm7
jmp 0x43cb
movslq %esi, %rax
cmpq %rax, -0x48(%rbp)
jne 0x43d4
xorps %xmm6, %xmm6
cvtsi2sd %r15d, %xmm6
movapd %xmm0, %xmm7
subsd %xmm6, %xmm7
addsd %xmm7, %xmm8
cmpl -0x68(%rbp), %r9d
jl 0x41f2
movsd %xmm11, -0x68(%rbp)
movsd %xmm10, -0x50(%rbp)
movsd %xmm9, -0x40(%rbp)
movsd %xmm8, -0x58(%rbp)
movq -0xa8(%rbp), %rax
movsd 0x20(%rax), %xmm0
movsd %xmm0, -0xe0(%rbp)
movsd 0x28(%rax), %xmm0
movsd %xmm0, -0x60(%rbp)
movsd 0x30(%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
testq %r13, %r13
je 0x4447
movq -0xc8(%rbp), %rsi
subq %r13, %rsi
movq %r13, %rdi
callq 0x1110
movq -0x80(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
movq -0xe8(%rbp), %rbx
je 0x4465
movq -0x38(%rbp), %rdi
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x98(%rbp), %rdi
testq %rdi, %rdi
je 0x4480
movq -0x88(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x449b
movq -0xb0(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movsd -0x50(%rbp), %xmm0
divsd -0x68(%rbp), %xmm0
movsd -0x48(%rbp), %xmm3
mulsd %xmm0, %xmm3
subq -0xf0(%rbp), %rbx
sarq $0x3, %rbx
addq -0xa0(%rbp), %rbx
movq -0x100(%rbp), %rax
subq -0xf8(%rbp), %rax
sarq $0x2, %rax
cmpq %rax, %rbx
cmovaq %rbx, %rax
movsd -0x58(%rbp), %xmm2
mulsd -0xe0(%rbp), %xmm2
movq %rax, %xmm0
punpckldq 0x2b8d(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x2b95(%rip), %xmm0     # 0x7090
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
divsd %xmm1, %xmm2
movsd -0x40(%rbp), %xmm0
mulsd -0x60(%rbp), %xmm0
divsd %xmm1, %xmm0
addsd %xmm2, %xmm0
addsd %xmm3, %xmm0
ucomisd -0x30(%rbp), %xmm0
setbe %al
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x4568
movq %rax, %rbx
jmp 0x457d
movq %rax, %rbx
jmp 0x4598
movq %rax, %rbx
movq -0xd8(%rbp), %rdi
testq %rdi, %rdi
je 0x4568
movq -0xc8(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x80(%rbp), %rdi
testq %rdi, %rdi
je 0x457d
movq -0x70(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0x98(%rbp), %rdi
testq %rdi, %rdi
je 0x4598
movq -0x88(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x45b3
movq -0xb0(%rbp), %rsi
subq %rdi, %rsi
callq 0x1110
movq %rbx, %rdi
callq 0x11a0
nop