// File: /workspace/github_cpp_makefile_star2_O2/grmauri[P]pmm/pmm.cpp
// Function: simulated_annealing(double, int, double, double, double, tSolucao&, double&, double&)
void simulated_annealing(const double alfa, const int sa_max, const double temp_ini, const double temp_con,
                         const double tempo_max, Solucao &s, double &tempo_melhor, double &tempo_total)
{
    clock_t hI, hF;
    Solucao s_atual, s_vizinha;
    double temp, delta, x;
    printf("\n\n>>> EXECUTANDO O SA...\n\n");
    hI = clock();
    heuConAle(s);
    calcFO(s);
    hF = clock();
    tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
    #ifdef DBG
        printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
    #endif // DBG
    tempo_total = tempo_melhor;
    memcpy(&s_atual, &s, sizeof(s));
    while(tempo_total < tempo_max)
    {
        temp = temp_ini;
        while(temp > temp_con)
        {
            for(int i = 0; i < sa_max; i++)
            {
                memcpy(&s_vizinha, &s_atual, sizeof(s_atual));
                gerar_vizinha(s_vizinha);
                delta = s_atual.funObj - s_vizinha.funObj;
                if(delta < 0)
                {
                    memcpy(&s_atual, &s_vizinha, sizeof(s_vizinha));
                    if(s_vizinha.funObj > s.funObj)
                    {
                        memcpy(&s, &s_vizinha, sizeof(s_vizinha));
                        hF = clock();
                        tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
                        #ifdef DBG
                            printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
                        #endif // DBG
                    }
                }
                else
                {
                    x = rand()%1001;
                    x = x / 1000.0;
                    if(x < exp(-delta/temp))
                        memcpy(&s_atual, &s_vizinha, sizeof(s_vizinha));
                }
            }
            temp = temp * alfa;
            hF = clock();
            tempo_total = ((double)(hF - hI))/CLOCKS_PER_SEC;
            if(tempo_total >= tempo_max)
                break;
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1198, %rsp           # imm = 0x1198
movq %rcx, %r14
movq %rdx, %r12
movq %rsi, %r15
movsd %xmm3, 0x10(%rsp)
movsd %xmm2, 0x38(%rsp)
movsd %xmm1, 0x20(%rsp)
movl %edi, %ebx
movsd %xmm0, 0x28(%rsp)
leaq 0x2909(%rip), %rdi      # 0x553e
callq 0x21b0
callq 0x20b0
movq %rax, %r13
movq %r15, %rdi
callq 0x38af
movq %r15, %rdi
callq 0x38ec
callq 0x20b0
movq %r13, 0x18(%rsp)
subq %r13, %rax
cvtsi2sd %rax, %xmm0
divsd 0x23cc(%rip), %xmm0     # 0x5038
movsd %xmm0, (%r12)
movl 0x898(%r15), %esi
leaq 0x2453(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
movq %r12, 0x40(%rsp)
movsd (%r12), %xmm0
movsd %xmm0, (%rsp)
movq %r14, 0x30(%rsp)
movsd %xmm0, (%r14)
leaq 0x900(%rsp), %rbp
movl $0x898, %edx            # imm = 0x898
movq %rbp, %rdi
movq %r15, %rsi
callq 0x20d0
movsd (%rsp), %xmm1
movl 0x898(%r15), %r13d
xorl %eax, %eax
testl %ebx, %ebx
cmovgl %ebx, %eax
movl %eax, 0xc(%rsp)
leaq 0x64(%rsp), %rbx
movsd 0x10(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2e3e
movsd 0x20(%rsp), %xmm0
ucomisd 0x38(%rsp), %xmm0
jbe 0x2cd5
movl 0xc(%rsp), %r12d
movsd %xmm0, (%rsp)
subl $0x1, %r12d
jb 0x2dfd
movl $0x898, %edx            # imm = 0x898
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x20d0
movl %r13d, 0x8fc(%rsp)
movq %rbx, %rdi
callq 0x39a2
movl 0x8fc(%rsp), %r14d
movl %r13d, %eax
subl %r14d, %eax
js 0x2d92
cvtsi2sd %eax, %xmm0
movapd %xmm0, 0x50(%rsp)
callq 0x2060
cltd
movl $0x3e9, %ecx            # imm = 0x3E9
idivl %ecx
cvtsi2sd %edx, %xmm0
divsd 0x22c6(%rip), %xmm0     # 0x5020
movsd %xmm0, 0x48(%rsp)
movapd 0x50(%rsp), %xmm0
xorpd 0x2312(%rip), %xmm0     # 0x5080
divsd (%rsp), %xmm0
callq 0x21d0
ucomisd 0x48(%rsp), %xmm0
jbe 0x2df3
movl $0x898, %edx            # imm = 0x898
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x20d0
jmp 0x2df0
movl $0x898, %edx            # imm = 0x898
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x20d0
cmpl 0x898(%r15), %r14d
jle 0x2df0
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %rbx, %rsi
callq 0x20d0
callq 0x20b0
subq 0x18(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x2266(%rip), %xmm0     # 0x5038
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x22ea(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
movl %r14d, %r13d
movsd (%rsp), %xmm0
jmp 0x2cfd
mulsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rsp)
callq 0x20b0
movsd (%rsp), %xmm0
subq 0x18(%rsp), %rax
cvtsi2sd %rax, %xmm1
divsd 0x2214(%rip), %xmm1     # 0x5038
movq 0x30(%rsp), %rax
movsd %xmm1, (%rax)
ucomisd 0x10(%rsp), %xmm1
jb 0x2ceb
jmp 0x2cd5
addq $0x1198, %rsp           # imm = 0x1198
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq