// File: /workspace/github_cpp_makefile_star2_O1/GAStudyGroup[P]GPX2/src/main.cpp
// Function: GA()
void GA() {
    Population pop;
    bool foundBestWithoutGA = true;

    ofstream *logFile{Log::initLogFile()};  

    Log::printHeader(*logFile);

    auto start = std::chrono::high_resolution_clock::now();

    GAUtils::init(pop);
    AntMap::initMap();
    AntMap::updatePheromoneMap(pop.getBestTour());

    // cout<<"tour size "<<Globals::TOUR_SIZE<<endl;
    // antColony.printPheromoneMap();

    // Population tmpPop = antColony.run();
    // cout<<"Size of return pop "<<tmpPop.getPopulation().size()<<" Best fitness of run 0 "<<tmpPop.bestFitness()<<endl;
    // antColony.printPheromoneMap();

    auto finishInitPop = std::chrono::high_resolution_clock::now();

    Log::printTime(*logFile,"Population created in:",
                    std::chrono::duration<double,std::milli> (finishInitPop - start).count()); 

    auto startGA = std::chrono::high_resolution_clock::now();

    int i{0}, firstBestFitness{pop.bestFitness()};
    *logFile << "\nFirst fitness " << firstBestFitness << endl;
    while(GAUtils::stop(pop,*logFile)){
        foundBestWithoutGA = false;
        i++;
        pop = GAUtils::generateNewPopulation(pop);
        // AntMap::printPheromoneMap();
        *logFile << "gen " << i << " best fitness " << pop.bestFitness() << endl;
        
    }

    if(foundBestWithoutGA){
        *logFile << "Found best without GA" << endl;
        cout << "Found best without GA" << endl;
    }

    auto finishGA = std::chrono::high_resolution_clock::now();
    Log::printTime(*logFile,"GA execution time:",
                    std::chrono::duration<double,std::milli> (finishGA - startGA).count()); 

    auto finish = std::chrono::high_resolution_clock::now();
    Log::printTime(*logFile,"Total execution time:",
                    std::chrono::duration<double,std::milli> (finish - start).count()); 

    Log::printFooter(*logFile,pop,i,firstBestFitness);

    (*logFile).close();
    delete logFile;
    AntMap::deleteMap();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsp, %rdi
callq 0xeac4
callq 0xc37c
movq %rax, %rbx
movq %rax, %rdi
callq 0xd1cd
callq 0x5070
movq %rax, %r12
movq %rsp, %rdi
callq 0x835c
callq 0x22c65
movq %rsp, %rdi
callq 0xeb72
movq %rax, %rdi
callq 0x22902
callq 0x5070
movq %rax, %r14
leaq 0x80(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x29393(%rip), %rsi     # 0x31020
leaq 0x293a2(%rip), %rdx     # 0x31036
leaq 0x70(%rsp), %rdi
callq 0x823c
subq %r12, %r14
cvtsi2sd %r14, %xmm0
divsd 0x2935a(%rip), %xmm0    # 0x31008
leaq 0x70(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf68
movq %r12, 0x20(%rsp)
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x7cda
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x53c0
callq 0x5070
movq %rax, 0x28(%rsp)
movq %rsp, %rdi
callq 0xead8
movl %eax, %ebp
leaq 0x29342(%rip), %rsi     # 0x31037
movl $0xf, %edx
movq %rbx, %rdi
callq 0x5440
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5640
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x5390
movsbl %al, %esi
movq %r14, %rdi
callq 0x5040
movq %rax, %rdi
callq 0x5290
movl %ebp, 0x1c(%rsp)
movb $0x1, %bpl
xorl %r15d, %r15d
movq %rsp, %r13
leaq 0x90(%rsp), %r12
leaq 0x292fa(%rip), %r14     # 0x3104c
movq %r13, %rdi
movq %rbx, %rsi
callq 0x8746
testb %al, %al
je 0x7e5a
movq %r12, %rdi
movq %r13, %rsi
callq 0x8d88
xorpd %xmm0, %xmm0
movapd %xmm0, 0xb0(%rsp)
movapd (%rsp), %xmm0
movq 0x10(%rsp), %rax
movaps 0x90(%rsp), %xmm1
movaps %xmm1, (%rsp)
movq 0xa0(%rsp), %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0xc0(%rsp)
movaps 0xb0(%rsp), %xmm1
movapd %xmm0, 0xb0(%rsp)
movaps %xmm1, 0x90(%rsp)
movq $0x0, 0xa0(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x8102
movq %r12, %rdi
callq 0x8102
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x29256(%rip), %rsi     # 0x31047
callq 0x5440
incl %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x5640
movq %rax, %rbp
movl $0xe, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x5440
movq %r13, %rdi
callq 0xead8
movq %rbp, %rdi
movl %eax, %esi
callq 0x5640
movq %rax, %rbp
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x5390
movsbl %al, %esi
movq %rbp, %rdi
callq 0x5040
xorl %ebp, %ebp
movq %rax, %rdi
callq 0x5290
jmp 0x7d52
testb $0x1, %bpl
movl 0x1c(%rsp), %ebp
je 0x7ee9
leaq 0x291ec(%rip), %rsi     # 0x3105b
movl $0x15, %edx
movq %rbx, %rdi
callq 0x5440
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x5390
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5040
movq %rax, %rdi
callq 0x5290
movq 0x3a0f6(%rip), %r14     # 0x41fa0
leaq 0x291aa(%rip), %rsi     # 0x3105b
movl $0x15, %edx
movq %r14, %rdi
callq 0x5440
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x5390
movsbl %al, %esi
movq 0x3a0c4(%rip), %rdi     # 0x41fa0
callq 0x5040
movq %rax, %rdi
callq 0x5290
callq 0x5070
movq %rax, %r14
leaq 0x60(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x2916f(%rip), %rsi     # 0x31071
leaq 0x2917a(%rip), %rdx     # 0x31083
leaq 0x50(%rsp), %rdi
callq 0x823c
subq 0x28(%rsp), %r14
cvtsi2sd %r14, %xmm0
divsd 0x290e3(%rip), %xmm0    # 0x31008
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf68
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x7f49
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x53c0
callq 0x5070
movq %rax, %r14
leaq 0x40(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x29122(%rip), %rsi     # 0x31084
leaq 0x29130(%rip), %rdx     # 0x31099
leaq 0x30(%rsp), %rdi
callq 0x823c
subq 0x20(%rsp), %r14
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
divsd 0x29080(%rip), %xmm0    # 0x31008
leaq 0x30(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf68
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0x7fac
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x53c0
movq %rsp, %rsi
movq %rbx, %rdi
movl %r15d, %edx
movl %ebp, %ecx
callq 0xdc5b
movq %rbx, %rdi
callq 0x5530
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
callq 0x22d94
movq %rsp, %rdi
callq 0x8102
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0x8046
movq 0x40(%rsp), %rsi
jmp 0x802d
jmp 0x8043
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x8046
movq 0x60(%rsp), %rsi
jmp 0x802d
jmp 0x8043
movq %rax, %rbx
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x8046
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x53c0
jmp 0x8046
jmp 0x8043
jmp 0x8043
jmp 0x8043
jmp 0x8043
jmp 0x8043
jmp 0x8043
movq %rax, %rbx
movq %rsp, %rdi
callq 0x8102
movq %rbx, %rdi
callq 0x5670