// File: /workspace/github_cpp_makefile_star2_O3/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 0x3a0a8(%rip), %al      # 0x42830
testb %al, %al
je 0x889c
movq %r14, %rdi
callq 0xeac0
movl %eax, 0x4(%rsp)
movq %r14, %rdi
callq 0xeabc
movq (%rax), %r14
movq 0x8(%rax), %r13
xorl %r12d, %r12d
cmpq %r13, %r14
je 0x87fd
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xb078
movq %r15, %rdi
callq 0xf1cc
xorl %ebx, %ebx
cmpl 0x3a055(%rip), %eax     # 0x42828
sete %bpl
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x87ee
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x53b0
movb %bpl, %bl
addl %ebx, %r12d
addq $0x18, %r14
cmpq %r13, %r14
jne 0x87b8
movl 0x3a025(%rip), %eax     # 0x42828
movl 0x4(%rsp), %edx
cmpl %edx, %eax
jbe 0x881c
movl %edx, 0x3a017(%rip)     # 0x42828
xorl %ecx, %ecx
movl %edx, %eax
movq 0x8(%rsp), %rbx
jmp 0x8843
leaq 0x3a0ad(%rip), %rcx     # 0x428d0
cmpl (%rcx), %r12d
movq 0x8(%rsp), %rbx
jne 0x883b
leaq 0x28b08(%rip), %rsi     # 0x3133c
movl $0x16, %edx
jmp 0x887b
movl 0x39fe3(%rip), %ecx     # 0x42824
incl %ecx
movl %ecx, 0x39fdb(%rip)     # 0x42824
leaq 0x3a084(%rip), %rdx     # 0x428d4
cmpl (%rdx), %eax
jbe 0x886f
leaq 0x39f5d(%rip), %rdx     # 0x427b8
movb $0x1, %al
cmpl (%rdx), %ecx
jb 0x888d
leaq 0x28b01(%rip), %rsi     # 0x31369
movl $0x1a, %edx
jmp 0x887b
leaq 0x28add(%rip), %rsi     # 0x31353
movl $0x15, %edx
movq %rbx, %rdi
callq 0x5430
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 0x39f8d(%rip), %rdi     # 0x42830
callq 0x5680
testl %eax, %eax
je 0x8790
movq %r14, %rdi
callq 0xeac0
movl %eax, 0x39f6a(%rip)     # 0x42828
leaq 0x39f6b(%rip), %rdi     # 0x42830
callq 0x5270
jmp 0x8790
movq %rax, %rbx
leaq 0x39f57(%rip), %rdi     # 0x42830
callq 0x5260
jmp 0x88fa
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x88fa
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x53b0
movq %rbx, %rdi
callq 0x5660