My Particle Swarm Optimization code generates different answers in C++ and MATLAB
Solution 1
You've got integer division in the following line
w = 0.9 - 0.7 * (float) (t / numofiterations);
w will be 0.2 for every iteration, change it to
w = 0.9 - 0.7 * t / numofiterations;
The first multiplication will automatically promote t to a double the division should then promote numof iterations to a double.
The parenthesis means it will be done first and therefore not be promoted as wo integers is involved in the division.
Solution 2
This could be a mistake in function mean
:
return (float)(addvalue / vallength);
This is integer division, so the result is truncated down, then cast to float. It is unlikely this is what you want.
Hamed
An Electronics engineer who is interested in programming and an Ubuntu user for more than 7 years.
Updated on June 05, 2022Comments
-
Hamed almost 2 years
I have written a global version of Particle Swarm Optimization algorithm in C++. I tried to write it exactly as same as my MATLAB PSO code that have written before, but this code generates different and so worst answers. The MATLAB code is:
clear all; numofdims = 30; numofparticles = 50; c1 = 2; c2 = 2; numofiterations = 1000; V = zeros(50, 30); initialpop = V; Vmin = zeros(30, 1); Vmax = Vmin; Xmax = ones(30, 1) * 100; Xmin = -Xmax; pbestfits = zeros(50, 1); worsts = zeros(50, 1); bests = zeros(50, 1); meanfits = zeros(50, 1); pbests = zeros(50, 30); initialpop = Xmin + (Xmax - Xmin) .* rand(numofparticles, numofdims); X = initialpop; fitnesses = testfunc1(X); [minfit, minfitidx] = min(fitnesses); gbestfit = minfit; gbest = X(minfitidx, :); for i = 1:numofdims Vmax(i) = 0.2 * (Xmax(i) - Xmin(i)); Vmin(i) = -Vmax(i); end for t = 1:1000 w = 0.9 - 0.7 * (t / numofiterations); for i = 1:numofparticles if(fitnesses(i) < pbestfits(i)) pbestfits(i) = fitnesses(i); pbests(i, :) = X(i, :); end end for i = 1:numofparticles for j = 1:numofdims V(i, j) = min(max((w * V(i, j) + rand * c1 * (pbests(i, j) - X(i, j))... + rand * c2 * (gbest(j) - X(i, j))), Vmin(j)), Vmax(j)); X(i, j) = min(max((X(i, j) + V(i, j)), Xmin(j)), Xmax(j)); end end fitnesses = testfunc1(X); [minfit, minfitidx] = min(fitnesses); if(minfit < gbestfit) gbestfit = minfit; gbest = X(minfitidx, :); end worsts(t) = max(fitnesses); bests(t) = gbestfit; meanfits(t) = mean(fitnesses); end
In which, testfunc1 is:
function [out] = testfunc1(R) out = sum(R .^ 2, 2); end
The C++ code is:
#include <cstring> #include <iostream> #include <cmath> #include <algorithm> #include <ctime> #define rand_01 ((float)rand() / (float)RAND_MAX) const int numofdims = 30; const int numofparticles = 50; using namespace std; void fitnessfunc(float X[numofparticles][numofdims], float fitnesses[numofparticles]) { memset(fitnesses, 0, sizeof (float) * numofparticles); for(int i = 0; i < numofparticles; i++) { for(int j = 0; j < numofdims; j++) { fitnesses[i] += (pow(X[i][j], 2)); } } } float mean(float inputval[], int vallength) { int addvalue = 0; for(int i = 0; i < vallength; i++) { addvalue += inputval[i]; } return (float)(addvalue / vallength); } void PSO(int numofiterations, float c1, float c2, float Xmin[numofdims], float Xmax[numofdims], float initialpop[numofparticles][numofdims], float worsts[], float meanfits[], float bests[], float *gbestfit, float gbest[numofdims]) { float V[numofparticles][numofdims] = {0}; float X[numofparticles][numofdims]; float Vmax[numofdims]; float Vmin[numofdims]; float pbests[numofparticles][numofdims]; float pbestfits[numofparticles]; float fitnesses[numofparticles]; float w; float minfit; int minfitidx; memcpy(X, initialpop, sizeof(float) * numofparticles * numofdims); fitnessfunc(X, fitnesses); minfit = *min_element(fitnesses, fitnesses + numofparticles); minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses; *gbestfit = minfit; memcpy(gbest, X[minfitidx], sizeof(float) * numofdims); for(int i = 0; i < numofdims; i++) { Vmax[i] = 0.2 * (Xmax[i] - Xmin[i]); Vmin[i] = -Vmax[i]; } for(int t = 0; t < 1000; t++) { w = 0.9 - 0.7 * (float) (t / numofiterations); for(int i = 0; i < numofparticles; i++) { if(fitnesses[i] < pbestfits[i]) { pbestfits[i] = fitnesses[i]; memcpy(pbests[i], X[i], sizeof(float) * numofdims); } } for(int i = 0; i < numofparticles; i++) { for(int j = 0; j < numofdims; j++) { V[i][j] = min(max((w * V[i][j] + rand_01 * c1 * (pbests[i][j] - X[i][j]) + rand_01 * c2 * (gbest[j] - X[i][j])), Vmin[j]), Vmax[j]); X[i][j] = min(max((X[i][j] + V[i][j]), Xmin[j]), Xmax[j]); } } fitnessfunc(X, fitnesses); minfit = *min_element(fitnesses, fitnesses + numofparticles); minfitidx = min_element(fitnesses, fitnesses + numofparticles) - fitnesses; if(minfit < *gbestfit) { *gbestfit = minfit; memcpy(gbest, X[minfitidx], sizeof(float) * numofdims); } worsts[t] = *max_element(fitnesses, fitnesses + numofparticles); bests[t] = *gbestfit; meanfits[t] = mean(fitnesses, numofparticles); } } int main() { time_t t; srand((unsigned) time(&t)); float xmin[30], xmax[30]; float initpop[50][30]; float worsts[1000], bests[1000]; float meanfits[1000]; float gbestfit; float gbest[30]; for(int i = 0; i < 30; i++) { xmax[i] = 100; xmin[i] = -100; } for(int i = 0; i < 50; i++) for(int j = 0; j < 30; j++) { initpop[i][j] = rand() % (100 + 100 + 1) - 100; } PSO(1000, 2, 2, xmin, xmax, initpop, worsts, meanfits, bests, &gbestfit, gbest); cout<<"fitness: "<<gbestfit<<endl; return 0; }
I have debugged two codes many times but can not find the difference which makes answers different. It is making me crazy! May you help me please?
Update:
Please consider that, the function mean is just used for reporting some information and is not used in the optimization procedure.