// File: /workspace/github_cpp_makefile_star2_O1/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, 0x18(%rsp)
movsd %xmm2, 0x58(%rsp)
movsd %xmm1, 0x20(%rsp)
movl %edi, 0x14(%rsp)
movsd %xmm0, 0x50(%rsp)
leaq 0x312b(%rip), %rdi      # 0x653e
callq 0x21c0
callq 0x20a0
movq %rax, %r12
movq %r15, %rdi
callq 0x4220
movq %r15, %rdi
callq 0x4264
callq 0x20a0
movq %r12, 0x28(%rsp)
subq %r12, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2beb(%rip), %xmm0     # 0x6038
movsd %xmm0, (%r14)
movl 0x898(%r15), %esi
leaq 0x2c73(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
movq %r14, 0x60(%rsp)
movsd (%r14), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd %xmm0, (%rbx)
leaq 0x910(%rsp), %rdi
movl $0x898, %edx            # imm = 0x898
movq %r15, %rsi
callq 0x20c0
movsd 0x18(%rsp), %xmm1
ucomisd 0x30(%rsp), %xmm1
jbe 0x3650
movl 0x898(%r15), %r12d
leaq 0x74(%rsp), %r13
leaq 0x910(%rsp), %rbp
movsd 0x20(%rsp), %xmm0
movq %rbx, 0x48(%rsp)
ucomisd 0x58(%rsp), %xmm0
jbe 0x3640
movsd %xmm0, 0x8(%rsp)
movl 0x14(%rsp), %eax
movl %eax, %r14d
testl %eax, %eax
jle 0x35f5
movl $0x898, %edx            # imm = 0x898
movq %r13, %rdi
movq %rbp, %rsi
callq 0x20c0
movl %r12d, 0x90c(%rsp)
movq %r13, %rdi
callq 0x4311
movl 0x90c(%rsp), %ebx
movl %r12d, %eax
subl %ebx, %eax
js 0x3588
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
xorpd 0x2b61(%rip), %xmm0     # 0x6080
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 0x2ac9(%rip), %xmm0     # 0x6020
movsd %xmm0, 0x68(%rsp)
movapd 0x30(%rsp), %xmm0
divsd 0x8(%rsp), %xmm0
callq 0x2200
ucomisd 0x68(%rsp), %xmm0
jbe 0x35ec
movl $0x898, %edx            # imm = 0x898
movq %rbp, %rdi
movq %r13, %rsi
callq 0x20c0
jmp 0x35e9
movl $0x898, %edx            # imm = 0x898
movq %rbp, %rdi
movq %r13, %rsi
callq 0x20c0
cmpl 0x898(%r15), %ebx
jle 0x35e9
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 0x2a6d(%rip), %xmm0     # 0x6038
movq 0x60(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x2af1(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
movl %ebx, %r12d
decl %r14d
jne 0x34e2
movsd 0x8(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
callq 0x20a0
subq 0x28(%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2a17(%rip), %xmm0     # 0x6038
movq 0x48(%rsp), %rbx
movsd %xmm0, (%rbx)
movsd 0x18(%rsp), %xmm1
ucomisd %xmm1, %xmm0
movsd 0x8(%rsp), %xmm0
jb 0x34c1
ucomisd (%rbx), %xmm1
movsd 0x20(%rsp), %xmm0
ja 0x34c1
addq $0x11a8, %rsp           # imm = 0x11A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq