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

CuckooSearch's runIteration is incompatible with other algorithms runIteration #281

Closed
karakatic opened this issue Dec 1, 2020 · 6 comments

Comments

@karakatic
Copy link

CuckooSearch's runIteration is incompatible with other algorithms' runIteration. It is because of the required argument pa_v. This makes it impossible to use it in the experiments with generic method calls.

def runIteration(self, task, pop, fpop, xb, fxb, pa_v, **dparams):

@karakatic
Copy link
Author

To expand this issue: many NIA optimizers were changed in the latest version to extend the standard required arguments when calling runIteration. Earlier versions forced all the NIA parameter settings at the construction, not in the runIteration call... This change makes NiaPy unusable in other frameworks, where generic runIteration calls are made...

@sisco0
Copy link
Contributor

sisco0 commented Dec 2, 2020

Have a good day @karakatic . Would you recommend to move out these parameters to constructor function instead of being at the runIteration function?

@kb2623
Copy link
Contributor

kb2623 commented Jan 26, 2021

This parameter should not be and issue, because in Algorithm interface, method runYield unpacks the parameter as seen from:

pop, fpop, xb, fxb, dparams = self.runIteration(task, pop, fpop, xb, fxb, **dparams)

Method runIteration has an additional argument, because I mead the code shorter. If there was no additional argument, algorithm developer should manually obtain this parameter from argument dparams.

Many advanced IDEs report this as an issue, as for some other incompatible type problems, but Python code still runs.

Parameter pa_v is set when run is started, seen from:

d.update({'pa_v': self.NP * self.pa})

If this parameter is set when constructing an instance of CuckooSearch class, then the code for updating parameters (method setParametes) should be updated. But this parameter is not a default parameter of Cuckoo Search algorithm, based on article Yang, Xin-She, and Suash Deb. "Cuckoo search via Lévy flights." Nature & Biologically Inspired Computing, 2009. NaBIC 2009. World Congress on. IEEE, 2009, so I did not set this parameter at creation of Cuckoo Search algorithm instance.

@zStupan
Copy link
Contributor

zStupan commented Mar 26, 2021

IDEs report this as a problem because it seemingly goes against the Liskov substitution principle of object oriented programming. But it actually doesn't because of keyword arguments. Also, runIteration is essentially a private/protected method, I see no use case where you would need to call runIteration directly in your code.

In this particular case though, I don't think pa_v should be an additional parameter, because it stays the same through all iterations. It should just be set in the constructor/setParameters method. If it's optional there should be a flag in setParameters, something like use_pa_v=True and if it's true, self.pa should be set to NP * pa.

@karakatic Can you provide an example of this causing problems?

If it's an issue we would just need to change every algorithms runIteration to pop the additional parameters from dparams like I did in my BFOA implementation:

def runIteration(self, task, pop, fpop, xb, fxb, **dparams):
r"""Core function of Bacterial Foraging Optimization algorithm.
Args:
task (Task): Optimization task.
pop (numpy.ndarray): Current population.
fpop (numpy.ndarray): Current populations fitness/function values.
xb (numpy.ndarray): Global best individual.
fxb (float): Global best individuals function/fitness value.
**dparams (Dict[str, Any]): Additional arguments.
Returns:
Tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray, float, Dict[str, Any]]:
1. New population.
2. New populations function/fitness values.
3. New global best solution,
4. New global best solutions fitness/objective value.
5. Additional arguments.
"""
cost = dparams.pop('cost')
health = dparams.pop('health')

We could also just do this to remove the warnings.

@zStupan zStupan mentioned this issue May 7, 2021
@firefly-cpp
Copy link
Contributor

Fixed in #309

@zStupan please post your solution (current status) and final comments before we close this issue.

@zStupan
Copy link
Contributor

zStupan commented May 11, 2021

As I described in my previous comment, for the algorithms that had extra arguments in the run_iteration method, I removed them and popped them from the keyword arguments inside run_iteration.

In the case of CS, the pa_v parameter was actually static, it represents the number of nests abandoned each iteration i. e. pa * population_size, where pa is the probability of a nest being abandoned. So I just added an attribute self.num_abandoned in init which stores that value so no additional parameters are actually needed.

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

5 participants