class Particle { int max_dimension; Tuple position; Tuple velocity; Tuple best_local_position; Tuple best_global_position; Swarm s; boolean has_max_velocity_magnitude; float max_velocity_magnitude; boolean use_time; float last_update_millis; float w; // inertial constant (favors the current values) usually set slightly under 1 float c1, c2; //learning constants (favors the best local and best global values respectively) float d; //defiance (between 0 and 1) this affects how much the particle tends to defy the ideal location of the swarm float random_search_radius; float r; //the display radius color f; //the display fill color Particle(int max_dimension) { this.max_dimension = max_dimension; this.s = null; this.position = new Tuple(max_dimension); this.velocity = new Tuple(max_dimension); this.best_local_position = new Tuple(max_dimension); this.best_global_position = new Tuple(max_dimension); this.has_max_velocity_magnitude = false; this.max_velocity_magnitude = 0; this.use_time = false; this.last_update_millis = millis(); this.w = .9; this.c1 = 1; this.c2 = 1; this.d = 0; this.random_search_radius = 0; this.r = 15; this.f = color(255,0,0); } public void setSwarm(Swarm s) { this.s = s; } public void update() { //compute time elapsed float current_millis = millis(); float time_elapsed = (current_millis - last_update_millis) / 1000; last_update_millis = current_millis; move(time_elapsed); } public void setInertiaFactor(float w) { this.w = w; } public float getInertiaFactor() { return w; } public void setSelfishFactor(float c1) { this.c1 = c1; } public float getSelfishFactor() { return c1; } public void setSocialFactor(float c2) { this.c2 = c2; } public float getSocialFactor() { return c2; } public void setDefianceFactor(float d) { this.d = d; } public float getDefianceFactor() { return this.d; } public void setRandomSearchRadius(float random_search_radius) { this.random_search_radius = random_search_radius; } public float getRandomSearchRadius() { return this.random_search_radius; } public void move(float time_elapsed) { //check out: http://en.wikipedia.org/wiki/Particle_swarm_optimization float r1, r2; //the random values between 0 and 1 which control the fraction of the distance to traverse between the best values and the current values //update position float new_position_value; float upper_bound, lower_bound; for(int i = 0; i < max_dimension; i++) { if (use_time) { new_position_value = position.getValue(i) + velocity.getValue(i) * time_elapsed; } else { new_position_value = position.getValue(i) + velocity.getValue(i); } upper_bound = s.e.getUpperBound(i); lower_bound = s.e.getLowerBound(i); if (new_position_value > upper_bound) { new_position_value = lower_bound; } if (new_position_value < lower_bound) { new_position_value = upper_bound; } position.setValue(new_position_value, i); } //update velocity float new_velocity_value; float current_position_value; for(int i = 0; i < max_dimension; i++) { r1 = random(-d,1); r2 = random(-d,1); current_position_value = position.getValue(i); //determine new velocity new_velocity_value = w * velocity.getValue(i) + (c1 * r1 * (best_local_position.getValue(i) - current_position_value)) + (c2 * r2 * (best_global_position.getValue(i) - current_position_value)) + random(-random_search_radius/2, random_search_radius/2); if (has_max_velocity_magnitude) { if (new_velocity_value > 0 && new_velocity_value > max_velocity_magnitude) { new_velocity_value = max_velocity_magnitude; } if (new_velocity_value < 0 && new_velocity_value < (-1 * max_velocity_magnitude)) { new_velocity_value = -1 * max_velocity_magnitude; } } velocity.setValue(new_velocity_value, i); } if (s != null) { //update best local position if (s.isBetterPosition(position, best_local_position)) { best_local_position = new Tuple(position); } //update best global position best_global_position = s.updateBestPosition(position); } } public void setHasMaxVelocityMagnitude(boolean has_max_velocity_magnitude) { this.has_max_velocity_magnitude = has_max_velocity_magnitude; } public boolean getHasMaxVelocityMagnitude() { return has_max_velocity_magnitude; } public void setMaxVelocityMagnitude(float max_velocity_magnitude) { this.max_velocity_magnitude = max_velocity_magnitude; } public float getMaxVelocityMagnitude() { return max_velocity_magnitude; } public int getMaxDimension() { return this.max_dimension; } public void setPosition(Tuple position) { this.position = position; } public Tuple getPosition() { return position; } public void setUseTime(boolean use_time) { this.use_time = use_time; } public boolean getUseTime() { return use_time; } public void setFillColor(color f) { this.f = f; } public color getFillColor() { return f; } public void setRadius(float r) { this.r = r; } public float getRadius() { return r; } public void display() { float x, y, z; x = position.getValue(0); y = position.getValue(1); z = position.getValue(2); fill(f); pushMatrix(); translate(x, y, z); //sphere(r); box(r); popMatrix(); } }