// File: EduBic[P]TSP-MetaheuristicSolvers/LocalSearchSolver.cpp
// Function: LocalSearchSolver::solve(TSP const&, TSPSolution const&, TSPSolution&)
bool LocalSearchSolver::solve( const TSP& tsp , const TSPSolution& initSol , TSPSolution& bestSol ) {

    try {
        bool stop = false;
        int  iter = 0;

        TSPSolution currSol(initSol);
        double bestValue, currValue;

        bestValue = currValue = currSol.evaluateObjectiveFunction(tsp);
        TSPMove move;

        while (!stop) {
            if ( tsp.n < 20 ) {
                currSol.print(std::cout); //log current solution (only small instances)
            }

            std::cout << " (" << ++iter << ") value " << currValue << " (" << bestValue << ")";

            // first improvement
            // neigh = findFirstBestNeighbor(tsp, currSol, )
            // neighValue = compute neight obj fun value
            // if neighValue < currentBest then bestFound = currentBest = neightValue


            // incremental evaluation: findBestNeighbour returns the cost increment
            double bestNeighValue = currValue + findNeighbor->execute(tsp, currSol, move);

            std::cout << "\t move: " << move.from << " , " << move.to << std::endl;

            // stop criteria
            if (bestNeighValue < currValue) {
                bestValue = currValue = bestNeighValue;
                currSol = swap(currSol,move);
            }
            else {
                stop = true;    // exit from cycle
            }
        }

        bestSol = currSol;
        bestSol.iterations = iter;
    }
    catch (std::exception& e) {
        std::cout << ">>>EXCEPTION: " << e.what() << std::endl;
        return false;
    }

    return true;
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rdi, 0x138(%rsp)
movq %rsi, 0x130(%rsp)
movq %rdx, 0x128(%rsp)
movq %rcx, 0x120(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x88(%rsp)
movb $0x0, 0x11f(%rsp)
movl $0x0, 0x118(%rsp)
movq 0x128(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x9e80
jmp 0x9a11
movq 0x130(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x5bf0
movsd %xmm0, 0x80(%rsp)
jmp 0x9a31
movsd 0x80(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movsd %xmm0, 0xb0(%rsp)
movb 0x11f(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x9a5e
jmp 0x9d4b
movq 0x130(%rsp), %rax
cmpl $0x14, (%rax)
jge 0x9b4e
movq 0xa55a(%rip), %rsi      # 0x13fd0
leaq 0xc8(%rsp), %rdi
callq 0x8720
jmp 0x9a85
jmp 0x9b4e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
jmp 0x9ac1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xa060
movl 0xbc(%rsp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x9db9
movq 0xc0(%rsp), %rdi
callq 0x3110
movq %rax, 0x90(%rsp)
movq 0xa4df(%rip), %rdi      # 0x13fd0
leaq 0x479a(%rip), %rsi      # 0xe292
callq 0x3280
movq %rax, 0x78(%rsp)
jmp 0x9b04
movq 0x90(%rsp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq 0x78(%rsp), %rdi
movq %rax, %rsi
callq 0x3280
movq %rax, 0x70(%rsp)
jmp 0x9b29
movq 0x70(%rsp), %rdi
movq 0xa47b(%rip), %rsi      # 0x13fb0
callq 0x32b0
jmp 0x9b3c
movb $0x0, 0x147(%rsp)
callq 0x33d0
jmp 0x9da8
movq 0xa47b(%rip), %rdi      # 0x13fd0
leaq 0x471b(%rip), %rsi      # 0xe277
callq 0x3280
movq %rax, 0x68(%rsp)
jmp 0x9b68
movq 0x68(%rsp), %rdi
movl 0x118(%rsp), %esi
incl %esi
movl %esi, 0x118(%rsp)
callq 0x3410
movq %rax, 0x60(%rsp)
jmp 0x9b89
movq 0x60(%rsp), %rdi
leaq 0x46e5(%rip), %rsi      # 0xe27a
callq 0x3280
movq %rax, 0x58(%rsp)
jmp 0x9ba1
movq 0x58(%rsp), %rdi
movsd 0xa8(%rsp), %xmm0
callq 0x3460
movq %rax, 0x50(%rsp)
jmp 0x9bbb
movq 0x50(%rsp), %rdi
leaq 0x46b0(%rip), %rsi      # 0xe277
callq 0x3280
movq %rax, 0x48(%rsp)
jmp 0x9bd3
movq 0x48(%rsp), %rdi
movsd 0xb0(%rsp), %xmm0
callq 0x3460
movq %rax, 0x40(%rsp)
jmp 0x9bed
movq 0x40(%rsp), %rdi
leaq 0x468a(%rip), %rsi      # 0xe283
callq 0x3280
jmp 0x9c00
movq 0x88(%rsp), %rax
movsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x8(%rax), %rdi
movq 0x130(%rsp), %rsi
movq (%rdi), %rax
movq (%rax), %rax
leaq 0xc8(%rsp), %rdx
leaq 0xa0(%rsp), %rcx
callq *%rax
movsd %xmm0, 0x38(%rsp)
jmp 0x9c43
movsd 0x38(%rsp), %xmm1
movsd 0x30(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0xa36d(%rip), %rdi      # 0x13fd0
leaq 0x461b(%rip), %rsi      # 0xe285
callq 0x3280
movq %rax, 0x28(%rsp)
jmp 0x9c76
movq 0x28(%rsp), %rdi
movl 0xa0(%rsp), %esi
callq 0x3410
movq %rax, 0x20(%rsp)
jmp 0x9c8e
movq 0x20(%rsp), %rdi
leaq 0x45f4(%rip), %rsi      # 0xe28e
callq 0x3280
movq %rax, 0x18(%rsp)
jmp 0x9ca6
movq 0x18(%rsp), %rdi
movl 0xa4(%rsp), %esi
callq 0x3410
movq %rax, 0x10(%rsp)
jmp 0x9cbe
movq 0x10(%rsp), %rdi
movq 0xa2e6(%rip), %rsi      # 0x13fb0
callq 0x32b0
jmp 0x9cd1
movsd 0x98(%rsp), %xmm1
movsd 0xa8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x9d3e
movq 0x88(%rsp), %rdi
movsd 0x98(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
movsd %xmm0, 0xb0(%rsp)
leaq 0xc8(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x9dd0
movq %rax, 0x8(%rsp)
jmp 0x9d28
movq 0x8(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x9fb0
jmp 0x9d3c
jmp 0x9d46
movb $0x1, 0x11f(%rsp)
jmp 0x9a4c
movq 0x120(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x9fb0
jmp 0x9d62
movl 0x118(%rsp), %ecx
movq 0x120(%rsp), %rax
movl %ecx, 0x48(%rax)
leaq 0xc8(%rsp), %rdi
callq 0xa060
jmp 0x9da0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
callq 0x33d0
jmp 0x9d9e
jmp 0x9db9
movb $0x1, 0x147(%rsp)
movb 0x147(%rsp), %al
andb $0x1, %al
addq $0x148, %rsp            # imm = 0x148
retq
movq 0xc0(%rsp), %rdi
callq 0x3420
movq %rax, %rdi
callq 0x6770
nop