Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RVEA not reaching specified number of evaluations #564

Open
jordan-cork opened this issue Feb 15, 2024 · 6 comments
Open

RVEA not reaching specified number of evaluations #564

jordan-cork opened this issue Feb 15, 2024 · 6 comments
Assignees

Comments

@jordan-cork
Copy link

jordan-cork commented Feb 15, 2024

RVEA does not complete the specified number of evaluations set by the termination condition.

I've run RVEA on several problems, both those implemented in pymoo and those implemented elsewhere, and never is the algorithm able to achieve the set number of evaluations. Mostly, it finishes in max_evals - pop_size evaluations, however, often it is less, sometimes significantly so. I'm assuming this is a bug and not a feature, as I cannot find mention of some early stopping mechanism in the paper.

As an example of this, I ran RVEA with 100 reference points (Riesz s-energy method) on a large set of 2 and 3 objective problems. The minimize function was used and the termination criteria was 10000 evaluations. Below are the results from individual runs on the CTP problems:

Problem | Total Evaluations
CTP1 | 8246
CTP2 | 9061
CTP3 | 9172
CTP4 | 9101
CTP5 | 9052
CTP6 | 9684
CTP7 | 9631
CTP8 | 9734

One part of the issue is likely due to the setup method that converts the evaluations termination to a generations termination. Here, pop_size is negated from the maximum number of evaluations. In the example above, this results in maximum evaluations being set to 99 as opposed to 100.

    def _setup(self, problem, **kwargs):

        # if maximum functions termination convert it to generations
        if isinstance(self.termination, MaximumFunctionCallTermination):
            n_gen = np.ceil((self.termination.n_max_evals - self.pop_size) / self.n_offsprings)
            self.termination = MaximumGenerationTermination(n_gen)

        # check whether the n_gen termination is used - otherwise this algorithm can be not run
        if not isinstance(self.termination, MaximumGenerationTermination):
            raise Exception("Please use the n_gen or n_eval as a termination criterion to run RVEA!")

The other part may actually be a feature of the survival mechanism. The algorithm's evaluator is recording the correct number of evaluations, despite there being less solutions in the population.

@blankjul
Copy link
Collaborator

blankjul commented Feb 19, 2024

RVEA was proposed as a unconstrained algorithm, thus I don't think it makes sense to test it on the CTP problems.

Originally, the paper has only proposed to have number of generations as termination criterion. However, we have added this fix to provide number of function evaluations as well.

# if maximum functions termination convert it to generations
if isinstance(self.termination, MaximumFunctionCallTermination):
    n_gen = np.ceil((self.termination.n_max_evals - self.pop_size) / self.n_offsprings)
    self.termination = MaximumGenerationTermination(n_gen)

# check whether the n_gen termination is used - otherwise this algorithm can be not run
if not isinstance(self.termination, MaximumGenerationTermination):
    raise Exception("Please use the n_gen or n_eval as a termination criterion to run RVEA!")

@blankjul blankjul self-assigned this Feb 19, 2024
@blankjul
Copy link
Collaborator

Have you noticed the algorithm terminating early by fixing the number of generations as well?

@jordan-cork
Copy link
Author

jordan-cork commented Feb 19, 2024

When I fix the number of generations, it completes these correctly and the algorithm's evaluator records the correct number of evaluations. However, when I 'save_history' and check for the number of solutions saved, there are less. The same occurs when I record solutions using a callback.

I'm now testing on the WFG, DTLZ and ZDT suites and I get the same outcomes.

@blankjul
Copy link
Collaborator

I am not sure if I can follow.

However, when I 'save_history' and check for the number of solutions saved, there are less. 

Not all evaluations are stored in the populatio. It might be an offspring is not improving the current population so it will not be contributing. Or are you actually trying to count all offsprings in each iteration?

@jordan-cork
Copy link
Author

I meant that the res.history object does not store all evaluated solutions. It was my understanding it should.

Also, just to note, RVEA is listed as handling constraints on this page. Perhaps, it shouldn't?

@blankjul
Copy link
Collaborator

Thanks for calling this out! I have updated the table. See my commit above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants