mazhar-ansari-ardeh/BenchmarkFcns

Ackley function No.3 has confusing properties

Closed this issue · 3 comments

whzup commented

Hello, I tried to implement the Ackley function No.3 in Python and found that the minimum differed from the properties on benchmarkfncs.xyz. I then tried to look it up in the cited paper but there was yet another minimum for the Ackley function No.3. This is my implementation:

j = -200.0 * np.exp(-0.2 * np.sqrt(x_ ** 2.0 + y_ ** 2.0)) + 5.0 * np.exp(
        np.cos(3.0 * x_) + np.sin(3.0 * y_)
    )

Could you clarify which minimum is right?

Hi there.
Thanks for your interest in this repository.
For this function, I could not find any resources that would specify a unique value for the function's minima (is the minima of the function known?). As a result, I turned to Matlab's Optimization Toolbox and obtained the values that are in the function's web page with Matlab's implementation of Genetic Algorithm. Different runs of the algorithm gave different results (which is a normal behaviour because GA is a stochastic algorithm) and I took the one with the lowest function value. I should have mentioned this in the page but unfortunately I forgot. I will add this explanation some time soon.
I hope this explanation is satisfactory.
If you have any more information about this function, I will be grateful if you could share it with me.
Regards

whzup commented

Thanks @mazhar-ansari-ardeh for your quick response 😄 I really appreciate your project! I used the project I work on (pyswarms) to determine the plot and the optimum of the function.

The code I used for reference
import pyswarms as ps
import numpy as np
from pyswarms.utils.plotters.formatters import Mesher, Designer
import matplotlib.pyplot as plt

def cost_function(X):
    x_ = X[:, 0]
    y_ = X[:, 1]

    j = -200.0 * np.exp(-0.2 * np.sqrt(x_ ** 2.0 + y_ ** 2.0)) + 5.0 * np.exp(
        np.cos(3.0 * x_) + np.sin(3.0 * y_)
    )

    return j

m = Mesher(func=cost_function,
                               delta=0.1,
                               levels=np.arange(-200, 0, 10),
                               limits=[(-10, 10), (-10, 10)])

d = Designer(limits=[(-10, 10), (-10, 10), (-200, 0)],
                                label=['x-axis', 'y-axis', 'z-axis'])

optimizer = ps.single.GlobalBestPSO(n_particles=12,
                                    dimensions=2,
                                    options={"c1": 0.7, "c2": 0.7, "w":0.5},
                                    )

best_cost, best_pos = optimizer.optimize(cost_function, iters=1000)

pos_history_3d = m.compute_history_3d(optimizer.pos_history)
animation3d= ps.utils.plotters.plot_surface(pos_history=pos_history_3d,
                           mesher=m,
                           designer=d,
                           mark=(0,0,-186.4))

ps.utils.plotters.plot_contour(pos_history=optimizer.pos_history,
             mesher=m,
             designer=d,
             mark=(0,0))
plt.show()
print(best_cost, best_pos)

After some runs, the optimum turns out to be around:
[-1.86557969e-10, -6.77345513e-03, -186.4112127112689]

Regarding the z-value, it didn't change for small deviations in x and y so I guess it's a pretty good approximation.

I did some plotting with the implementation of the function I mentioned above. A 3D plot:

ackley_3_3d

And here is a contour plot:

ackley_3_contour

It looks like the Matlab implementation is not the same as the formal function.

Thank you for your kind comment. I am glad that you find it useful.

Nice job with the plots. Thanks for sharing them.

Because I am not aware of the actual minima of the function, I cannot make any assertion about the correctness of the values that I have given in the website. After your post, I modified the website to indicate this fact and hope that will be less confusing.

Cheers.