7个版本
0.1.6 | 2020年6月19日 |
---|---|
0.1.5 | 2020年6月17日 |
0.1.4 | 2020年5月12日 |
0.1.0 | 2020年4月13日 |
5 in #优化器
每月 21 次下载
48KB
1K SLoC
POS_PSO
纯Rust实现的具有高度可配置性的粒子群优化器
可以轻松地在多个线程上最小化成本函数
- 可以使用独立群体并行运行多个优化
- 或者群体可以定期共享搜索空间中的最佳已知位置,使用协作群体
运动动力学松散基于Matlab的粒子群算法
优化器采用以下头部的闭包作为成本函数
move |x: &[f64]| -> f64 {}
- 输入的切片数组表示N维优化空间中的一个点
- 返回的成本用于在搜索空间中导航以定位最小值
- 目前仅支持f64,但未来的更新可能允许更通用的成本函数
一些入门示例
单线程示例(单个群体)
- 使用默认的独立群体配置(这是一个好起点,但您可能希望根据您的用例定义自己的配置)
- 搜索空间边界和最大速度仍然必须在JobConfig对象中定义
- 单群体可能是高端英特尔处理器的最快性能选项
extern crate pos_pso;
use pos_pso::{PSO, PSOConfig, JobConfig};
fn main() {
let num_variables = 5;
// Define a cost function to minimize:
//data captured by closure
let mins = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let coeffs = vec![0.25; num_variables];
//cost function closure must take a &[f64] and return f64
let cost_function = move |point: &[f64]| -> f64 {
let mut sum = 0.0;
for i in 0..num_variables {
sum += (point[i] - mins[i]).powi(2) * coeffs[i];
}
sum
};
// Create a PSO Configuration:
let pso_config = PSOConfig::new(
1, // 1 swarm used in optimization
256, // 256 particles are spawned
10, // console is updated every 10 itterations
true // optimizer is verbose (will provide more detailed information to console)
);
// Create a PSO:
let pso = PSO::new(pso_config);
// Create a Job Configuration:
let job_config = JobConfig::new(
num_variables,
vec![[-15.0, 15.0]; num_variables], // [upper, lower] bounds for each variable
vec![1.125; num_variables], // max velocity for each variable
100, // run for 100 itterations
0.0000001, // exit cost (optimization will stop when a cost of 0.0000001 is reached)
);
// Minimize cost function:
//use minimize_independant to optimize with the default independant-swarm configuration
//the next example will show how to use collaborative-swarms
let min = pso.minimize_independant(job_config, cost_function);
println!("Minimum of: {}, With value: {:?}", min.0, min.1);
}
多线程示例*使用4个协作群体,每个群体中粒子更少
- 使用运动系数和记录共享周期定义自定义群体配置
- 这可能是高端AMD处理器的最快性能选项
let num_variables = 5;
// Define a cost function to minimize:
//data captured by closure
let mins = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let coeffs = vec![0.25; num_variables];
//cost function closure must take a &[f64] and return f64
let cost_function = move |point: &[f64]| -> f64 {
let mut sum = 0.0;
for i in 0..num_variables {
sum += (point[i] - mins[i]).powi(2) * coeffs[i];
}
sum
};
// Create a PSO Configuration:
let pso_config = PSOConfig::new(
4, // 4 swarms (each spawned on their own thread)
64, // 64 particles per swarm
10, // console is updated every 10 itterations
true // optimizer is verbose (will provide more detailed information to console)
);
// Create a PSO:
let pso = PSO::new(pso_config);
// Create a Job Configuration:
let job_config = JobConfig::new(
num_variables,
vec![[-15.0, 15.0]; num_variables], // [upper, lower] bounds for each variable
vec![1.125; num_variables], // max velocity for each variable
100, // run for 100 itterations
0.0000001, // exit cost (swarms will stop when a cost of 0.0000001 is reached)
);
// Create a custom Swarm Configuration:
//collaborative swarms will share information with eachother about best known locations in the search space
let swarm_config = SwarmConfig::new_collaborative(
1.45, // local weigth: how much particles care about their best known location
1.6, // tribal weight: how much particles care about their swarms best known location
1.25, // global weight: how much particles care about the overall best known location
0.4, // inertial coefficient: component of a particles velocity that contributes to its next velocity
1.25, // inertial growth factor: how much inertia grows and shrinks throughout optimization
0.125, // wall bounce factor: component of velocity that is saved when particle goes out of bounds
10, // tribal-global collab period: swarms share best known location every 10 itterations
);
// Minimize cost function:
//use minimize to optimize with a custom SwarmConfig
let min = pso.minimize(job_config, swarm_config, cost_function);
println!("Minimum of: {}, With value: {:?}", min.0, min.1);
高级示例
- 使用8个独立群体以不同的群体参数最小化相同的成本函数
- 此示例展示了如何使用SwarmConfigDistribution,其中群体行为系数是从用户定义的分布中采样的
- 所有8个群体在单独的线程上并行运行(在所有线程完成后返回最低成本和最佳位置)
extern crate pos_pso;
use pos_pso::{PSO, PSOConfig, JobConfig, SwarmConfigDistribution, ParamDist};
fn main() {
let num_variables = 5;
// Define a cost function to minimize:
//data captured by closure
let mins = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let coeffs = vec![0.25; num_variables];
//cost function closure must take a &[f64] and return f64
let cost_function = move |point: &[f64]| -> f64 {
let mut sum = 0.0;
for i in 0..num_variables {
sum += (point[i] - mins[i]).powi(2) * coeffs[i];
}
sum
};
// Create a PSO Configuration:
let pso_config = PSOConfig::new(
8, // 8 swarms (each spawned on their own thread)
128, // 128 particles per swarm
10, // console is updated by each thread every 10 itterations
true // optimizer is verbose (will provide more detailed information to console)
);
// Create a PSO:
let pso = PSO::new(pso_config);
// Create a Job Configuration:
let job_config = JobConfig::new(
num_variables,
vec![[-15.0, 15.0]; num_variables], // [upper, lower] bounds for each variable
vec![1.125; num_variables], // max velocity for each variable
100, // run for 100 itterations
0.0000001, // exit cost (swarms will stop when a cost of 0.0000001 is reached)
);
// Create a Swarm Configuration Distribution:
//the optimizer will sample a new swarm configuration for each swarm
//this is usefull for automatically creating a range of swarm behaviors
//in this case we are using new_independant, so all 8 optimizations will run seperately in parallel
let swarm_config = SwarmConfigDistribution::new_independant(
ParamDist::Fixed(1.45), // local: fixed value of 1.45
ParamDist::Range([1.65, 0.25]), // tribal: random value: 1.65 +/- 25%
ParamDist::Fixed(0.4), // momentum: fixed value of 0.4
ParamDist::Range([1.25, 0.05]), // momentum growth factor: random value: 1.25 +/- 5%
ParamDist::Fixed(0.0125), // wall bounce factor: fixed value of 0.0125
);
// Minimize cost function:
//use minimize_distributed to accept SwarmConfigDistribution
let min = pso.minimize_distributed(job_config, swarm_config, cost_function);
println!("Minimum of: {}, With value: {:?}", min.0, min.1);
}
依赖项
~1.3–2MB
~36K SLoC