pythonoptimizationdifferential-evolution

scipy.optimize differential_evolution seems to ignore population size limit


I'm using the following code to make experiments and start learnig how to use DE to optimize more complex problems. i need and optimizer that can work with integer numbers.

from scipy.optimize import differential_evolution
def objfun(x):
    print('N')
    return x[0]+2*x[1]**-4*x[2]
solution=differential_evolution(objfun,bounds=((1,10000),(1,200000),(1,50000)),popsize=0,maxiter=3,polish=False,disp=True)

The problem rises when setting popsize. I get more population than expected and if i set it to 0 it keep getting me 10 elements for the first population and then 5 for the other populations till it gets to maxiter.

that's an exampre of the output i get with the above code

runfile('D:/PYTHON/untitled0.py', wdir='D:/PYTHON')
N
N
N
N
N
N
N
N
N
N
differential_evolution step 1: f(x)= 318.074
N
N
N
N
N
differential_evolution step 2: f(x)= 169.667
N
N
N
N
N
differential_evolution step 3: f(x)= 169.667

I really don't understand what i'm doing wrong, at least i expected popsize=0 to give an error. Moreover, are there any other hidden parameters to set initial population size that must be edited?

I'm still a beguinner, i've started with python a few week ago so i'd be really thankfull for a simple explaination.

Thank a lot to everyone who take time to answer me.

Steve


Solution

  • There are a couple parts to the questions so I'll have a couple parts to this answer.

    Why does popsize=0 not throw an error?

    This is in scipy implementation of differential_evolution for why it doesn't throw an error. You can see that the first call will result in 10 calls and while the second and third result in only 5. This is because of the random seed.

    When you call differential_evolution there is an argument seed which determines the "randomness" in the function. Since the first time point, it can be very off from the true value, it will call it 10 times, while in 1 step, the function can optimize to the true value.

    If you set the seed and popsize is 0:

    If you do set a seed then you can reproduce the code and see if it is right.

    Here is where the seed is 0 (it does not optimize more):

    >>> soln = differential_evolution(objfun, bounds=((1,10000),(1,200000),(1,50000)),popsize=0,maxiter=3,polish=False,disp=True, seed=0)
    differential_evolution step 1: f(x)= 1098.52
    differential_evolution step 2: f(x)= 1098.52
    differential_evolution step 3: f(x)= 1098.52
    

    Seed with popsize > 0:

    It could be possible that the first iteration calls the function more times than the last, and this could be due to how the function is being optimized and the stochastic nature of it.

    differential_evolution step 1: f(x)= 183.92
    differential_evolution step 2: f(x)= 183.92
    differential_evolution step 3: f(x)= 5.81206
    

    If we change the popsize to something larger than 10 we will get closer to the minimum.

    >>> soln = differential_evolution(objfun, bounds=((1,10000),(1,200000),(1,50000)),popsize=100,maxiter=3,polish=False,disp=True, seed=0)
    differential_evolution step 1: f(x)= 10.3284
    differential_evolution step 2: f(x)= 8.35376
    differential_evolution step 3: f(x)= 2.65333