// File: /workspace/github_cpp_makefile_star2_O1/grmauri[P]pmm/pmm.cpp
// Function: algoritmo_genetico(int, int, double, double, double, tSolucao&, double&, double&)
void algoritmo_genetico(const int pop, const int cro, const double mut, const double eli,
                        const double tempo_max, Solucao &s, double &tempo_melhor, double &tempo_total)
{
    int filho, p1, p2;
    clock_t hI, hF;
    printf("\n\n>>> EXECUTANDO O AG...\n\n");
    hI = clock();
    for(int i = 0; i < pop; i++)
    {
        heuConAle(vet_populacao[i]);
        calcFO(vet_populacao[i]);
    }
    ordenar_populacao(pop);
    hF = clock();
    tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
    memcpy(&s, &vet_populacao[0], sizeof(vet_populacao[0]));
    #ifdef DBG
        printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
    #endif
    tempo_total = tempo_melhor;
    while(tempo_total < tempo_max)
    {
       filho = pop;
       for(int i = 0; i < cro; i++)
       {
           //------------------
           // Selecao elite
           p1 = MAX(1,(eli/100.0)*pop);
           p1 = rand()%p1;
           do
               p2 = rand()%pop;
           while(p2 == p1);
           //------------------
           // Cruzamento
           crossover(p1,p2,filho,filho+1);
           if(vet_populacao[filho].funObj > s.funObj)
           {
                memcpy(&s, &vet_populacao[filho], sizeof(vet_populacao[filho]));
                hF = clock();
                tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
                #ifdef DBG
                    printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
                #endif
           }
           if(vet_populacao[filho+1].funObj > s.funObj)
           {
                memcpy(&s, &vet_populacao[filho+1], sizeof(vet_populacao[filho+1]));
                hF = clock();
                tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
                #ifdef DBG
                    printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
                #endif
           }
           //------------------
           // Mutacao
           if(rand()%100 < mut)
           {
               gerar_vizinha(vet_populacao[filho]);
               if(vet_populacao[filho].funObj > s.funObj)
               {
                    memcpy(&s, &vet_populacao[filho], sizeof(vet_populacao[filho]));
                    hF = clock();
                    tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
                    #ifdef DBG
                        printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
                    #endif
               }
           }
           if(rand()%100 < mut)
           {
               gerar_vizinha(vet_populacao[filho+1]);
               if(vet_populacao[filho+1].funObj > s.funObj)
               {
                    memcpy(&s, &vet_populacao[filho+1], sizeof(vet_populacao[filho+1]));
                    hF = clock();
                    tempo_melhor = ((double)(hF - hI))/CLOCKS_PER_SEC;
                    #ifdef DBG
                        printf("FO: %d\tTempo: %.2f\n", s.funObj, tempo_melhor);
                    #endif
               }
           }
           filho += 2;
       }
       //------------------
       // Selecao de sobreviventes
       ordenar_populacao(pop + 2 * cro);
       hF = clock();
       tempo_total = ((double)(hF - hI))/CLOCKS_PER_SEC;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %r8, 0x30(%rsp)
movq %rcx, 0x8(%rsp)
movq %rdx, %r15
movsd %xmm2, 0x28(%rsp)
movsd %xmm1, 0x10(%rsp)
movsd %xmm0, 0x38(%rsp)
movq %rsi, 0x18(%rsp)
movl %edi, %r13d
leaq 0x299e(%rip), %rdi      # 0x658f
callq 0x21c0
callq 0x20a0
movq %rax, (%rsp)
testl %r13d, %r13d
jle 0x3c2a
leaq 0x6d85(%rip), %rbx      # 0xa990
movl %r13d, %r14d
movq %rbx, %rdi
callq 0x4220
movq %rbx, %rdi
callq 0x4264
addq $0x89c, %rbx            # imm = 0x89C
decq %r14
jne 0x3c0e
movl %r13d, %edi
callq 0x4687
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x23ed(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rbx
movsd %xmm0, (%rbx)
leaq 0x6d35(%rip), %rsi      # 0xa990
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
callq 0x20c0
movl 0x898(%r15), %esi
movsd (%rbx), %xmm0
leaq 0x2459(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
movsd (%rbx), %xmm0
movq 0x30(%rsp), %rax
movsd %xmm0, (%rax)
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3f63
movsd 0x10(%rsp), %xmm1
divsd 0x2394(%rip), %xmm1     # 0x6040
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
mulsd %xmm1, %xmm0
movsd 0x2388(%rip), %xmm1     # 0x6048
maxsd %xmm0, %xmm1
cvttsd2si %xmm1, %eax
movl %eax, 0x10(%rsp)
movq 0x18(%rsp), %rax
leal (%r13,%rax,2), %eax
movl %eax, 0x24(%rsp)
movslq %r13d, %rax
movq %rax, 0x40(%rsp)
cmpl $0x0, 0x18(%rsp)
jle 0x3f28
xorl %ebx, %ebx
movq 0x40(%rsp), %r12
callq 0x2060
cltd
idivl 0x10(%rsp)
movl %edx, %ebp
callq 0x2060
cltd
idivl %r13d
cmpl %ebp, %edx
je 0x3d00
leal 0x1(%r12), %ecx
movl %ebp, %edi
movl %edx, %esi
movl %r12d, %edx
callq 0x4740
imulq $0x89c, %r12, %rax      # imm = 0x89C
leaq 0x6c64(%rip), %rcx      # 0xa990
leaq (%rcx,%rax), %rbp
movl 0x898(%rax,%rcx), %eax
cmpl 0x898(%r15), %eax
jle 0x3d87
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %rbp, %rsi
callq 0x20c0
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x22cf(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x2353(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
leaq 0x1(%r12), %rax
imulq $0x89c, %rax, %rax      # imm = 0x89C
leaq 0x6bf6(%rip), %rcx      # 0xa990
leaq (%rcx,%rax), %r14
movl 0x898(%rax,%rcx), %eax
cmpl 0x898(%r15), %eax
jle 0x3df5
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r14, %rsi
callq 0x20c0
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2261(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x22e5(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
callq 0x2060
cltq
imulq $0x51eb851f, %rax, %rcx # imm = 0x51EB851F
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x25, %rcx
addl %edx, %ecx
imull $0x64, %ecx, %ecx
subl %ecx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x38(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3e86
movq %rbp, %rdi
callq 0x4311
movl 0x898(%rbp), %eax
cmpl 0x898(%r15), %eax
jle 0x3e86
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %rbp, %rsi
callq 0x20c0
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x21d0(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x2254(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
callq 0x2060
cltq
imulq $0x51eb851f, %rax, %rcx # imm = 0x51EB851F
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x25, %rcx
addl %edx, %ecx
imull $0x64, %ecx, %ecx
subl %ecx, %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x38(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3f18
movq %r14, %rdi
callq 0x4311
movl 0x898(%r14), %eax
cmpl 0x898(%r15), %eax
jle 0x3f18
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r14, %rsi
callq 0x20c0
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x213e(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x21c2(%rip), %rdi      # 0x60d3
movb $0x1, %al
callq 0x2050
addq $0x2, %r12
incl %ebx
cmpl 0x18(%rsp), %ebx
jne 0x3cf4
movl 0x24(%rsp), %edi
callq 0x4687
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x20ee(%rip), %xmm0     # 0x6038
movq 0x30(%rsp), %rax
movsd %xmm0, (%rax)
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x3ce2
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq