// File: /workspace/github_cpp_makefile_star2_O1/GAStudyGroup[P]GPX2/src/base/sources/GAUtils.cpp
// Function: GAUtils::stop(Population&, std::ostream&)
bool GAUtils::stop(Population &pop, ostream &out) {
    unsigned static generationsWithoutChange{0};
    unsigned static bestFitness{(unsigned)pop.bestFitness()};
    
    unsigned currentFitness{(unsigned)pop.bestFitness()};

    unsigned totalEqual{0};
    //how many routes have fitness equal to the best route, to determine stagnation
    for (vector<int> t : pop.getPopulation()) {
        if ((unsigned)getFitness(t) == bestFitness) {
            totalEqual++;
        }
    }

    //zero the generationsWithoutChange counter if a better fitness is found
    if (bestFitness > currentFitness) {
        bestFitness = currentFitness;
        generationsWithoutChange = 0;
    } else if (totalEqual == Config::POP_SIZE) {
        //if all elements are equal ends GA
        out << "\nPopulation converged!";
        out.flush();
        return (false);
    } else {
        generationsWithoutChange++;
    }

    //If the current fitness is equal to or less than the best known, it decreases the number of generations to stop AG
    if(bestFitness <= Config::BEST_FITNESS){
        // Config::GENERATION_LIMIT = Config::AFTER_BEST;
        out << "\nFound best fitness!\n";
        out.flush();
        return (false);
    }

    if (generationsWithoutChange >= Config::GENERATION_LIMIT) {
        out << "\nGeneration limit reached!";
        out.flush();
        return (false);
    } else {
        return (true);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, 0x8(%rsp)
movq %rdi, %r14
movb 0x3a0de(%rip), %al      # 0x42840
testb %al, %al
je 0x8878
movq %r14, %rdi
callq 0xead8
movl %eax, 0x4(%rsp)
movq %r14, %rdi
callq 0xead4
movq (%rax), %r14
movq 0x8(%rax), %r13
xorl %r12d, %r12d
cmpq %r13, %r14
je 0x87d7
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xb05c
movq %r15, %rdi
callq 0xf1c0
xorl %ebx, %ebx
cmpl 0x3a08b(%rip), %eax     # 0x42838
sete %bpl
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x87c8
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x53c0
movb %bpl, %bl
addl %ebx, %r12d
addq $0x18, %r14
cmpq %r13, %r14
jne 0x8792
movl 0x4(%rsp), %eax
cmpl %eax, 0x3a057(%rip)     # 0x42838
jbe 0x87f2
movl %eax, 0x3a04f(%rip)     # 0x42838
xorl %ecx, %ecx
movq 0x8(%rsp), %rbx
jmp 0x8819
leaq 0x3a0e7(%rip), %rax     # 0x428e0
cmpl (%rax), %r12d
movq 0x8(%rsp), %rbx
jne 0x8811
leaq 0x28b32(%rip), %rsi     # 0x3133c
movl $0x16, %edx
jmp 0x8857
movl 0x3a01d(%rip), %ecx     # 0x42834
incl %ecx
movl %ecx, 0x3a015(%rip)     # 0x42834
movl 0x3a013(%rip), %eax     # 0x42838
leaq 0x3a0b8(%rip), %rdx     # 0x428e4
cmpl (%rdx), %eax
jbe 0x884b
leaq 0x39f91(%rip), %rdx     # 0x427c8
movb $0x1, %al
cmpl (%rdx), %ecx
jb 0x8869
leaq 0x28b25(%rip), %rsi     # 0x31369
movl $0x1a, %edx
jmp 0x8857
leaq 0x28b01(%rip), %rsi     # 0x31353
movl $0x15, %edx
movq %rbx, %rdi
callq 0x5440
movq %rbx, %rdi
callq 0x5290
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x39fc1(%rip), %rdi     # 0x42840
callq 0x5690
testl %eax, %eax
je 0x876a
movq %r14, %rdi
callq 0xead8
movl %eax, 0x39f9e(%rip)     # 0x42838
leaq 0x39f9f(%rip), %rdi     # 0x42840
callq 0x5270
jmp 0x876a
movq %rax, %rbx
leaq 0x39f8b(%rip), %rdi     # 0x42840
callq 0x5260
jmp 0x88d6
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x88d6
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x53c0
movq %rbx, %rdi
callq 0x5670