--- /dev/null
+#include <gtk/gtk.h>
+
+GtkApplication *gui_init();
+++ /dev/null
-typedef struct particle particle;
-
-typedef struct {
- double min;
- double max;
-} range;
-
-typedef struct {
- double *x;
- double fitness;
-} particle_state;
-
-typedef struct {
- int particlec;
- particle *particles;
- particle *global_best;
-} swarm;
-
-struct particle {
- particle_state current;
- particle_state best;
- double *velocity;
-};
-
-void pick(const int dim, const range *vrange, double *v);
-void swarm_init(swarm *sw, const int dim, const range *vrange);
-void swarm_velocity_update(swarm *sw, const int dim);
--- /dev/null
+typedef struct particle particle;
+
+typedef struct {
+ double min;
+ double max;
+} range;
+
+typedef struct {
+ double *x;
+ double fitness;
+} particle_state;
+
+typedef struct {
+ int dim;
+ double (*f)(double*);
+ int particlec;
+ double eps;
+ double w;
+ double c;
+ double s;
+} swarm_parameters;
+
+typedef struct {
+ swarm_parameters params;
+ particle *particles;
+ particle *global_best;
+} swarm;
+
+struct particle {
+ particle_state current;
+ particle_state best;
+ double *velocity;
+};
+
+void pick(const int dim, const range *vrange, double *v);
+void swarm_populate(swarm *sw, const range *rrange);
+void swarm_velocity_update(swarm *sw);
+void swarm_optimize(swarm *sw);
--- /dev/null
+#include "gui.h"
+
+static void on_activate(GtkApplication *app) {
+ GtkWidget *window = gtk_application_window_new(app);
+ GtkWidget *button = gtk_button_new_with_label("Hello, World!");
+ g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_close), window);
+ gtk_window_set_child(GTK_WINDOW(window), button);
+ gtk_window_present(GTK_WINDOW(window));
+}
+
+GtkApplication *gui_init() {
+ GtkApplication *app = gtk_application_new("org.wafflesoft.NCPSO", G_APPLICATION_DEFAULT_FLAGS);
+ g_signal_connect(app, "activate", G_CALLBACK(on_activate), NULL);
+ return app;
+}
--- /dev/null
+#include "vector.h"
+#include "swarm.h"
+#include "gui.h"
+
+double b0(double *x) {
+ return -x[0];
+}
+
+double b1(double *x) {
+ return -x[1];
+}
+
+double b2(double *x) {
+ return x[0] - 10;
+}
+
+double b3(double *x) {
+ return x[1] - 15;
+}
+
+double f(double *x) {
+ return exp(b0(x)) + exp(b1(x)) + exp(b2(x)) + exp(b3(x)) + x[0] - x[1];
+}
+
+int main(int argc, char *argv[]) {
+ swarm sw = {
+ 2,
+ f,
+ 100,
+ pow(2, 40),
+ 0.8,
+ 2.05,
+ 2.05
+ };
+ range rrange[2] = {
+ (range) { -100.0, 100.0 },
+ (range) { -100.0, 100.0 }
+ };
+ swarm_populate(&sw, rrange);
+ swarm_optimize(&sw);
+ printf("APSO: converged in x=");
+ vec_print(sw.params.dim, sw.global_best->current.x);
+ printf(" with fitness f(x)=%f\n", sw.global_best->current.fitness);
+ // GtkApplication *app = gui_init();
+ // return g_application_run(G_APPLICATION(app), argc, argv);
+ return 0;
+}
+++ /dev/null
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "particle_swarm.h"
-#include "vector.h"
-#include <gtk/gtk.h>
-
-double c = 2.05;
-double s = 2.05;
-double w = 0.8;
-
-double rands() {
- return (double) rand() / RAND_MAX;
-}
-
-double randrange(double min, double max) {
- return rands() * (max - min) + min;
-}
-
-void pick(const int dim, const range *vrange, double *v) {
- for (int d = 0; d < dim; d++) v[d] = randrange(vrange[d].min, vrange[d].max);
-}
-
-double b0(double *x) {
- return -x[0];
-}
-
-double b1(double *x) {
- return -x[1];
-}
-
-double b2(double *x) {
- return x[0] - 10;
-}
-
-double b3(double *x) {
- return x[1] - 15;
-}
-
-double f(double *x) {
- return exp(b0(x)) + exp(b1(x)) + exp(b2(x)) + exp(b3(x)) + x[0] - x[1];
-}
-
-void swarm_init(swarm *sw, const int dim, const range *vrange) {
- sw->particles = malloc(sizeof(particle) * sw->particlec);
- sw->global_best = &sw->particles[0];
- for (int p = 0; p < sw->particlec; p++) {
- particle *pt = &sw->particles[p];
- pt->current.x = vec_alloc(dim);
- pt->best.x = vec_alloc(dim);
- pt->velocity = vec_alloc(dim);
- for (int d = 0; d < dim; d++) {
- pick(dim, vrange, pt->current.x);
- vec_copy(dim, pt->current.x, pt->best.x);
- }
- pt->current.fitness = f(pt->current.x);
- pt->best.fitness = pt->current.fitness;
- if (pt->current.fitness < sw->global_best->current.fitness) sw->global_best = pt;
- }
-}
-
-void swarm_velocity_update(swarm *sw, const int dim) {
- for (int p = 0; p < sw->particlec; p++) {
- particle *pt = &sw->particles[p];
- for (int d = 0; d < dim; d++)
- pt->velocity[d] = w * pt->velocity[d] + c * rands() * (pt->best.x[d] - pt->current.x[d]) + s * rands() * (sw->global_best->current.x[d] - pt->current.x[d]);
- }
- for (int p = 0; p < sw->particlec; p++) {
- particle *pt = &sw->particles[p];
- vec_add(dim, pt->velocity, pt->current.x);
- pt->current.fitness = f(pt->current.x);
- if (pt->current.fitness < pt->best.fitness) pt->best = pt->current;
- if (pt->current.fitness < sw->global_best->current.fitness) sw->global_best = &sw->particles[p];
- }
-}
-
-static void on_activate(GtkApplication *app) {
- GtkWidget *window = gtk_application_window_new(app);
- GtkWidget *button = gtk_button_new_with_label("Hello, World!");
- g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_close), window);
- gtk_window_set_child(GTK_WINDOW(window), button);
- gtk_window_present(GTK_WINDOW(window));
-}
-
-int main(int argc, char *argv[]) {
- double eps = pow(2, 40);
- int dim = 2;
- int particlec = 100;
- range vrange[2] = {
- (range) { -100.0, 100.0 },
- (range) { -100.0, 100.0 }
- };
- swarm sw;
- sw.particlec = particlec;
- swarm_init(&sw, dim, vrange);
- int conv = 0;
- double best = 0.0;
- while (conv < 10000) {
- swarm_velocity_update(&sw, dim);
- if (fabs(sw.global_best->current.fitness - best) < eps)
- conv++;
- else {
- best = sw.global_best->current.fitness;
- conv = 0;
- }
- }
- printf("PSO: converged in x=");
- vec_print(dim, sw.global_best->current.x);
- printf(" with fitness f(x)=%f\n", sw.global_best->current.fitness);
-
- GtkApplication *app = gtk_application_new("org.wafflesoft.NCPSO", G_APPLICATION_DEFAULT_FLAGS);
- g_signal_connect(app, "activate", G_CALLBACK(on_activate), NULL);
- return g_application_run(G_APPLICATION(app), argc, argv);
-}
--- /dev/null
+#include <math.h>
+#include <stdlib.h>
+#include "swarm.h"
+#include "vector.h"
+
+double c = 2.05;
+double s = 2.05;
+double w = 0.8;
+
+double rands() {
+ return (double) rand() / RAND_MAX;
+}
+
+double randrange(double min, double max) {
+ return rands() * (max - min) + min;
+}
+
+void pick(const int dim, const range *vrange, double *v) {
+ for (int d = 0; d < dim; d++) v[d] = randrange(vrange[d].min, vrange[d].max);
+}
+
+void swarm_populate(swarm *sw, const range *rrange) {
+ sw->particles = malloc(sizeof(particle) * sw->params.particlec);
+ sw->global_best = &sw->particles[0];
+ for (int p = 0; p < sw->params.particlec; p++) {
+ particle *pt = &sw->particles[p];
+ pt->current.x = vec_alloc(sw->params.dim);
+ pt->best.x = vec_alloc(sw->params.dim);
+ pt->velocity = vec_alloc(sw->params.dim);
+ for (int d = 0; d < sw->params.dim; d++) {
+ pick(sw->params.dim, rrange, pt->current.x);
+ vec_copy(sw->params.dim, pt->current.x, pt->best.x);
+ }
+ pt->current.fitness = sw->params.f(pt->current.x);
+ pt->best.fitness = pt->current.fitness;
+ if (pt->current.fitness < sw->global_best->current.fitness) sw->global_best = pt;
+ }
+}
+
+void swarm_velocity_update(swarm *sw) {
+ for (int p = 0; p < sw->params.particlec; p++) {
+ particle *pt = &sw->particles[p];
+ for (int d = 0; d < sw->params.dim; d++)
+ pt->velocity[d] = w * pt->velocity[d] + c * rands() * (pt->best.x[d] - pt->current.x[d]) + s * rands() * (sw->global_best->current.x[d] - pt->current.x[d]);
+ }
+ for (int p = 0; p < sw->params.particlec; p++) {
+ particle *pt = &sw->particles[p];
+ vec_add(sw->params.dim, pt->velocity, pt->current.x);
+ pt->current.fitness = sw->params.f(pt->current.x);
+ if (pt->current.fitness < pt->best.fitness) pt->best = pt->current;
+ if (pt->current.fitness < sw->global_best->current.fitness) sw->global_best = &sw->particles[p];
+ }
+}
+
+void swarm_optimize(swarm *sw) {
+ int conv = 0;
+ double best = INFINITY;
+ while (conv < 10000) {
+ swarm_velocity_update(sw);
+ if (fabs(sw->global_best->current.fitness - best) < sw->params.eps)
+ conv++;
+ else {
+ best = sw->global_best->current.fitness;
+ conv = 0;
+ }
+ }
+}