Commit 8770eecd authored by Martin Beseda's avatar Martin Beseda

FIX: Fixed several problems in Particle Swarm optimization.

parent 2d89622a
This diff is collapsed.
This diff is collapsed.
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.12
# Generated by "Unix Makefiles" Generator, CMake Version 3.10
# Default target executed when no arguments are given to make.
default_target: all
......@@ -39,19 +39,19 @@ cmake_force:
SHELL = /bin/sh
# The CMake executable.
CMAKE_COMMAND = /home/fluffymoo/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/182.3684.76/bin/cmake/linux/bin/cmake
CMAKE_COMMAND = /home/martin/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/181.5540.8/bin/cmake/bin/cmake
# The command to remove a file.
RM = /home/fluffymoo/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/182.3684.76/bin/cmake/linux/bin/cmake -E remove -f
RM = /home/martin/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/181.5540.8/bin/cmake/bin/cmake -E remove -f
# Escaping for special characters.
EQUALS = =
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /home/fluffymoo/4NEURO_BIATCH/4Neuro
CMAKE_SOURCE_DIR = /home/martin/4Neuro
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /home/fluffymoo/4NEURO_BIATCH/4Neuro
CMAKE_BINARY_DIR = /home/martin/4Neuro
#=============================================================================
# Targets provided globally by CMake.
......@@ -59,7 +59,7 @@ CMAKE_BINARY_DIR = /home/fluffymoo/4NEURO_BIATCH/4Neuro
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
/home/fluffymoo/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/182.3684.76/bin/cmake/linux/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
/home/martin/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/181.5540.8/bin/cmake/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
......@@ -70,7 +70,7 @@ rebuild_cache/fast: rebuild_cache
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
/home/fluffymoo/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/182.3684.76/bin/cmake/linux/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
/home/martin/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/181.5540.8/bin/cmake/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
.PHONY : edit_cache
# Special rule for the target edit_cache
......@@ -80,9 +80,9 @@ edit_cache/fast: edit_cache
# The main all target
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start /home/fluffymoo/4NEURO_BIATCH/4Neuro/CMakeFiles /home/fluffymoo/4NEURO_BIATCH/4Neuro/CMakeFiles/progress.marks
$(CMAKE_COMMAND) -E cmake_progress_start /home/martin/4Neuro/CMakeFiles /home/martin/4Neuro/CMakeFiles/progress.marks
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start /home/fluffymoo/4NEURO_BIATCH/4Neuro/CMakeFiles 0
$(CMAKE_COMMAND) -E cmake_progress_start /home/martin/4Neuro/CMakeFiles 0
.PHONY : all
# The main clean target
......@@ -383,6 +383,19 @@ particle_test/fast:
$(MAKE) -f build/CMakeFiles/particle_test.dir/build.make build/CMakeFiles/particle_test.dir/build
.PHONY : particle_test/fast
#=============================================================================
# Target rules for targets named NeuralNetworkSum_test
# Build rule for target.
NeuralNetworkSum_test: cmake_check_build_system
$(MAKE) -f CMakeFiles/Makefile2 NeuralNetworkSum_test
.PHONY : NeuralNetworkSum_test
# fast build rule for target.
NeuralNetworkSum_test/fast:
$(MAKE) -f build/CMakeFiles/NeuralNetworkSum_test.dir/build.make build/CMakeFiles/NeuralNetworkSum_test.dir/build
.PHONY : NeuralNetworkSum_test/fast
# Help Target
help:
@echo "The following are some of the valid targets for this Makefile:"
......@@ -412,6 +425,7 @@ help:
@echo "... errorfunction_test"
@echo "... linear_neuron_test"
@echo "... particle_test"
@echo "... NeuralNetworkSum_test"
.PHONY : help
......
......@@ -69,7 +69,7 @@ case `uname -s` in
esac
#-------------------------------------------------------------------------
rm -rf build;
rm -rf build CMakeCache.txt;
cmake -G "${MAKEFILE_TYPE}" -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_TIME_PROFILING:BOOLEAN=${WITH_TIME_PROFILING} .
make VERBOSE=1 && echo "Build complete." || exit -1;
#make install;
# Install script for directory: /home/fluffymoo/4NEURO_BIATCH/4Neuro
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Install shared libraries without execute permission?
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
set(CMAKE_INSTALL_SO_NO_EXE "1")
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
if(NOT CMAKE_INSTALL_LOCAL_ONLY)
# Include the install script for each subdirectory.
include("/home/fluffymoo/4NEURO_BIATCH/4Neuro/build/cmake_install.cmake")
endif()
if(CMAKE_INSTALL_COMPONENT)
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
else()
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
endif()
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
"${CMAKE_INSTALL_MANIFEST_FILES}")
file(WRITE "/home/fluffymoo/4NEURO_BIATCH/4Neuro/${CMAKE_INSTALL_MANIFEST}"
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
......@@ -30,6 +30,16 @@ DataSet::DataSet(std::vector<std::pair<std::vector<double>, std::vector<double>>
//TODO check the complete data set for input/output dimensions
}
DataSet::DataSet(double lower_bound, double upper_bound, unsigned int size, double output) {
std::vector<std::pair<std::vector<double>, std::vector<double>>> new_data_vec;
this->data = new_data_vec;
this->n_elements = size;
this->input_dim = 1;
this->output_dim = 1;
this->add_isotropic_data(lower_bound, upper_bound, size, output);
}
void DataSet::add_data_pair(std::vector<double> inputs, std::vector<double> outputs) {
if(inputs.size() != this->input_dim) {
throw InvalidDimension("Bad input dimension.");
......@@ -41,6 +51,23 @@ void DataSet::add_data_pair(std::vector<double> inputs, std::vector<double> outp
this->data.emplace_back(std::make_pair(inputs, outputs));
}
void DataSet::add_isotropic_data(double lower_bound, double upper_bound, unsigned int size, double output) {
if(this->input_dim != 1 || this->output_dim != 1) {
throw InvalidDimension("Cannot add data with dimensionality 1:1 when the data set "
"is of different dimensionality!");
}
double frac = (upper_bound - lower_bound) / (size - 1);
std::vector<double> inp, out;
out = {output};
for(unsigned int i = 0; i < size; ++i){
inp = {frac*i};
this->data.emplace_back(std::make_pair(inp, out));
}
}
std::vector<std::pair<std::vector<double>, std::vector<double>>>* DataSet::get_data() {
return &(this->data);
}
......
......@@ -149,6 +149,22 @@ public:
*/
DataSet(std::vector<std::pair<std::vector<double>, std::vector<double>>>* data_ptr);
/**
* Creates a new data set with input values equidistantly positioned
* over the certain interval and the output value
* being constant
*
* Both input and output are 1-dimensional
*
* @todo add bounds as vectors for multi-dimensional data-sets
*
* @param lower_bound Lower bound of the input data interval
* @param upper_bound Upper bound of the input data interval
* @param size Number of input-output pairs generated
* @param output Constant output value
*/
DataSet(double lower_bound, double upper_bound, unsigned int size, double output);
/**
* Getter for number of elements
* @return Number of elements in the data set
......@@ -181,6 +197,23 @@ public:
*/
void add_data_pair(std::vector<double> inputs, std::vector<double> outputs);
//TODO expand method to generate multiple data types - chebyshev etc.
/**
* Adds a new data with input values equidistantly positioned
* over the certain interval and the output value
* being constant
*
* Both input and output are 1-dimensional
*
* @param lower_bound Lower bound of the input data interval
* @param upper_bound Upper bound of the input data interval
* @param size Number of input-output pairs generated
* @param output Constant output value
*/
void add_isotropic_data(double lower_bound, double upper_bound, unsigned int size, double output);
//TODO Chebyshev - ch. interpolation points, i-th point = cos(i*alpha) from 0 to pi
/**
* Prints the data set
*/
......
......@@ -5,9 +5,6 @@
* @date 2.7.18 -
*/
#include <cmath>
#include <set>
#include <stdexcept>
#include "ParticleSwarm.h"
#include "../ErrorFunction/ErrorFunctions.h"
......@@ -35,6 +32,7 @@ Particle::Particle(ErrorFunction* ef, double *domain_bounds) {
// this->r2 = (rand() % 100001) / (double) 100000;
this->r1 = 1.0;
this->r2 = 1.0;
this->r3 = 1.0;
this->optimal_coordinate = new double[this->coordinate_dim];
......@@ -72,20 +70,24 @@ double* Particle::get_coordinate() {
return this->coordinate;
}
double Particle::get_current_value() {
return this->current_val;
}
double Particle::get_optimal_value() {
return this->optimal_value;
}
void Particle::get_optimal_coordinate(double *ref_coordinate) {
void Particle::get_optimal_coordinate(std::vector<double> &ref_coordinate) {
for( unsigned int i = 0; i < this->coordinate_dim; ++i ){
ref_coordinate[i] = this->optimal_coordinate[i];
}
}
double Particle::change_coordinate(double w, double c1, double c2, double *glob_min_coord, double penalty_coef) {
double Particle::change_coordinate(double w, double c1, double c2, std::vector<double> glob_min_coord, std::vector<std::vector<double>> global_min_vec, double penalty_coef) {
/**
* v = w * v + c1r1(p_min_loc - x) + c2r2(p_min_glob - x)
* v = w * v + c1r1(p_min_loc - x) + c2r2(p_min_glob - x) + c3r3(random_global_min - x)
* x = x + v
*/
......@@ -93,8 +95,22 @@ double Particle::change_coordinate(double w, double c1, double c2, double *glob_
double output;
bool in_domain;
double compensation_coef = 1;
/* Choose random global minima */
std::vector<double> random_global_best(this->coordinate_dim);
std::random_device rand_dev;
std::mt19937 engine{rand_dev()};
std::uniform_int_distribution<int> dist(0, global_min_vec.size() - 1);
random_global_best = global_min_vec[dist(engine)];
// TODO use std::sample to choose random vector
//std::sample(global_min_vec.begin(), global_min_vec.end(), std::back_inserter(random_global_best), 1, std::mt19937{std::random_device{}()});
for(unsigned int i = 0; i < this->coordinate_dim; ++i){
vel_mem = w * this->velocity[i] + c1 * this->r1 * (this->optimal_coordinate[i] - this->coordinate[i]) + c2 * this->r2 * (glob_min_coord[i] - this->coordinate[i]);
vel_mem = w * this->velocity[i]
+ c1 * this->r1 * (this->optimal_coordinate[i] - this->coordinate[i])
+ c2 * this->r2 * (glob_min_coord[i] - this->coordinate[i])
+ (c1+c2)/2 * this->r3 * (random_global_best[i] - this->coordinate[i]);
do{
if (this->coordinate[i] + vel_mem > this->domain_bounds[2 * i + 1]) {
......@@ -118,6 +134,7 @@ double Particle::change_coordinate(double w, double c1, double c2, double *glob_
}
vel_mem = this->ef->eval(this->coordinate);
this->current_val = vel_mem;
if(vel_mem < this->optimal_value){
this->optimal_value = vel_mem;
......@@ -149,6 +166,8 @@ ParticleSwarm::ParticleSwarm(ErrorFunction* ef, double *domain_bounds,
this->c2 = c2;
this->c3 = (c1 + c2)/2.0;
this->w = w;
this->n_particles = n_particles;
......@@ -191,7 +210,8 @@ void ParticleSwarm::optimize( double gamma, double epsilon, double delta) {
unsigned int outer_it = 0;
Particle *particle;
double *p_min_glob = new double[this->func_dim];
std::vector<double> p_min_glob(this->func_dim);
std::vector<std::vector<double>> global_best_vec;
double optimal_value = 0.0;
std::set<Particle*> cluster; //!< Particles in a cluster
......@@ -213,9 +233,16 @@ void ParticleSwarm::optimize( double gamma, double epsilon, double delta) {
// Clustering algorithm - termination condition //
//////////////////////////////////////////////////
particle = this->determine_optimal_coordinate_and_value(p_min_glob, optimal_value);
if(std::find(global_best_vec.begin(), global_best_vec.end(), p_min_glob) == global_best_vec.end()) {
global_best_vec.emplace_back(p_min_glob); // TODO rewrite as std::set
}
cluster.insert(particle);
for(unsigned int i=0; i < 5; i++) {
//for(unsigned int i=0; i < 5; i++) {
/* Zero AVG coordinates */
std::fill(coords, coords+this->func_dim, 0);
/* Looking for a centroid */
for (auto it : cluster) {
......@@ -231,7 +258,7 @@ void ParticleSwarm::optimize( double gamma, double epsilon, double delta) {
for(unsigned int pi=0; pi < this->n_particles; pi++) {
particle = this->particle_swarm[pi];
tmp_velocity = particle->change_coordinate( this->w, this->c1, this->c2, p_min_glob);
tmp_velocity = particle->change_coordinate( this->w, this->c1, this->c2, p_min_glob, global_best_vec);
if(tmp_velocity > max_velocity) {
prev_max_velocity = max_velocity;
......@@ -249,20 +276,28 @@ void ParticleSwarm::optimize( double gamma, double epsilon, double delta) {
cluster.insert(particle);
}
}
}
//}
prev_max_vel_step = max_vel_step;
max_vel_step = max_velocity - prev_max_velocity;
//TODO only in verbose mode
euclidean_dist /= this->n_particles;
//printf("Iteration %d, avg euclidean distance: %f, cluster percent: %f, f-value: %f\n", outer_it, euclidean_dist,
// double(cluster.size())/this->n_particles, optimal_value);
// for(unsigned int i=0; i < this->n_particles; i++) {
// printf("Particle %d (%f): \n", i, this->particle_swarm[i]->get_current_value());
// for(unsigned int j=0; j < this->func_dim; j++) {
// printf("\t%f\n", this->particle_swarm[i]->get_coordinate()[j]);
// }
// }
/* Check if the particles are near to each other AND the maximal velocity is less than 'gamma' */
if(double(cluster.size())/this->n_particles > delta && std::abs(prev_max_vel_step/max_vel_step) > gamma) {
break;
}
//TODO only in verbose mode
euclidean_dist /= this->n_particles*5.;
printf("Iteration %d, avg euclidean distance: %f\n", outer_it, euclidean_dist);
outer_it++;
// this->w *= 0.99;
}
......@@ -283,11 +318,11 @@ void ParticleSwarm::optimize( double gamma, double epsilon, double delta) {
}
}
delete [] p_min_glob;
//delete [] p_min_glob; // TODO
delete [] coords;
}
Particle* ParticleSwarm::determine_optimal_coordinate_and_value(double *coord, double &val) {
Particle* ParticleSwarm::determine_optimal_coordinate_and_value(std::vector<double> &coord, double &val) {
Particle* p;
......
......@@ -8,8 +8,14 @@
#ifndef INC_4NEURO_PARTICLESWARM_H
#define INC_4NEURO_PARTICLESWARM_H
#include "stdlib.h"
#include "time.h"
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <set>
#include <stdexcept>
#include <random>
#include <iterator>
#include <algorithm>
#include "../Network/NeuralNetwork.h"
#include "../DataSet/DataSet.h"
......@@ -28,6 +34,9 @@ private:
double r1;
double r2;
double r3;
double current_val;
ErrorFunction* ef;
......@@ -50,6 +59,12 @@ public:
*/
double* get_coordinate();
/**
*
* @return
*/
double get_current_value();
/**
*
* @return
......@@ -60,7 +75,7 @@ public:
*
* @param ref_coordinate
*/
void get_optimal_coordinate(double *ref_coordinate);
void get_optimal_coordinate(std::vector<double> &ref_coordinate);
/**
*
......@@ -70,7 +85,7 @@ public:
* @param glob_min_coord
* @param penalty_coef
*/
double change_coordinate(double w, double c1, double c2, double* glob_min_coord, double penalty_coef=0.25);
double change_coordinate(double w, double c1, double c2, std::vector<double> glob_min_coord, std::vector<std::vector<double>> global_min_vec, double penalty_coef=0.25);
};
......@@ -98,6 +113,8 @@ private:
double c2;
double c3;
double w;
double global_optimal_value;
......@@ -111,7 +128,7 @@ protected:
* @param val
* @return
*/
Particle* determine_optimal_coordinate_and_value(double *coord, double &val);
Particle* determine_optimal_coordinate_and_value(std::vector<double> &coord, double &val);
/**
*
......
......@@ -18,7 +18,7 @@
int main() {
unsigned int n_inputs = 1;
unsigned int n_inner_neurons = 4;
unsigned int n_inner_neurons = 20;
unsigned int n_outputs = 1;
unsigned int n_equations = 3;
......@@ -98,7 +98,7 @@ int main() {
/* PARTICLE SWARM TRAINING METHOD SETUP */
unsigned int max_iters = 100;
unsigned int max_iters = 1500;
//must encapsulate each of the partial error functions
double *domain_bounds = new double[ 2 * n_inner_neurons * (n_inputs + n_outputs) ];
......@@ -107,11 +107,11 @@ int main() {
domain_bounds[2 * i + 1] = 800.0;
}
double c1 = 0.5, c2 = 1.5, w = 0.8;
double c1 = 0.5, c2 = 0.7, w = 0.3;
unsigned int n_particles = 100;
unsigned int n_particles = 250;
double gamma = 0.5, epsilon = 0.02, delta = 0.9;
double gamma = 0.8, epsilon = 1e-6, delta = 0.9;
solver_01.solve_via_particle_swarm( domain_bounds, c1, c2, w, n_particles, max_iters, gamma, epsilon, delta );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment