// File: /workspace/github_cpp_makefile_star2_O3/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 0x2933(%rip), %rdi      # 0x65bf
callq 0x21c0
callq 0x20a0
movq %rax, (%rsp)
testl %r13d, %r13d
jle 0x3cc5
leaq 0x6cea(%rip), %rbx      # 0xa990
movl %r13d, %r14d
movq %rbx, %rdi
callq 0x42bb
movq %rbx, %rdi
callq 0x42ff
addq $0x89c, %rbx            # imm = 0x89C
decq %r14
jne 0x3ca9
movl %r13d, %edi
callq 0x4777
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2352(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rbx
movsd %xmm0, (%rbx)
leaq 0x6c9a(%rip), %rsi      # 0xa990
movl $0x89c, %edx            # imm = 0x89C
movq %r15, %rdi
callq 0x20c0
movl 0x898(%r15), %esi
movsd (%rbx), %xmm0
leaq 0x23ee(%rip), %rdi      # 0x6103
movb $0x1, %al
callq 0x2050
movsd (%rbx), %xmm0
movq 0x30(%rsp), %rax
movsd %xmm0, (%rax)
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3ffe
movsd 0x10(%rsp), %xmm1
divsd 0x22f9(%rip), %xmm1     # 0x6040
xorps %xmm0, %xmm0
cvtsi2sd %r13d, %xmm0
mulsd %xmm1, %xmm0
movsd 0x22ed(%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 0x3fc3
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 0x3d9b
leal 0x1(%r12), %ecx
movl %ebp, %edi
movl %edx, %esi
movl %r12d, %edx
callq 0x4832
imulq $0x89c, %r12, %rcx      # imm = 0x89C
leaq 0x6bc9(%rip), %rdx      # 0xa990
leaq (%rdx,%rcx), %rbp
movl 0x898(%r15), %eax
cmpl %eax, 0x898(%rcx,%rdx)
jle 0x3e29
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 0x2234(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x22e8(%rip), %rdi      # 0x6103
movb $0x1, %al
callq 0x2050
movl 0x898(%r15), %eax
leaq 0x1(%r12), %rcx
imulq $0x89c, %rcx, %rcx      # imm = 0x89C
leaq 0x6b54(%rip), %rdx      # 0xa990
leaq (%rdx,%rcx), %r14
cmpl %eax, 0x898(%rcx,%rdx)
jle 0x3e90
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 0x21c6(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x227a(%rip), %rdi      # 0x6103
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 0x3f21
movq %rbp, %rdi
callq 0x43b2
movl 0x898(%rbp), %eax
cmpl 0x898(%r15), %eax
jle 0x3f21
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 0x2135(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x21e9(%rip), %rdi      # 0x6103
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 0x3fb3
movq %r14, %rdi
callq 0x43b2
movl 0x898(%r14), %eax
cmpl 0x898(%r15), %eax
jle 0x3fb3
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 0x20a3(%rip), %xmm0     # 0x6038
movq 0x8(%rsp), %rax
movsd %xmm0, (%rax)
movl 0x898(%r15), %esi
leaq 0x2157(%rip), %rdi      # 0x6103
movb $0x1, %al
callq 0x2050
addq $0x2, %r12
incl %ebx
cmpl 0x18(%rsp), %ebx
jne 0x3d8f
movl 0x24(%rsp), %edi
callq 0x4777
callq 0x20a0
subq (%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x2053(%rip), %xmm0     # 0x6038
movq 0x30(%rsp), %rax
movsd %xmm0, (%rax)
movsd 0x28(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x3d7d
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq