// File: /workspace/github_cpp_makefile_star2_O3/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 $0x11a8, %rsp           # imm = 0x11A8
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %r15
movsd %xmm3, 0x8(%rsp)
movsd %xmm2, 0x20(%rsp)
movsd %xmm1, 0x48(%rsp)
movl %edi, 0x1c(%rsp)
movsd %xmm0, 0x50(%rsp)
leaq 0x30ce(%rip), %rdi      # 0x656e
callq 0x21c0
callq 0x20a0
movq %rax, %r12
movq %r15, %rdi
callq 0x42bb
movq %r15, %rdi
callq 0x42ff
callq 0x20a0
movq %r12, 0x28(%rsp)
subq %r12, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2b5e(%rip), %xmm0     # 0x6038
movsd %xmm0, (%r14)
movl 0x898(%r15), %esi
leaq 0x2c16(%rip), %rdi      # 0x6103
movb $0x1, %al
callq 0x2050
movq %r14, 0x60(%rsp)
movsd (%r14), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %rbx, 0x58(%rsp)
movsd %xmm0, (%rbx)
leaq 0x910(%rsp), %rdi
movl $0x898, %edx            # imm = 0x898
movq %r15, %rsi
callq 0x20c0
movsd 0x30(%rsp), %xmm1
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x36df
movl 0x898(%r15), %r12d
leaq 0x74(%rsp), %r13
leaq 0x910(%rsp), %rbx
movsd 0x48(%rsp), %xmm0
ucomisd 0x20(%rsp), %xmm0
jbe 0x36cf
movsd %xmm0, 0x10(%rsp)
movl 0x1c(%rsp), %eax
movl %eax, %r14d
testl %eax, %eax
jle 0x3686
movl $0x898, %edx            # imm = 0x898
movq %r13, %rdi
movq %rbx, %rsi
callq 0x20c0
movl %r12d, 0x90c(%rsp)
movq %r13, %rdi
callq 0x43b2
movl 0x90c(%rsp), %ebp
movl %r12d, %eax
subl %ebp, %eax
js 0x3619
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
xorpd 0x2b00(%rip), %xmm0     # 0x60b0
movapd %xmm0, 0x30(%rsp)
callq 0x2060
cltq
imulq $0x4178749f, %rax, %rcx # imm = 0x4178749F
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x28, %rcx
addl %edx, %ecx
imull $0x3e9, %ecx, %ecx      # imm = 0x3E9
subl %ecx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0x2a38(%rip), %xmm0     # 0x6020
movsd %xmm0, 0x68(%rsp)
movapd 0x30(%rsp), %xmm0
divsd 0x10(%rsp), %xmm0
callq 0x2200
ucomisd 0x68(%rsp), %xmm0
jbe 0x367d
movl $0x898, %edx            # imm = 0x898
movq %rbx, %rdi
movq %r13, %rsi
callq 0x20c0
jmp 0x367a
movl $0x898, %edx            # imm = 0x898
movq %rbx, %rdi
movq %r13, %rsi
callq 0x20c0
cmpl 0x898(%r15), %ebp
jle 0x367a
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r13, %rsi
callq 0x20c0
callq 0x20a0
subq 0x28(%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x29dc(%rip), %xmm0     # 0x6038
movq 0x60(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x2a90(%rip), %rdi      # 0x6103
movb $0x1, %al
callq 0x2050
movl %ebp, %r12d
decl %r14d
jne 0x3573
callq 0x20a0
subq 0x28(%rsp), %rax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
divsd 0x2998(%rip), %xmm1     # 0x6038
movq 0x58(%rsp), %rax
movsd %xmm1, (%rax)
ucomisd 0x8(%rsp), %xmm1
jae 0x36cf
movsd 0x10(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
ucomisd 0x20(%rsp), %xmm0
ja 0x3564
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x354c
addq $0x11a8, %rsp           # imm = 0x11A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq