// File: /workspace/github_cpp_makefile_star2_O2/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 $0xa8, %rsp
leaq 0x10(%rsp), %rdi
callq 0xb97c
callq 0xa49c
movq %rax, %rbx
movq %rax, %rdi
callq 0xa916
callq 0x5060
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x71c4
callq 0x1bd16
leaq 0x10(%rsp), %rdi
callq 0xb9f0
movq %rax, %rdi
callq 0x1ba56
callq 0x5060
movq %rax, %r14
leaq 0x20615(%rip), %rsi     # 0x27010
leaq 0x88(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6cfa
subq 0x8(%rsp), %r14
cvtsi2sd %r14, %xmm0
divsd 0x205e9(%rip), %xmm0    # 0x27008
leaq 0x88(%rsp), %rsi
movq %rbx, %rdi
callq 0xaefb
leaq 0x88(%rsp), %rdi
callq 0x56f8
callq 0x5060
movq %rax, 0x28(%rsp)
leaq 0x10(%rsp), %rdi
callq 0xb98c
movl %eax, 0x4(%rsp)
leaq 0x205cc(%rip), %rsi     # 0x27027
movq %rbx, %rdi
callq 0x5370
movq %rax, %rdi
movl 0x4(%rsp), %esi
callq 0x55e0
movq %rax, %rdi
callq 0x51c0
movb $0x1, %r14b
xorl %r15d, %r15d
leaq 0x10(%rsp), %r13
leaq 0x30(%rsp), %r12
leaq 0x205ae(%rip), %rbp     # 0x2703c
movq %r13, %rdi
movq %rbx, %rsi
callq 0x7412
testb %al, %al
je 0x6b05
movq %r12, %rdi
movq %r13, %rsi
callq 0x791f
movq %r13, %rdi
movq %r12, %rsi
callq 0x6d8c
movq %r12, %rdi
callq 0x6dde
movq %rbx, %rdi
leaq 0x20572(%rip), %rsi     # 0x27037
callq 0x5370
incl %r15d
movq %rax, %rdi
movl %r15d, %esi
callq 0x55e0
movq %rax, %rdi
movq %rbp, %rsi
callq 0x5370
movq %rax, %r14
movq %r13, %rdi
callq 0xb98c
movq %r14, %rdi
movl %eax, %esi
callq 0x55e0
xorl %r14d, %r14d
movq %rax, %rdi
callq 0x51c0
jmp 0x6a8e
testb $0x1, %r14b
je 0x6b3d
leaq 0x20539(%rip), %rsi     # 0x2704b
movq %rbx, %rdi
callq 0x5370
movq %rax, %rdi
callq 0x51c0
movq 0x35477(%rip), %rdi     # 0x3bfa0
leaq 0x2051b(%rip), %rsi     # 0x2704b
callq 0x5370
movq %rax, %rdi
callq 0x51c0
callq 0x5060
movq %rax, %r14
leaq 0x20515(%rip), %rsi     # 0x27061
leaq 0x68(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6cfa
subq 0x28(%rsp), %r14
cvtsi2sd %r14, %xmm0
divsd 0x2049b(%rip), %xmm0    # 0x27008
leaq 0x68(%rsp), %rsi
movq %rbx, %rdi
callq 0xaefb
leaq 0x68(%rsp), %rdi
callq 0x56f8
callq 0x5060
movq %rax, %r14
leaq 0x204e1(%rip), %rsi     # 0x27074
leaq 0x48(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6cfa
subq 0x8(%rsp), %r14
cvtsi2sd %r14, %xmm0
divsd 0x20454(%rip), %xmm0    # 0x27008
leaq 0x48(%rsp), %rsi
movq %rbx, %rdi
callq 0xaefb
leaq 0x48(%rsp), %rdi
callq 0x56f8
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
movl %r15d, %edx
movl 0x4(%rsp), %ecx
callq 0xacd5
movq %rbx, %rdi
callq 0x54e0
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
callq 0x1be19
leaq 0x10(%rsp), %rdi
callq 0x6dde
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x48(%rsp), %rdi
jmp 0x6c34
jmp 0x6c47
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
jmp 0x6c34
jmp 0x6c47
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x56f8
jmp 0x6c4a
jmp 0x6c47
jmp 0x6c47
jmp 0x6c47
jmp 0x6c47
jmp 0x6c47
jmp 0x6c47
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x6dde
movq %rbx, %rdi
callq 0x5610