// File: /workspace/github_cpp_makefile_star2_O2/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 $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movb 0x353f4(%rip), %al      # 0x3c820
testb %al, %al
je 0x7509
movq %r14, %rdi
callq 0xb98c
movl %eax, %ebp
movq %r14, %rdi
callq 0xb988
movq (%rax), %r14
movq 0x8(%rax), %r13
xorl %r12d, %r12d
movq %rsp, %r15
cmpq %r13, %r14
je 0x7487
movq %r15, %rdi
movq %r14, %rsi
callq 0x9210
movq %r15, %rdi
callq 0xc060
xorl %ecx, %ecx
cmpl 0x353a5(%rip), %eax     # 0x3c818
sete %cl
addl %ecx, %r12d
movq %r15, %rdi
callq 0x6e4c
addq $0x18, %r14
jmp 0x7453
movl 0x3538b(%rip), %eax     # 0x3c818
cmpl %ebp, %eax
jbe 0x749b
movl %ebp, 0x35381(%rip)     # 0x3c818
xorl %ecx, %ecx
jmp 0x74ba
leaq 0x3541e(%rip), %rcx     # 0x3c8c0
cmpl (%rcx), %r12d
jne 0x74b0
leaq 0x1fe5e(%rip), %rsi     # 0x2730c
jmp 0x74e8
movl 0x3535e(%rip), %ecx     # 0x3c814
incl %ecx
movl %eax, %ebp
movl %ecx, 0x35354(%rip)     # 0x3c814
leaq 0x353fd(%rip), %rax     # 0x3c8c4
cmpl (%rax), %ebp
jbe 0x74e1
leaq 0x352d6(%rip), %rdx     # 0x3c7a8
movb $0x1, %al
cmpl (%rdx), %ecx
jb 0x74fa
leaq 0x1fe5a(%rip), %rsi     # 0x27339
jmp 0x74e8
leaq 0x1fe3b(%rip), %rsi     # 0x27323
movq %rbx, %rdi
callq 0x5370
movq %rbx, %rdi
callq 0x5290
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x35310(%rip), %rdi     # 0x3c820
callq 0x5630
testl %eax, %eax
je 0x7434
movq %r14, %rdi
callq 0xb98c
movl %eax, 0x352ed(%rip)     # 0x3c818
leaq 0x352ee(%rip), %rdi     # 0x3c820
callq 0x5270
jmp 0x7434
movq %rax, %rbx
leaq 0x352da(%rip), %rdi     # 0x3c820
callq 0x5260
jmp 0x7558
movq %rax, %rbx
movq %rsp, %rdi
callq 0x6e4c
movq %rbx, %rdi
callq 0x5610