Multi particle swarm optimization (MPSO).
163 {
164 FILE *fp=stdout;
165 int verbose=0;
if(status!=NULL) {verbose=status->
verbose; fp=status->
fp;}
166 if(verbose>0) {
167 fprintf(fp, "\n%s(NLOPT, %d, status)\n", __func__, doLocal);
168 fflush(fp);
169 }
170
171 if(nlo==NULL) {
174 }
178 }
180 if(verbose>0) {fprintf(stderr, "Error: too low limit for function calls.\n"); fflush(stderr);}
183 }
184
185
188 if(verbose>1 && fixedParNr>0) fprintf(fp, "fixedParNr := %d\n", fixedParNr);
189 unsigned int fittedParNr=nlo->
totalNr-fixedParNr;
190 if(verbose>2) fprintf(fp, "fittedParNr := %d\n", fittedParNr);
191 if(fittedParNr<1) {
194 }
195
196
197 for(
unsigned int i=0; i<nlo->
totalNr; i++) {
199 if(!(nlo->
xtol[i]>0.0)) {
200 if(verbose>0) {fprintf(stderr, "Error: invalid xtol[].\n"); fflush(stderr);}
203 }
204 }
205
206
207
208 if(verbose>2) fprintf(fp, "\nInitializing MPSO\n");
209
210 if(maxIter<10) maxIter=1000;
211 if(nSwarms<2) nSwarms=2+fittedParNr;
212 if(nParticles<5) nParticles=5+2*fittedParNr;
213 if(!(wInertia>0.0)) wInertia=0.333;
214 if(!(wParticle>0.0)) wParticle=1.00;
215 if(!(wSwarm>0.0)) wSwarm=1.60;
216 if(!isfinite(wGlobal)) wGlobal=0.40;
217 if(!isfinite(pDeath) || pDeath>=0.1)
218 pDeath=0.005; else if(pDeath<0.0) pDeath=0.0;
219 if(!isfinite(pImmigration) || pImmigration>=0.1)
220 pImmigration=0.025; else if(pImmigration<0.0) pImmigration=0.0;
221
226 }
228
229 unsigned int pFrustration=10;
230 unsigned int nFrustration=15;
231
232 if(verbose>3) {
233 fprintf(fp, "maxIter := %u\n", maxIter);
234 fprintf(fp,
"maxFunCalls := %u\n", nlo->
maxFunCalls);
235 fprintf(fp, "nSwarms := %u\n", nSwarms);
236 fprintf(fp, "nParticles := %u\n", nParticles);
237 fprintf(fp, "dim := %u\n", dim);
238 fprintf(fp, "wInertia := %g\n", wInertia);
239 fprintf(fp, "wParticle := %g\n", wParticle);
240 fprintf(fp, "swarm/social (wSwarm) := %g\n", wSwarm);
241 fprintf(fp, "multi-swarm/global (wGlobal) := %g\n", wGlobal);
242 fprintf(fp, "probability of death := %g\n", pDeath);
243 fprintf(fp, "probability of immigration := %g\n", pImmigration);
244 fprintf(fp, "pFrustration := %u\n", pFrustration);
245 fprintf(fp, "nFrustration := %u\n", nFrustration);
246 fflush(fp);
247 }
248
249
250 MPSO_MULTISWARM multi;
251 multi.dim=dim; multi.sn=nSwarms; multi.pn=nParticles;
252 multi.bestPosition=calloc(dim, sizeof(double));
253 multi.swarm=calloc(nSwarms, sizeof(MPSO_SWARM));
254 for(unsigned int si=0; si<nSwarms; si++) {
255 multi.swarm[si].particle=calloc(nParticles, sizeof(MPSO_PARTICLE));
256 multi.swarm[si].bestPosition=calloc(dim, sizeof(double));
257 for(unsigned int pi=0; pi<nParticles; pi++) {
258 multi.swarm[si].particle[pi].position=calloc(dim, sizeof(double));
259 multi.swarm[si].particle[pi].velocity=calloc(dim, sizeof(double));
260 multi.swarm[si].particle[pi].bestPosition=calloc(dim, sizeof(double));
261 }
262 }
263
265
266
267
268
269 int initGuessAvailable=1;
270 double initGuessCost=nan("");
271 for(unsigned int i=0; i<dim; i++) {
272 if(isnan(nlo->
xfull[i])) {initGuessAvailable=0;
break;}
273 if(nlo->
xfull[i]<nlo->
xlower[i]) {initGuessAvailable=0;
break;}
274 if(nlo->
xfull[i]>nlo->
xupper[i]) {initGuessAvailable=0;
break;}
275 }
276 if(initGuessAvailable) {
278 if(!isfinite(initGuessCost)) initGuessAvailable=0;
279 else if(verbose>3) {
280 fprintf(fp, "valid initial guess with cost=%g\n", initGuessCost); fflush(fp);
281 }
282 }
283
284 int carpetFill=0;
285
286 if(carpetFill) {
287
288 multi.bestCost=nan("");
289 for(unsigned int si=0; si<nSwarms; si++) {
290 for(unsigned int pi=0; pi<nParticles; pi++) {
293 for(unsigned int i=0; i<dim; i++)
294 multi.swarm[si].particle[pi].velocity[i]-=multi.swarm[si].particle[pi].position[i];
295 multi.swarm[si].particle[pi].cost=
296 (*nlo->
_fun)(dim, multi.swarm[si].particle[pi].position, nlo->
fundata);
298
299 multi.swarm[si].particle[pi].bestCost=multi.swarm[si].particle[pi].cost;
300 doubleCopy(multi.swarm[si].particle[pi].bestPosition,
301 multi.swarm[si].particle[pi].position, dim);
302 multi.swarm[si].particle[pi].since=0;
303
304 if(pi==0) {
305 if(si==0 && initGuessAvailable) {
306 multi.swarm[si].bestCost=initGuessCost;
308 } else {
309 multi.swarm[si].bestCost=multi.swarm[si].particle[pi].cost;
310 doubleCopy(multi.swarm[si].bestPosition, multi.swarm[si].particle[pi].position, dim);
311 }
312 } else {
313 if(!isfinite(multi.swarm[si].bestCost) ||
314 multi.swarm[si].bestCost>multi.swarm[si].particle[pi].cost)
315 {
316 multi.swarm[si].bestCost=multi.swarm[si].particle[pi].cost;
317 doubleCopy(multi.swarm[si].bestPosition, multi.swarm[si].particle[pi].position, dim);
318 }
319 }
320 }
321
322 if(si==0) {
323 multi.bestCost=multi.swarm[si].bestCost;
324 doubleCopy(multi.bestPosition, multi.swarm[si].bestPosition, dim);
325 } else {
326 if(!isfinite(multi.bestCost) || multi.bestCost>multi.swarm[si].bestCost) {
327 multi.bestCost=multi.swarm[si].bestCost;
328 doubleCopy(multi.bestPosition, multi.swarm[si].bestPosition, dim);
329 }
330 }
331 multi.swarm[si].since=0;
332 }
333 multi.since=0;
334 } else {
335
336 unsigned int si=0;
337 if(initGuessAvailable)
339 for(; si<nSwarms; si++)
341
342 double sd[dim];
343 for(
unsigned int i=0; i<dim; i++) sd[i]=0.13*(nlo->
xupper[i]-nlo->
xlower[i]);
344 for(unsigned int si=0; si<nSwarms; si++) {
345 for(unsigned int pi=1; pi<nParticles; pi++) {
347 multi.swarm[si].particle[0].position, sd, nlo->
xlower, nlo->
xupper, dim,
348 &multi.mt);
349 }
350 }
351
352 for(
unsigned int i=0; i<dim; i++) sd[i]=0.23*(nlo->
xupper[i]-nlo->
xlower[i]);
353 double mvel[dim]; for(unsigned int i=0; i<dim; i++) mvel[i]=0.0;
354 for(unsigned int si=0; si<nSwarms; si++) {
355 for(unsigned int pi=0; pi<nParticles; pi++) {
357 mvel, sd, NULL, NULL, dim, &multi.mt);
358 }
359 }
360
361 multi.bestCost=nan("");
362 for(unsigned int si=0; si<nSwarms; si++) {
363 multi.swarm[si].bestCost=nan("");
364 for(unsigned int pi=0; pi<nParticles; pi++) {
365 multi.swarm[si].particle[pi].cost=
366 (*nlo->
_fun)(dim, multi.swarm[si].particle[pi].position, nlo->
fundata);
368
369 multi.swarm[si].particle[pi].bestCost=multi.swarm[si].particle[pi].cost;
370 doubleCopy(multi.swarm[si].particle[pi].bestPosition,
371 multi.swarm[si].particle[pi].position, dim);
372 multi.swarm[si].particle[pi].since=0;
373
374 if(!isfinite(multi.swarm[si].bestCost) ||
375 multi.swarm[si].bestCost>multi.swarm[si].particle[pi].cost)
376 {
377 multi.swarm[si].bestCost=multi.swarm[si].particle[pi].cost;
379 multi.swarm[si].particle[pi].position, dim);
380 }
381 }
382
383 if(!isfinite(multi.bestCost) || multi.bestCost>multi.swarm[si].bestCost) {
384 multi.bestCost=multi.swarm[si].bestCost;
385 doubleCopy(multi.bestPosition, multi.swarm[si].bestPosition, dim);
386 }
387 multi.swarm[si].since=0;
388 }
389 multi.since=0;
390 }
391
392
393
394 double lastBestPosition[dim];
395 unsigned int movementCounter=0;
396 unsigned int convergenceCounter=0;
397
398 unsigned int stopCostLimit=20, stopCost=0;
399 double lastBestCost=multi.bestCost;
400
401 unsigned int iterNr=0;
402 while(iterNr<maxIter && nlo->funCalls<nlo->maxFunCalls) {
403 iterNr++;
404 if(verbose>4) {
405 fprintf(fp, "-----------------------------\nloop %d\n", iterNr);
406 fprintf(fp, "bestCost=%g since %u iterations\n", multi.bestCost, multi.since);
407 if(verbose>5) fprintf(fp,
"function_calls_so_far=%d\n", nlo->
funCalls);
408 fflush(fp);
409 }
410
411
412#if(0)
413
414 unsigned int swarmsConcentrated=0;
415 for(unsigned int si=0; si<nSwarms; si++) {
416 double psd[dim], vmean[dim], vsd[dim];
419 if(verbose>5) {
420 fprintf(fp, "swarm %d bestCost=%g since %u\n", 1+si,
421 multi.swarm[si].bestCost, multi.swarm[si].since);
422 if(verbose>6) {
423 fprintf(fp, " bestPosition: %g", multi.swarm[si].bestPosition[0]);
424 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %g", multi.swarm[si].bestPosition[i]);
425 fprintf(fp, "\n");
426 }
427 if(verbose>9 || iterNr==1) {
428 for(unsigned int i=0; i<dim; i++)
429 fprintf(fp, " parameter %d: meanPosition %g +- %g\n", 1+i, pmean[i], psd[i]);
430 for(unsigned int i=0; i<dim; i++)
431 fprintf(fp, " parameter %d: meanAbsVelocity %g +- %g\n", 1+i, vmean[i], vsd[i]);
432 }
433 fflush(fp);
434 }
435
436
437 unsigned int i=0;
438 for(i=0; i<dim; i++) {
439 if(fabs(pmean[i] - multi.swarm[si].bestPosition[i]) > 0.01*nlo->
xtol[i])
break;
440 if(psd[i]>0.02*nlo->
xtol[i])
break;
441 }
442 if(i==dim) {
443 if(verbose>5) fprintf(fp, " swarm %d particles inside tolerance.\n", 1+si);
444 swarmsConcentrated++;
445 }
446 }
447 if(swarmsConcentrated==nSwarms) {
448 if(verbose>2) fprintf(fp, " all swarm particles shrunk inside swarm tolerance.\n");
449 break;
450 }
451#endif
452
453
454
455 unsigned int swarmsConcentrated=0;
456 multi.since++;
457 for(unsigned int si=0; si<nSwarms; si++) {
458 multi.swarm[si].since++;
459
460
461 double pmean[dim], psd[dim], vmean[dim], vsd[dim];
464 if(verbose>5) {
465 fprintf(fp, "swarm %d bestCost=%g since %u\n", 1+si,
466 multi.swarm[si].bestCost, multi.swarm[si].since);
467 if(verbose>6) {
468 fprintf(fp, " bestPosition: %g", multi.swarm[si].bestPosition[0]);
469 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %g", multi.swarm[si].bestPosition[i]);
470 fprintf(fp, "\n");
471 }
472 if(verbose>7 || iterNr==1) {
473 for(unsigned int i=0; i<dim; i++)
474 fprintf(fp, " parameter %d: meanPosition %g +- %g\n", 1+i, pmean[i], psd[i]);
475 for(unsigned int i=0; i<dim; i++)
476 fprintf(fp, " parameter %d: meanAbsVelocity %g +- %g\n", 1+i, vmean[i], vsd[i]);
477 }
478 fflush(fp);
479 }
480
481
482 {
483 unsigned int i=0;
484 for(i=0; i<dim; i++) {
485 if(fabs(pmean[i] - multi.swarm[si].bestPosition[i]) > 0.01*nlo->
xtol[i])
break;
486 if(psd[i]>0.02*nlo->
xtol[i])
break;
487 }
488 if(i==dim) {
489 if(verbose>5) fprintf(fp, " swarm %d particles inside tolerance.\n", 1+si);
490 swarmsConcentrated++;
491 }
492 }
493
494
495
496
497 int swarmFrustrated=0;
498 if(multi.swarm[si].since>=nFrustration) {
499 swarmFrustrated=1; multi.swarm[si].since=0;
500 if(verbose>5) {fprintf(fp, "swarm is frustrated\n"); fflush(fp);}
501 }
502
503
504 if(doLocal && !swarmFrustrated && (iterNr%10)==0) {
505 if(verbose>5) {fprintf(fp, "local optimization:\n"); fflush(fp);}
506
508
509 for(unsigned int i=0; i<dim; i++) {
511 if(psd[i]>nlo->
xtol[i]) {nlo->
xdelta[i]=psd[i];
continue;}
513 }
514 if(verbose>7) {
515 fprintf(fp, "initial guesses and deltas, with cost %g:\n", multi.swarm[si].bestCost);
516 for(
unsigned int i=0; i<dim; i++) fprintf(fp,
"\t%e\t%e\n", nlo->
xfull[i], nlo->
xdelta[i]);
517 fflush(fp);
518 }
521 if(cost<multi.swarm[si].bestCost) {
522 multi.swarm[si].bestCost=cost;
524 multi.swarm[si].since=0;
525 if(verbose>7) {
526 fprintf(fp, "results: %e", multi.swarm[si].bestPosition[0]);
527 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %e", multi.swarm[si].bestPosition[i]);
528 fprintf(fp, ", with cost: %g\n", cost); fflush(fp);
529 }
530 } else {
531 if(verbose>10) fprintf(fp, "local optimization did not provide lower cost (%e)\n", cost);
532 }
533 } else {
534 if(verbose>10) fprintf(fp, "local optimization failed.\n");
535 }
536 }
537
538
539 for(unsigned int pi=0; pi<nParticles; pi++) {
540
541 if(verbose>14) {
542 fprintf(fp, " particle %d bestCost=%g since %u\n", 1+pi,
543 multi.swarm[si].particle[pi].bestCost, multi.swarm[si].particle[pi].since);
544 fflush(fp);
545 }
546
547
548
549 int killed=0;
551 || isnan(multi.swarm[si].particle[pi].cost))
552 {
553 killed=1; multi.swarm[si].particle[pi].since=0;
554
555 if(verbose>12) {fprintf(fp, "death of particle %u\n", 1+pi); fflush(fp);}
556
559 for(unsigned int i=0; i<dim; i++)
560 multi.swarm[si].particle[pi].velocity[i]-=multi.swarm[si].particle[pi].position[i];
561
562 multi.swarm[si].particle[pi].cost=
563 (*nlo->
_fun)(dim, multi.swarm[si].particle[pi].position, nlo->
fundata);
565
566 if(multi.swarm[si].particle[pi].bestCost>multi.swarm[si].particle[pi].cost) {
567 if(verbose>10) printf("Miracle: resurrection led to a new best!\n");
568 multi.swarm[si].particle[pi].bestCost=multi.swarm[si].particle[pi].cost;
569 doubleCopy(multi.swarm[si].particle[pi].bestPosition,
570 multi.swarm[si].particle[pi].position, dim);
571 }
572 }
573
574
575 int immigrated=0;
577 immigrated=1; multi.swarm[si].particle[pi].since=0;
578
579 if(verbose>12) {fprintf(fp, " immigration\n"); fflush(fp);}
580 unsigned int sj;
581 if(nSwarms<4) {
582 sj=si+1; if(sj>=nSwarms) sj=si-1;
583 } else {
585 }
586 if(verbose>12) fprintf(fp, " swapping particle %d between swarms %d and %d\n", 1+pi, 1+si, 1+sj);
587 for(unsigned int i=0; i<dim; i++) {
588
589 double d=multi.swarm[si].particle[pi].position[i];
590 multi.swarm[si].particle[pi].position[i]=multi.swarm[sj].particle[pi].position[i];
591 multi.swarm[sj].particle[pi].position[i]=d;
592
593 d=multi.swarm[si].particle[pi].velocity[i];
594 multi.swarm[si].particle[pi].velocity[i]=multi.swarm[sj].particle[pi].velocity[i];
595 multi.swarm[sj].particle[pi].velocity[i]=d;
596 }
597
598 double d=multi.swarm[si].particle[pi].cost;
599 multi.swarm[si].particle[pi].cost=multi.swarm[sj].particle[pi].cost;
600 multi.swarm[sj].particle[pi].cost=d;
601
602 d=multi.swarm[si].particle[pi].bestCost;
603 multi.swarm[si].particle[pi].bestCost=multi.swarm[sj].particle[pi].bestCost;
604 multi.swarm[sj].particle[pi].bestCost=d;
605 for(unsigned int i=0; i<dim; i++) {
606 double d=multi.swarm[si].particle[pi].bestPosition[i];
607 multi.swarm[si].particle[pi].bestPosition[i]=multi.swarm[sj].particle[pi].bestPosition[i];
608 multi.swarm[sj].particle[pi].bestPosition[i]=d;
609 }
610
611 if(multi.swarm[si].bestCost>multi.swarm[si].particle[pi].bestCost) {
612 multi.swarm[si].bestCost=multi.swarm[si].particle[pi].bestCost;
613 doubleCopy(multi.swarm[si].bestPosition, multi.swarm[si].particle[pi].bestPosition, dim);
614 }
615 if(multi.swarm[sj].bestCost>multi.swarm[sj].particle[pi].bestCost) {
616 multi.swarm[sj].bestCost=multi.swarm[sj].particle[pi].bestCost;
617 doubleCopy(multi.swarm[sj].bestPosition, multi.swarm[sj].particle[pi].bestPosition, dim);
618 }
619 }
620
621
622 int frustrated=0;
623 if(multi.swarm[si].particle[pi].since>=nFrustration && !killed && !immigrated) {
624 frustrated=1;
625 }
626 if(!frustrated && !killed && !immigrated && multi.swarm[si].particle[pi].since>2) {
627
628 frustrated=1;
629 for(unsigned int pj=0; pj<nParticles; pj++) if(pi!=pj)
630 if(multi.swarm[si].particle[pj].cost>multi.swarm[si].particle[pi].cost) {
631 frustrated=0; break;}
632 }
633 if(frustrated) {
634 multi.swarm[si].particle[pi].since=0;
635
636 if(verbose>12) {
637 fprintf(fp, " particle %u became frustrated\n", 1+pi);
638 fprintf(fp, " current position: %g", multi.swarm[si].particle[pi].position[0]);
639 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %g", multi.swarm[si].particle[pi].position[i]);
640 fprintf(fp, " -> %g\n", multi.swarm[si].particle[pi].cost);
641 fflush(fp);
642 }
643 }
644
645
646
647 if(!frustrated) {
648 for(
unsigned int i=0; i<dim; i++)
if(nlo->
xupper[i]>nlo->
xlower[i]) {
649 multi.swarm[si].particle[pi].velocity[i] =
650 wInertia*multi.swarm[si].particle[pi].velocity[i];
652 (multi.swarm[si].particle[pi].bestPosition[i] - multi.swarm[si].particle[pi].position[i]);
654 (multi.swarm[si].bestPosition[i] - multi.swarm[si].particle[pi].position[i]);
655 if(wGlobal>0.0)
657 (multi.bestPosition[i] - multi.swarm[si].particle[pi].position[i]);
658 }
659 if(swarmFrustrated) {
660
661 for(
unsigned int i=0; i<dim; i++)
if(nlo->
xupper[i]>nlo->
xlower[i]) {
663 if(multi.swarm[si].particle[pi].velocity[i]>0.0)
664 multi.swarm[si].particle[pi].velocity[i]+=v;
665 else multi.swarm[si].particle[pi].velocity[i]-=v;
666 }
667 }
668 } else {
669
670 for(
unsigned int i=0; i<dim; i++)
if(nlo->
xupper[i]>nlo->
xlower[i]) {
671 multi.swarm[si].particle[pi].velocity[i] =
672 0.11*wInertia*multi.swarm[si].particle[pi].velocity[i] +
673 0.89*(pmean[i] - multi.swarm[si].particle[pi].position[i]);
674 }
675 }
676 if(wGlobal<0.0 && nSwarms>1) {
677 for(unsigned int sj=0; sj<nSwarms; sj++) if(si!=sj) {
678 for(
unsigned int i=0; i<dim; i++)
if(nlo->
xupper[i]>nlo->
xlower[i]) {
680 (multi.swarm[sj].bestPosition[i] - multi.swarm[si].particle[pi].position[i]);
681 }
682 }
683 }
684 if(verbose>15 || (verbose>12 && frustrated)) {
685 fprintf(fp, " updated velocities: %g", multi.swarm[si].particle[pi].velocity[0]);
686 for(unsigned int i=1; i<dim; i++)
687 fprintf(fp, ", %g", multi.swarm[si].particle[pi].velocity[i]);
688 fprintf(fp, "\n");
689 }
690
691
692 for(unsigned int i=0; i<dim; i++)
693 multi.swarm[si].particle[pi].position[i]+=multi.swarm[si].particle[pi].velocity[i];
694
695 for(unsigned int i=0; i<dim; i++)
696 if(multi.swarm[si].particle[pi].position[i]<nlo->
xlower[i]) {
697 multi.swarm[si].particle[pi].position[i]=nlo->
xlower[i];
698
699 multi.swarm[si].particle[pi].velocity[i]*=-0.1;
700 }
else if(multi.swarm[si].particle[pi].position[i]>nlo->
xupper[i]) {
701 multi.swarm[si].particle[pi].position[i]=nlo->
xupper[i];
702
703 multi.swarm[si].particle[pi].velocity[i]*=-0.1;
704 }
705 if(verbose>15 || (verbose>12 && frustrated)) {
706 fprintf(fp, " updated positions: %g", multi.swarm[si].particle[pi].position[0]);
707 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %g", multi.swarm[si].particle[pi].position[i]);
708 fprintf(fp, "\n");
709 }
710
711
712
713 multi.swarm[si].particle[pi].cost=
714 (*nlo->
_fun)(dim, multi.swarm[si].particle[pi].position, nlo->
fundata);
716 if(verbose>15 || (verbose>12 && frustrated))
717 fprintf(fp, " updated_cost=%g\n", multi.swarm[si].particle[pi].cost);
718
719
720
721 if(multi.swarm[si].particle[pi].bestCost>multi.swarm[si].particle[pi].cost) {
722 multi.swarm[si].particle[pi].bestCost=multi.swarm[si].particle[pi].cost;
723 doubleCopy(multi.swarm[si].particle[pi].bestPosition,
724 multi.swarm[si].particle[pi].position, dim);
725 multi.swarm[si].particle[pi].since=0;
726 } else {
727 multi.swarm[si].particle[pi].since++;
728 }
729
730
731
732 if(multi.swarm[si].bestCost>multi.swarm[si].particle[pi].bestCost) {
733 multi.swarm[si].bestCost=multi.swarm[si].particle[pi].bestCost;
734 doubleCopy(multi.swarm[si].bestPosition, multi.swarm[si].particle[pi].bestPosition, dim);
735 multi.swarm[si].since=0;
736 }
737
738 }
739
740
741 if(multi.bestCost>multi.swarm[si].bestCost) {
742 multi.bestCost=multi.swarm[si].bestCost;
743 doubleCopy(multi.bestPosition, multi.swarm[si].bestPosition, dim);
744 multi.since=0;
745 }
746
747 }
748
749
750 if(swarmsConcentrated==nSwarms) {
751 if(verbose>2) fprintf(fp, " all swarm particles shrunk inside swarm tolerance.\n");
752 break;
753 }
754
755
756
757
758 if(nSwarms>1 && iterNr>10) {
759 int swarmsConverged=1;
760 for(unsigned int i=0; i<dim; i++) {
761 for(unsigned int si=0; si<nSwarms; si++) {
762 double d=fabs(multi.bestPosition[i]-multi.swarm[si].bestPosition[i]);
763 if(d>nlo->
xtol[i]) {swarmsConverged=0; convergenceCounter=0;
break;}
764 }
765 if(!swarmsConverged) break;
766 }
767 if(swarmsConverged) {
768 convergenceCounter++;
769 if(convergenceCounter>5) {
770 if(verbose>3) fprintf(fp, "all swarms converged into one minimum.\n");
771
772 }
773 }
774 }
775
776
777
778 if(iterNr>=20) {
779 int moved=0;
780 for(unsigned int i=0; i<dim; i++) {
781 double d=fabs(lastBestPosition[i]-multi.bestPosition[i]);
782 if(d>0.1*nlo->
xtol[i]) {moved=1; movementCounter=0;
break;}
783 }
784 if(moved==0) {
785 movementCounter++;
786 if(movementCounter>10) {
787 if(verbose>3)
788 fprintf(fp, "best position did not improve in %d last loops.\n", movementCounter);
789#if(0)
790 if(verbose>80 && movementCounter>10) {
791 fprintf(fp, "Why does the movement not continue?\n");
792 for(unsigned int si=0; si<nSwarms; si++) {
793 fprintf(fp, "Swarm %d : bestCost=%g\n", 1+si, multi.swarm[si].bestCost);
794
795 unsigned int pBest=0;
796 double pBestCost=multi.swarm[si].particle[0].cost;
797 for(unsigned int pi=1; pi<nParticles; pi++)
798 if(multi.swarm[si].particle[pi].cost<pBestCost) {
799 pBestCost=multi.swarm[si].particle[pi].cost; pBest=pi;
800 }
801 fprintf(fp, " currentBestCost=%g\n", pBestCost);
802 fprintf(fp, "\tDim\toPos\tcPos\tcVel\n");
803 for(unsigned int i=0; i<dim; i++) {
804 fprintf(fp, "\t%d\t%g\t%g\t%g\n", 1+i, multi.swarm[si].bestPosition[i],
805 multi.swarm[si].particle[pBest].position[i],
806 multi.swarm[si].particle[pBest].velocity[i]);
807 }
808 }
809 }
810#endif
811 }
812 }
813 if(movementCounter>20+dim) {
814 fprintf(fp, "best position did not move markedly in %d last loops.\n", movementCounter);
815 break;
816 }
817 }
818 doubleCopy(lastBestPosition, multi.bestPosition, dim);
819
820
821
822 if(multi.bestCost<lastBestCost) {
823 lastBestCost=multi.bestCost;
824 stopCost=0;
825 } else {
826 stopCost++;
827 }
828 if(stopCost>=stopCostLimit) {
829 if(verbose>1) fprintf(fp, "Cost did not improve in %d last iterations.\n", stopCost);
830 break;
831 }
832
833
834 }
835
836
837 if(iterNr>=maxIter) {
838 if(verbose>1) fprintf(fp, "exceeded the maximum number for loops.\n");
839 }
841 if(verbose>1) fprintf(fp, "exceeded the maximum number for function calls.\n");
842 }
843
844
846
847
848 if(verbose>2) {
849 fprintf(fp, "\n---- MPSO end analysis ----\n");
850 fprintf(fp, "loops: %d\n", iterNr);
851 fprintf(fp,
"function calls: %d\n", nlo->
funCalls);
852 for(unsigned int si=0; si<nSwarms; si++) {
853 fprintf(fp, "\nSwarm %d : bestCost=%g\n", 1+si, multi.swarm[si].bestCost);
854 for(unsigned int i=0; i<dim; i++) {
855 fprintf(fp, "parameter %d: bestPosition %g\n", 1+i, multi.swarm[si].bestPosition[i]);
856 }
857 double pmean[dim], psd[dim];
859 for(unsigned int i=0; i<dim; i++) {
860 fprintf(fp, "parameter %d: meanPosition %g +- %g\n", 1+i, pmean[i], psd[i]);
861 }
863 for(unsigned int i=0; i<dim; i++) {
864 fprintf(fp, "parameter %d: meanAbsVelocity %g +- %g\n", 1+i, pmean[i], psd[i]);
865 }
866
867 }
868 fprintf(fp, "\nOverall bestCost=%g\n", multi.bestCost);
869 fprintf(fp, "at position: %g", multi.bestPosition[0]);
870 for(unsigned int i=1; i<dim; i++) fprintf(fp, ", %g", multi.bestPosition[i]);
871 fprintf(fp, "\n"); fflush(fp);
872 }
873
874
875 for(unsigned int si=0; si<nSwarms; si++) {
876 for(unsigned int pi=0; pi<nParticles; pi++) {
877 free(multi.swarm[si].particle[pi].position);
878 free(multi.swarm[si].particle[pi].velocity);
879 free(multi.swarm[si].particle[pi].bestPosition);
880 }
881 free(multi.swarm[si].particle);
882 free(multi.swarm[si].bestPosition);
883 }
884 free(multi.bestPosition);
885 free(multi.swarm);
886
887
890}
void doubleCopy(double *t, double *s, const unsigned int n)
void mertwiInitWithSeed64(MERTWI *mt, uint64_t seed)
Initialize the state vector mt[] inside data structure for Mersenne Twister MT19937 pseudo-random num...
double mertwiRandomDouble1(MERTWI *mt)
Generate a 64-bit double precision floating point pseudo-random number in the range of [0,...
double mertwiRandomExponential(MERTWI *mt, double mean)
Generate pseudo-random number with exponential distribution and specified mean.
uint64_t mertwiSeed64(void)
Make uint64_t seed for pseudo-random number generators.
void mertwiInit(MERTWI *mt)
int64_t mertwiRandomInt63(MERTWI *mt)
Generate a random number on [0, 2^63-1]-interval using Mersenne Twister MT19937.
void nloptMPSOabsvMean(MPSO_MULTISWARM *ms, unsigned int si, double *mean, double *sd)
void nloptMPSOpMean(MPSO_MULTISWARM *ms, unsigned int si, double *mean, double *sd)
unsigned int nloptLimitFixedNr(NLOPT *d)
int nloptRandomPoint(double *p, double *low, double *up, unsigned int n, MERTWI *mt)
int nloptGaussianPoint(double *p, double *mean, double *sd, double *low, double *up, unsigned int n, MERTWI *mt)
int nloptSimplex(NLOPT *nlo, unsigned int maxIter, TPCSTATUS *status)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
double(* _fun)(int, double *, void *)
int verbose
Verbose level, used by statusPrint() etc.
FILE * fp
File pointer for writing log information during development and testing.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_FAIL
General error.
@ TPCERROR_NO_DATA
File contains no data.