// File: /workspace/github_cpp_makefile_star2_O2/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, 0x40(%rsp)
movq %rcx, 0x10(%rsp)
movq %rdx, %r15
movsd %xmm2, 0x38(%rsp)
movsd %xmm1, 0x18(%rsp)
movsd %xmm0, 0x28(%rsp)
movl %esi, %ebx
movl %edi, %r12d
leaq 0x2294(%rip), %rdi      # 0x558f
callq 0x21b0
callq 0x20b0
movq %rax, 0x8(%rsp)
xorl %r13d, %r13d
testl %r12d, %r12d
cmovgl %r12d, %r13d
leaq 0x6665(%rip), %r14      # 0x9980
subq $0x1, %r13
jb 0x333a
movq %r14, %rdi
callq 0x38af
movq %r14, %rdi
callq 0x38ec
addq $0x89c, %r14            # imm = 0x89C
jmp 0x331b
movl %r12d, %edi
callq 0x3cc9
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1cdf(%rip), %xmm0     # 0x5038
movq 0x10(%rsp), %r14
movsd %xmm0, (%r14)
leaq 0x6616(%rip), %rsi      # 0x9980
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
callq 0x20d0
movl 0x898(%r15), %esi
movsd (%r14), %xmm0
leaq 0x1d49(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
movsd 0x18(%rsp), %xmm2
divsd 0x1ca1(%rip), %xmm2     # 0x5040
movsd (%r14), %xmm0
cvtsi2sd %r12d, %xmm1
mulsd %xmm2, %xmm1
movsd 0x1c93(%rip), %xmm2     # 0x5048
maxsd %xmm1, %xmm2
cvttsd2si %xmm2, %eax
movl %eax, 0x24(%rsp)
leal (%r12,%rbx,2), %eax
movl %eax, 0x20(%rsp)
movslq %r12d, %rax
movq %rax, 0x30(%rsp)
xorl %eax, %eax
testl %ebx, %ebx
cmovgl %ebx, %eax
movl %eax, 0x18(%rsp)
movq 0x40(%rsp), %rax
movsd %xmm0, (%rax)
movsd 0x38(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3622
xorl %ebp, %ebp
movq 0x30(%rsp), %rbx
cmpl 0x18(%rsp), %ebp
je 0x35fd
callq 0x2060
cltd
idivl 0x24(%rsp)
movl %edx, %r14d
callq 0x2060
cltd
idivl %r12d
cmpl %r14d, %edx
je 0x3413
leal 0x1(%rbx), %ecx
movl %r14d, %edi
movl %edx, %esi
movl %ebx, %edx
callq 0x3d77
imulq $0x89c, %rbx, %rcx      # imm = 0x89C
leaq 0x6542(%rip), %rdx      # 0x9980
leaq (%rdx,%rcx), %r13
movl 0x898(%r15), %eax
cmpl %eax, 0x898(%rcx,%rdx)
jle 0x349e
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r13, %rsi
callq 0x20d0
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1bbf(%rip), %xmm0     # 0x5038
movq 0x10(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x1c43(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
movl 0x898(%r15), %eax
leaq 0x1(%rbx), %rcx
imulq $0x89c, %rcx, %rcx      # imm = 0x89C
leaq 0x64d0(%rip), %rdx      # 0x9980
leaq (%rdx,%rcx), %r14
cmpl %eax, 0x898(%rcx,%rdx)
jle 0x3502
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r14, %rsi
callq 0x20d0
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1b54(%rip), %xmm0     # 0x5038
movq 0x10(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x1bd8(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
callq 0x2060
cltd
pushq $0x64
popq %rcx
idivl %ecx
cvtsi2sd %edx, %xmm0
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x357a
movq %r13, %rdi
callq 0x39a2
movl 0x898(%r13), %eax
cmpl 0x898(%r15), %eax
jle 0x357a
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r13, %rsi
callq 0x20d0
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1adc(%rip), %xmm0     # 0x5038
movq 0x10(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x1b60(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
callq 0x2060
cltd
pushq $0x64
popq %rcx
idivl %ecx
cvtsi2sd %edx, %xmm0
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x35f2
movq %r14, %rdi
callq 0x39a2
movl 0x898(%r14), %eax
cmpl 0x898(%r15), %eax
jle 0x35f2
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
movq %r14, %rsi
callq 0x20d0
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1a64(%rip), %xmm0     # 0x5038
movq 0x10(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x1ae8(%rip), %rdi      # 0x50d3
movb $0x1, %al
callq 0x2050
addq $0x2, %rbx
incl %ebp
jmp 0x33fc
movl 0x20(%rsp), %edi
callq 0x3cc9
callq 0x20b0
subq 0x8(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x1a1b(%rip), %xmm0     # 0x5038
jmp 0x33dc
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq