Implementing an optimization algorithm in WL

I am trying to implement the Jaya optimization algorithm (Jaya). This is a flowchart from the Author 's webpage showing the details of the Algorithm.

Note that there is a typo in the equation in the above figure. It should be:

X'j,k,i = Xj,k,i + r1,j,i (Xj,best,i - │Xj,k,i│) - r2,j,i (Xj,worst,i - │Xj,k,i│)

I have implemented it in the Wolfram Language (WL) as follows:

Setting the parameters

lb = -10; ub = 10; n (*pop size*)= 4; d (*dimension*)= 2; fn (* function number*)= 1;


Initializing the population

x = RandomReal[{lb, ub}, {n, d + 1}];


Calculating the objective function for each individual

Table[x[[i, -1]] = f[x[[i, 1 ;; -2]], fn], {i, 1, n}]; (* f is the objective function. I am using the last element of each solution to store its objective function *)


The Jaya update equation

update[y_] := Module[{z},

z = y + RandomReal[{0, 1}, d] (x[[minIndex, 1 ;; -2]] - Abs[y]) - RandomReal[{0, 1}, d] (x[[maxIndex, 1 ;; -2]] - Abs[y]);

Map[If[# < lb, lb, If[# > ub, ub, #]] &, z]];


One iteration of Jaya

jaya[x_] := Module[{y, fy},

minIndex = First[Ordering[x[[All, -1]], 1]];

maxIndex = First[Ordering[x[[All, -1]], -1]];

y = Map[update, x[[All, 1 ;; -2]]];

fy = Table[f[y[[i, All]], fn], {i, 1, n}];

MapThread[(If[#1[[-1]] <= #2[[-1]], #1, #2]) &, {x, y}]

]


Repeating the update

Timing[Min[Nest[jaya, x, 1000] [[All, -1]]]]


The results when applied to the Sphere function (shown below) are not close to the Matlab implementation of the same Algorithm for the same setting and on the same function.

f[x_, 1] := Total[x^2] (* The Sphere function *)


In addition, the WL implementation is much slower than Matlab even after using Parallelize, ParallelTable, etc.

• Can you please format your code properly inside code blocks   . You've got some syntax errors early on which look like they should be comments e.g (pop size) should be a comment (* popsize *) ? Aug 28, 2021 at 21:26
• I have edit the post to properly format the code. Thanks! Aug 29, 2021 at 7:48
• One of the problematic point is Append - this is very slow operation for iterative process. Switch to usage of Join or something else. Additionally, you can change the jaya[x_] and update[x_] to the pure function style. Like jaya=Module[{x=#,..},..]& It will add the performance too. Aug 29, 2021 at 7:55
• Please add cross-post links between this and the Wolfram Community post. Aug 29, 2021 at 14:44
• Thank you so much Rom38. I really appreciate your valuable feedback. I will do that to improve the performance. But do you think the implementation is correct given that for the same settings Matlab is giving me much better results? Aug 29, 2021 at 20:41

I managed finally to make a faster and correct version for Jaya:

jaya[fun_, l_, u_, d_, popsize_] :=
Block[{x, f, best, worst, bestX, worstX, xn, fn, r1, r2},
x = RandomReal[{l, u}, {popsize, d}];
f = fun /@ x;
Do[
best = x[[First@Ordering[f, 1]]];
worst = x[[First@Ordering[f, -1]]];
bestX = Table[best, popsize];
worstX = Table[worst, popsize];
r1 = RandomReal[{0, 1}, {popsize, d}];
r2 = RandomReal[{0, 1}, {popsize, d}];
xn = x + r1*(bestX - Abs[x]) - r2*(worstX - Abs[x]);
xn = Map[If[# > u, u, If[# < l, l, #]] &, xn, {2}];
fn = Map[fun, xn];
Do[
If[f[[i]] >= fn[[i]], {x[[i]], f[[i]]} = {xn[[i]], fn[[i]]}];
, {i, Length[x]}];
, {2000}];
Min[f]
]


I call it using:

sphere = Compile[{{x, _Real, 1}}, Total[x^2]];
AbsoluteTiming[jaya[sphere, -100., 100., 10., 50.]]


However, it is 4 times slower than my Matlab implementation (even when I replace the outer Do loop with Nest -- it becomes slightly slower).

Is there a way to make the code faster? The Compile does not work with me.