// File: /workspace/github_cpp_makefile_star2_O3/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 0xeaac
callq 0xc3b0
movq %rax, %rbx
movq %rax, %rdi
callq 0xd1b5
callq 0x5070
movq %rax, %r12
movq %rsp, %rdi
callq 0x8390
callq 0x22cd2
movq %rsp, %rdi
callq 0xeb5a
movq %rax, %rdi
callq 0x2295e
callq 0x5070
movq %rax, %r14
leaq 0x80(%rsp), %r15
movq %r15, -0x10(%r15)
leaq 0x29363(%rip), %rsi     # 0x31020
leaq 0x29372(%rip), %rdx     # 0x31036
leaq 0x70(%rsp), %rdi
callq 0x8264
subq %r12, %r14
cvtsi2sd %r14, %xmm0
divsd 0x2932a(%rip), %xmm0    # 0x31008
leaq 0x70(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf08
movq %r12, 0x20(%rsp)
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x7d0a
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x53b0
callq 0x5070
movq %rax, 0x28(%rsp)
movq %rsp, %rdi
callq 0xeac0
movl %eax, %ebp
leaq 0x29312(%rip), %rsi     # 0x31037
movl $0xf, %edx
movq %rbx, %rdi
callq 0x5430
movq %rbx, %rdi
movl %ebp, %esi
callq 0x5630
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x5380
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 0x292ca(%rip), %r14     # 0x3104c
movq %r13, %rdi
movq %rbx, %rsi
callq 0x876c
testb %al, %al
je 0x7e7a
movq %r12, %rdi
movq %r13, %rsi
callq 0x8d71
movq 0x10(%rsp), %rax
movapd 0x90(%rsp), %xmm0
movq 0xa0(%rsp), %rcx
movq %rcx, 0x10(%rsp)
movaps (%rsp), %xmm1
movapd %xmm0, (%rsp)
movaps %xmm1, 0xb0(%rsp)
movq %rax, 0xc0(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x90(%rsp)
movq $0x0, 0xa0(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x8122
movq %r12, %rdi
callq 0x8122
movl $0x4, %edx
movq %rbx, %rdi
leaq 0x29236(%rip), %rsi     # 0x31047
callq 0x5430
incl %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x5630
movq %rax, %rbp
movl $0xe, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x5430
movq %r13, %rdi
callq 0xeac0
movq %rbp, %rdi
movl %eax, %esi
callq 0x5630
movq %rax, %rbp
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x5380
movsbl %al, %esi
movq %rbp, %rdi
callq 0x5040
xorl %ebp, %ebp
movq %rax, %rdi
callq 0x5290
jmp 0x7d82
testb $0x1, %bpl
movl 0x1c(%rsp), %ebp
je 0x7f09
leaq 0x291cc(%rip), %rsi     # 0x3105b
movl $0x15, %edx
movq %rbx, %rdi
callq 0x5430
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x5380
movsbl %al, %esi
movq %rbx, %rdi
callq 0x5040
movq %rax, %rdi
callq 0x5290
movq 0x3a0d6(%rip), %r14     # 0x41fa0
leaq 0x2918a(%rip), %rsi     # 0x3105b
movl $0x15, %edx
movq %r14, %rdi
callq 0x5430
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x5380
movsbl %al, %esi
movq 0x3a0a4(%rip), %rdi     # 0x41fa0
callq 0x5040
movq %rax, %rdi
callq 0x5290
callq 0x5070
movq %rax, %r14
leaq 0x60(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x2914f(%rip), %rsi     # 0x31071
leaq 0x2915a(%rip), %rdx     # 0x31083
leaq 0x50(%rsp), %rdi
callq 0x8264
subq 0x28(%rsp), %r14
cvtsi2sd %r14, %xmm0
divsd 0x290c3(%rip), %xmm0    # 0x31008
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf08
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x7f69
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x53b0
callq 0x5070
movq %rax, %r14
leaq 0x40(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x29102(%rip), %rsi     # 0x31084
leaq 0x29110(%rip), %rdx     # 0x31099
leaq 0x30(%rsp), %rdi
callq 0x8264
subq 0x20(%rsp), %r14
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
divsd 0x29060(%rip), %xmm0    # 0x31008
leaq 0x30(%rsp), %rsi
movq %rbx, %rdi
callq 0xdf08
movq 0x30(%rsp), %rdi
cmpq %r12, %rdi
je 0x7fcc
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x53b0
movq %rsp, %rsi
movq %rbx, %rdi
movl %r15d, %edx
movl %ebp, %ecx
callq 0xdbfb
movq %rbx, %rdi
callq 0x5520
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
callq 0x22e12
movq %rsp, %rdi
callq 0x8122
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 0x8066
movq 0x40(%rsp), %rsi
jmp 0x804d
jmp 0x8063
movq %rax, %rbx
movq 0x50(%rsp), %rdi
cmpq %r12, %rdi
je 0x8066
movq 0x60(%rsp), %rsi
jmp 0x804d
jmp 0x8063
movq %rax, %rbx
movq 0x70(%rsp), %rdi
cmpq %r15, %rdi
je 0x8066
movq 0x80(%rsp), %rsi
incq %rsi
callq 0x53b0
jmp 0x8066
jmp 0x8063
jmp 0x8063
jmp 0x8063
jmp 0x8063
jmp 0x8063
jmp 0x8063
movq %rax, %rbx
movq %rsp, %rdi
callq 0x8122
movq %rbx, %rdi
callq 0x5660