Skip to content

Instantly share code, notes, and snippets.

@pablormier
Last active March 12, 2024 16:59
Show Gist options
  • Save pablormier/0caff10a5f76e87857b44f63757729b0 to your computer and use it in GitHub Desktop.
Save pablormier/0caff10a5f76e87857b44f63757729b0 to your computer and use it in GitHub Desktop.
Small and efficient implementation of the Differential Evolution algorithm using the rand/1/bin schema
import numpy as np
def de(fobj, bounds, mut=0.8, crossp=0.7, popsize=20, its=1000):
dimensions = len(bounds)
pop = np.random.rand(popsize, dimensions)
min_b, max_b = np.asarray(bounds).T
diff = np.fabs(min_b - max_b)
pop_denorm = min_b + pop * diff
fitness = np.asarray([fobj(ind) for ind in pop_denorm])
best_idx = np.argmin(fitness)
best = pop_denorm[best_idx]
for i in range(its):
for j in range(popsize):
idxs = [idx for idx in range(popsize) if idx != j]
a, b, c = pop[np.random.choice(idxs, 3, replace = False)]
mutant = np.clip(a + mut * (b - c), 0, 1)
cross_points = np.random.rand(dimensions) < crossp
if not np.any(cross_points):
cross_points[np.random.randint(0, dimensions)] = True
trial = np.where(cross_points, mutant, pop[j])
trial_denorm = min_b + trial * diff
f = fobj(trial_denorm)
if f < fitness[j]:
fitness[j] = f
pop[j] = trial
if f < fitness[best_idx]:
best_idx = j
best = trial_denorm
yield best, fitness[best_idx]
@pablormier
Copy link
Author

Hi,

You have to provide an objective function to optimize, which returns a number. x ** 2 / len(x) in you case is a 32 vector, but sum(x**2)/len(x) is a number.

Cheers,
P

@vietvo89-ADL
Copy link

Hi Pablo

Thank you for your response. So you mean if any objective function = f(x) returns a vector/matrix/array will not work. Is it right? In this case, I have to select which dimension of a vector/matric/array such as f [i, j, k] to return?

How about the issue "ImportError: cannot import name 'problem'"? What's wrong?

Thanks

Viet

@pablormier
Copy link
Author

Yes you are right, you need to assign values to your vectors that you can compare. If your goal is to maximize or minimize other kind of funcion, you would need multiobjective optimization.

The import problems you are having I guess is for not using Yabox?:

pip install yabox

Then in python:

from yabox import problems

It should work.

Cheers

@rjm227
Copy link

rjm227 commented Oct 1, 2020

hi Pablo, how I fit the follow function in your code? fobj = lambda x: sum(((1-x) ^2)+ 100*(((x+1) - x^2)^2)/len(x-1)
all the bounds i put give me a SyntaxError: invalid syntax

@pablormier
Copy link
Author

Python does not use the ^ operator, but ** instead: (1-x)**2 + 100...

@mj-ribeiro
Copy link

Hi Pablo, I have the same problem: cannot import name 'problem' from 'yabox.problems'

I installed yabox in my machine and doesn't work.

@bummuck
Copy link

bummuck commented Oct 31, 2023

Hi how should I change the code to get best/1/bin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment