// File: /workspace/github_cpp_makefile_star2_O1/EduBic[P]TSP-MetaheuristicSolvers/./neighborimprovement.h
// Function: FirstImprovement::execute(TSP const&, TSPSolution const&, move&)
double execute(const TSP& tsp , const TSPSolution& currSol, TSPMove& move) {
        //cout << endl << endl << "-------------- find neighbor --------------";


        double bestCostVariation = tsp.infinite;

        for ( uint a = 1 ; a < currSol.sequence.size() - 2 ; a++ ) {

            int h = currSol.sequence[a-1];
            int i = currSol.sequence[a];

            for ( uint b = a + 1 ; b < currSol.sequence.size() - 1 ; b++ ) {
                int j = currSol.sequence[b];
                int l = currSol.sequence[b+1];

                // incremental evaluation --> bestCostVariation (instead of best cost)
                double neighCostVariation = - tsp.cost[h][i] - tsp.cost[j][l]
                                            + tsp.cost[h][j] + tsp.cost[i][l];

                if (neighCostVariation < bestCostVariation ) {
                    // neighbor better of precedent neighbors
                    bestCostVariation = neighCostVariation;
                    move.from = a;
                    move.to = b;

                    double currentBestValueFound = currSol.evaluateObjectiveFunction(tsp);

                    // on first improvement exit
                    //cout << endl << "Move from " << a << " to " << b;
                    //cout << "\tNeighbor Value = " << currentBestValueFound + bestCostVariation << " - CurrentBestValue = " << currentBestValueFound;
                    if (currentBestValueFound + bestCostVariation < currentBestValueFound) {
                        //cout << "\tIt's an improvement, chose it!" << endl;
                        //cout << "------------------------" << endl;
                        return bestCostVariation;
                    }
                }
            }
        }

        //cout << endl << "------------------------------" << endl;
        return bestCostVariation;
    }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, -0x10(%rsp)
movsd 0x20(%rsi), %xmm3
movq (%rdx), %rax
movq 0x8(%rdx), %rdx
subq %rax, %rdx
sarq $0x2, %rdx
leaq -0x2(%rdx), %rsi
movq %rsi, -0x8(%rsp)
decq %rdx
movl $0x1, %r8d
movapd 0x6a6(%rip), %xmm1      # 0x82f0
movl %r8d, %r9d
cmpq %r9, -0x8(%rsp)
jbe 0x7d54
leal -0x1(%r8), %r10d
movslq (%rax,%r10,4), %rbx
movslq (%rax,%r9,4), %r10
leal 0x1(%r8), %edi
movq -0x10(%rsp), %rsi
movq 0x8(%rsi), %r11
leaq (%rbx,%rbx,2), %rbx
leaq (%r11,%rbx,8), %r14
leaq (%r10,%r10,2), %rbx
leaq (%r11,%rbx,8), %r15
movl %edi, -0x14(%rsp)
movl %edi, %r12d
movl %r12d, %ebx
cmpq %rbx, %rdx
jbe 0x7d3a
movl %r12d, %r13d
movslq (%rax,%rbx,4), %rbp
leal 0x1(%r13), %r12d
movslq (%rax,%r12,4), %rdi
movq (%r14), %rsi
movsd (%rsi,%r10,8), %xmm2
xorpd %xmm1, %xmm2
leaq (%rbp,%rbp,2), %r9
movq (%r11,%r9,8), %r9
subsd (%r9,%rdi,8), %xmm2
addsd (%rsi,%rbp,8), %xmm2
movq (%r15), %rsi
addsd (%rsi,%rdi,8), %xmm2
movb $0x1, %bpl
ucomisd %xmm2, %xmm3
jbe 0x7d27
movl %r8d, (%rcx)
movl %r13d, 0x4(%rcx)
xorpd %xmm3, %xmm3
xorl %r13d, %r13d
movslq (%rax,%r13,4), %rsi
incq %r13
movl %r13d, %edi
movslq (%rax,%rdi,4), %r9
leaq (%rsi,%rsi,2), %rsi
movq (%r11,%rsi,8), %rsi
addsd (%rsi,%r9,8), %xmm3
cmpq %rdi, %rdx
ja 0x7ce3
movapd %xmm2, %xmm4
addsd %xmm3, %xmm4
ucomisd %xmm4, %xmm3
cmpnltsd %xmm3, %xmm4
andpd %xmm4, %xmm0
andnpd %xmm2, %xmm4
orpd %xmm4, %xmm0
jbe 0x7d2b
xorl %ebp, %ebp
jmp 0x7d2b
movapd %xmm3, %xmm2
movapd %xmm2, %xmm3
testb %bpl, %bpl
jne 0x7c88
jmp 0x7d3e
movapd %xmm3, %xmm2
movl -0x14(%rsp), %esi
movl %esi, %r8d
movapd %xmm2, %xmm3
cmpq %rbx, %rdx
jbe 0x7c4a
jmp 0x7d58
movapd %xmm3, %xmm0
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop