Skip to content

Instantly share code, notes, and snippets.

@masklinn
Created April 30, 2023 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masklinn/9ace0957a49a73a2c2959594ab7ef5e2 to your computer and use it in GitHub Desktop.
Save masklinn/9ace0957a49a73a2c2959594ab7ef5e2 to your computer and use it in GitHub Desktop.
use std::fmt::Display;
use rand::prelude::*;
const DIM: usize = 100;
type V = [f64; DIM];
struct ObjectiveFunctionStruct {
name: String,
function: fn(&V) -> f64,
lower_bound: V,
upper_bound: V,
}
struct Particle {
position: V,
velocity: V,
personal_best_position: V,
personal_best_fitness: f64,
}
impl Display for Particle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(Position: {:?}, Velocity: {:?}, Personal Best Position: {:?}, Personal Best Fitness: {})", self.position, self.velocity, self.personal_best_position, self.personal_best_fitness)
}
}
struct Swarm {
w: f64,
c1: f64,
c2: f64,
particles: Vec<Particle>,
global_best_position: V,
global_best_fitness: f64,
objective_function_struct: ObjectiveFunctionStruct,
rng_thread: SmallRng,
}
impl Swarm {
fn new(
w: f64,
c1: f64,
c2: f64,
swarm_size: usize,
objective_function_struct: ObjectiveFunctionStruct,
) -> Swarm {
let mut particles = Vec::new();
let mut rng_thread = SmallRng::from_entropy();
let mut global_best_position = [0.0; DIM];
let mut global_best_fitness = std::f64::MAX;
for _ in 0..swarm_size {
let mut particle: Particle = Particle {
position: std::array::from_fn(|i| {
rng_thread.gen_range(
objective_function_struct.lower_bound[i]
..objective_function_struct.upper_bound[i],
)
}),
velocity: [0.0; DIM],
personal_best_position: [0.0; DIM],
personal_best_fitness: std::f64::MAX,
};
particle.personal_best_position = particle.position;
particle.personal_best_fitness =
(objective_function_struct.function)(&particle.position);
if particle.personal_best_fitness < global_best_fitness {
global_best_fitness = particle.personal_best_fitness;
global_best_position = particle.personal_best_position;
}
particles.push(particle);
}
Swarm {
w,
c1,
c2,
particles,
global_best_position,
global_best_fitness,
objective_function_struct,
rng_thread,
}
}
fn update_particles(&mut self) {
for particle in &mut self.particles {
for i in 0..DIM {
particle.velocity[i] = self.w * particle.velocity[i]
+ self.c1
* self.rng_thread.gen_range(0.0..1.0)
* (particle.personal_best_position[i] - particle.position[i])
+ self.c2
* self.rng_thread.gen_range(0.0..1.0)
* (self.global_best_position[i] - particle.position[i]);
particle.position[i] += particle.velocity[i];
}
let fitness: f64 = (self.objective_function_struct.function)(&particle.position);
if fitness < self.global_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position;
self.global_best_fitness = fitness;
self.global_best_position = particle.position;
} else if fitness < particle.personal_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position;
}
}
}
fn run(&mut self, iterations: usize) {
for _ in 0..iterations {
self.update_particles();
}
}
fn print(&self) {
println!("Global Best Position: {:?}", self.global_best_position);
println!("Global Best Fitness: {}", self.global_best_fitness);
}
}
fn sphere_function(x: &V) -> f64 {
x.iter().map(|a: &f64| a.powi(2)).sum()
}
fn main() {
use std::time::Instant;
let now = Instant::now();
let objective_function_struct: ObjectiveFunctionStruct = ObjectiveFunctionStruct {
name: "Sphere Function".to_string(),
function: sphere_function,
lower_bound: [-5.12; DIM],
upper_bound: [5.12; DIM],
};
let mut swarm: Swarm = Swarm::new(0.729, 1.49445, 1.49445, 1000, objective_function_struct);
swarm.run(10000);
swarm.print();
let elapsed = now.elapsed();
println!("Elapsed: {} ms", elapsed.as_millis());
}
use std::fmt::Display;
use rand::Rng;
struct ObjectiveFunctionStruct {
name: String,
function: fn(&Vec<f64>) -> f64,
lower_bound: Vec<f64>,
upper_bound: Vec<f64>,
}
struct Particle {
position: Vec<f64>,
velocity: Vec<f64>,
personal_best_position: Vec<f64>,
personal_best_fitness: f64,
}
impl Display for Particle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(Position: {:?}, Velocity: {:?}, Personal Best Position: {:?}, Personal Best Fitness: {})", self.position, self.velocity, self.personal_best_position, self.personal_best_fitness)
}
}
struct Swarm {
w: f64,
c1: f64,
c2: f64,
particles: Vec<Particle>,
global_best_position: Vec<f64>,
global_best_fitness: f64,
objective_function_struct: ObjectiveFunctionStruct,
rng_thread: rand::rngs::ThreadRng,
}
impl Swarm {
fn new(
w: f64,
c1: f64,
c2: f64,
swarm_size: usize,
objective_function_struct: ObjectiveFunctionStruct,
) -> Swarm {
let dimension: usize = objective_function_struct.lower_bound.len();
let mut particles: Vec<Particle> = Vec::new();
let mut rng_thread: rand::rngs::ThreadRng = rand::thread_rng();
let mut global_best_position: Vec<f64> = vec![0.0; dimension];
let mut global_best_fitness: f64 = std::f64::MAX;
for _ in 0..swarm_size {
let mut particle: Particle = Particle {
position: (0..dimension)
.map(|i| {
rng_thread.gen_range(
objective_function_struct.lower_bound[i]
..objective_function_struct.upper_bound[i],
)
})
.collect(),
velocity: vec![0.0; dimension],
personal_best_position: vec![0.0; dimension],
personal_best_fitness: std::f64::MAX,
};
particle.personal_best_position = particle.position.clone();
particle.personal_best_fitness =
(objective_function_struct.function)(&particle.position);
if particle.personal_best_fitness < global_best_fitness {
global_best_fitness = particle.personal_best_fitness;
global_best_position = particle.personal_best_position.clone();
}
particles.push(particle);
}
Swarm {
w,
c1,
c2,
particles,
global_best_position,
global_best_fitness,
objective_function_struct,
rng_thread,
}
}
fn update_particles(&mut self) {
for particle in &mut self.particles {
let dimension: usize = particle.position.len();
for i in 0..dimension {
particle.velocity[i] = self.w * particle.velocity[i]
+ self.c1
* self.rng_thread.gen_range(0.0..1.0)
* (particle.personal_best_position[i] - particle.position[i])
+ self.c2
* self.rng_thread.gen_range(0.0..1.0)
* (self.global_best_position[i] - particle.position[i]);
particle.position[i] += particle.velocity[i];
}
let fitness: f64 = (self.objective_function_struct.function)(&particle.position);
if fitness < self.global_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position.clone();
self.global_best_fitness = fitness;
self.global_best_position = particle.position.clone();
} else if fitness < particle.personal_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position.clone();
}
}
}
fn run(&mut self, iterations: usize) {
for _ in 0..iterations {
self.update_particles();
}
}
fn print(&self) {
println!("Global Best Position: {:?}", self.global_best_position);
println!("Global Best Fitness: {}", self.global_best_fitness);
}
}
fn sphere_function(x: &Vec<f64>) -> f64 {
x.iter().map(|a: &f64| a.powi(2)).sum()
}
fn main() {
use std::time::Instant;
let now = Instant::now();
let dim = 100;
let objective_function_struct: ObjectiveFunctionStruct = ObjectiveFunctionStruct {
name: "Sphere Function".to_string(),
function: sphere_function,
lower_bound: vec![-5.12; dim],
upper_bound: vec![5.12; dim],
};
let mut swarm: Swarm = Swarm::new(0.729, 1.49445, 1.49445, 1000, objective_function_struct);
swarm.run(10000);
swarm.print();
let elapsed = now.elapsed();
println!("Elapsed: {} ms", elapsed.as_millis());
}
use std::fmt::Display;
use rand::prelude::*;
struct ObjectiveFunctionStruct {
name: String,
function: fn(&Vec<f64>) -> f64,
lower_bound: Vec<f64>,
upper_bound: Vec<f64>,
}
struct Particle {
position: Vec<f64>,
velocity: Vec<f64>,
personal_best_position: Vec<f64>,
personal_best_fitness: f64,
}
impl Display for Particle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(Position: {:?}, Velocity: {:?}, Personal Best Position: {:?}, Personal Best Fitness: {})", self.position, self.velocity, self.personal_best_position, self.personal_best_fitness)
}
}
struct Swarm {
w: f64,
c1: f64,
c2: f64,
particles: Vec<Particle>,
global_best_position: Vec<f64>,
global_best_fitness: f64,
objective_function_struct: ObjectiveFunctionStruct,
rng_thread: SmallRng,
}
impl Swarm {
fn new(
w: f64,
c1: f64,
c2: f64,
swarm_size: usize,
objective_function_struct: ObjectiveFunctionStruct,
) -> Swarm {
let dimension: usize = objective_function_struct.lower_bound.len();
let mut particles: Vec<Particle> = Vec::new();
let mut rng_thread = rand::rngs::SmallRng::from_entropy();
let mut global_best_position: Vec<f64> = vec![0.0; dimension];
let mut global_best_fitness: f64 = std::f64::MAX;
for _ in 0..swarm_size {
let mut particle: Particle = Particle {
position: (0..dimension)
.map(|i| {
rng_thread.gen_range(
objective_function_struct.lower_bound[i]
..objective_function_struct.upper_bound[i],
)
})
.collect(),
velocity: vec![0.0; dimension],
personal_best_position: vec![0.0; dimension],
personal_best_fitness: std::f64::MAX,
};
particle.personal_best_position = particle.position.clone();
particle.personal_best_fitness =
(objective_function_struct.function)(&particle.position);
if particle.personal_best_fitness < global_best_fitness {
global_best_fitness = particle.personal_best_fitness;
global_best_position = particle.personal_best_position.clone();
}
particles.push(particle);
}
Swarm {
w,
c1,
c2,
particles,
global_best_position,
global_best_fitness,
objective_function_struct,
rng_thread,
}
}
fn update_particles(&mut self) {
for particle in &mut self.particles {
let dimension: usize = particle.position.len();
for i in 0..dimension {
particle.velocity[i] = self.w * particle.velocity[i]
+ self.c1
* self.rng_thread.gen_range(0.0..1.0)
* (particle.personal_best_position[i] - particle.position[i])
+ self.c2
* self.rng_thread.gen_range(0.0..1.0)
* (self.global_best_position[i] - particle.position[i]);
particle.position[i] += particle.velocity[i];
}
let fitness: f64 = (self.objective_function_struct.function)(&particle.position);
if fitness < self.global_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position.clone();
self.global_best_fitness = fitness;
self.global_best_position = particle.position.clone();
} else if fitness < particle.personal_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position.clone();
}
}
}
fn run(&mut self, iterations: usize) {
for _ in 0..iterations {
self.update_particles();
}
}
fn print(&self) {
println!("Global Best Position: {:?}", self.global_best_position);
println!("Global Best Fitness: {}", self.global_best_fitness);
}
}
fn sphere_function(x: &Vec<f64>) -> f64 {
x.iter().map(|a: &f64| a.powi(2)).sum()
}
fn main() {
use std::time::Instant;
let now = Instant::now();
let dim = 100;
let objective_function_struct: ObjectiveFunctionStruct = ObjectiveFunctionStruct {
name: "Sphere Function".to_string(),
function: sphere_function,
lower_bound: vec![-5.12; dim],
upper_bound: vec![5.12; dim],
};
let mut swarm: Swarm = Swarm::new(0.729, 1.49445, 1.49445, 1000, objective_function_struct);
swarm.run(10000);
swarm.print();
let elapsed = now.elapsed();
println!("Elapsed: {} ms", elapsed.as_millis());
}
use std::fmt::Display;
use rand::Rng;
const DIM: usize = 100;
type V = [f64; DIM];
struct ObjectiveFunctionStruct {
name: String,
function: fn(&V) -> f64,
lower_bound: V,
upper_bound: V,
}
struct Particle {
position: V,
velocity: V,
personal_best_position: V,
personal_best_fitness: f64,
}
impl Display for Particle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(Position: {:?}, Velocity: {:?}, Personal Best Position: {:?}, Personal Best Fitness: {})", self.position, self.velocity, self.personal_best_position, self.personal_best_fitness)
}
}
struct Swarm {
w: f64,
c1: f64,
c2: f64,
particles: Vec<Particle>,
global_best_position: V,
global_best_fitness: f64,
objective_function_struct: ObjectiveFunctionStruct,
rng_thread: rand::rngs::ThreadRng,
}
impl Swarm {
fn new(
w: f64,
c1: f64,
c2: f64,
swarm_size: usize,
objective_function_struct: ObjectiveFunctionStruct,
) -> Swarm {
let mut particles = Vec::new();
let mut rng_thread = rand::thread_rng();
let mut global_best_position = [0.0; DIM];
let mut global_best_fitness = std::f64::MAX;
for _ in 0..swarm_size {
let mut particle: Particle = Particle {
position: std::array::from_fn(|i| {
rng_thread.gen_range(
objective_function_struct.lower_bound[i]
..objective_function_struct.upper_bound[i],
)
}),
velocity: [0.0; DIM],
personal_best_position: [0.0; DIM],
personal_best_fitness: std::f64::MAX,
};
particle.personal_best_position = particle.position;
particle.personal_best_fitness =
(objective_function_struct.function)(&particle.position);
if particle.personal_best_fitness < global_best_fitness {
global_best_fitness = particle.personal_best_fitness;
global_best_position = particle.personal_best_position;
}
particles.push(particle);
}
Swarm {
w,
c1,
c2,
particles,
global_best_position,
global_best_fitness,
objective_function_struct,
rng_thread,
}
}
fn update_particles(&mut self) {
for particle in &mut self.particles {
for i in 0..DIM {
particle.velocity[i] = self.w * particle.velocity[i]
+ self.c1
* self.rng_thread.gen_range(0.0..1.0)
* (particle.personal_best_position[i] - particle.position[i])
+ self.c2
* self.rng_thread.gen_range(0.0..1.0)
* (self.global_best_position[i] - particle.position[i]);
particle.position[i] += particle.velocity[i];
}
let fitness: f64 = (self.objective_function_struct.function)(&particle.position);
if fitness < self.global_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position;
self.global_best_fitness = fitness;
self.global_best_position = particle.position;
} else if fitness < particle.personal_best_fitness {
particle.personal_best_fitness = fitness;
particle.personal_best_position = particle.position;
}
}
}
fn run(&mut self, iterations: usize) {
for _ in 0..iterations {
self.update_particles();
}
}
fn print(&self) {
println!("Global Best Position: {:?}", self.global_best_position);
println!("Global Best Fitness: {}", self.global_best_fitness);
}
}
fn sphere_function(x: &V) -> f64 {
x.iter().map(|a: &f64| a.powi(2)).sum()
}
fn main() {
use std::time::Instant;
let now = Instant::now();
let objective_function_struct: ObjectiveFunctionStruct = ObjectiveFunctionStruct {
name: "Sphere Function".to_string(),
function: sphere_function,
lower_bound: [-5.12; DIM],
upper_bound: [5.12; DIM],
};
let mut swarm: Swarm = Swarm::new(0.729, 1.49445, 1.49445, 1000, objective_function_struct);
swarm.run(10000);
swarm.print();
let elapsed = now.elapsed();
println!("Elapsed: {} ms", elapsed.as_millis());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment