4 个版本 (重大变更)
新 0.4.0 | 2024年8月15日 |
---|---|
0.3.3 | 2024年8月12日 |
0.2.3 | 2024年8月10日 |
0.1.0 | 2024年8月10日 |
#216 在 算法 中
413 每月下载量
1MB
11K SLoC
Optirustic
Optirustic 是一个用 Rust 编写的框架,它提供了解决多目标问题的算法和分析工具,使用多目标进化算法(MOEAs)。它允许您
- 定义具有自定义目标函数的最小化和最大化问题;
- 定义约束和无约束变量(实数、整数、布尔值或选择);
- 使用多线程评估具有许多个体的种群中的目标和约束;
- 将种群历史导出为 JSON 格式,并从文件中恢复其进化;
目前,它包括 NSGA2
和 NSGA3
算法。
API 文档可在 docs.rs 上找到。展示此库功能的示例可在此存储库的示例文件夹中找到。
安装 Optirustic
Optirustic 可在 crates.io 上找到。推荐的方法是在您的 Cargo.toml 中添加一行
[dependencies]
optirustic = "*"
示例
问题定义
在这个例子中,我们将使用 NSGA2
算法解决 Schaffer 的问题。该问题旨在最小化以下 2 个目标
- f1(x) = x2
- f2(x) = (x - 2)2
该问题有 1 个变量(x
),范围在 -1000
和 1000
之间。可选解预期位于 [0; 2]
范围内。
问题实现
问题通过使用 SCHProblem
结构体实现。当算法运行时,它首先为问题变量(在本例中为 x
)生成一组潜在解。然后,它在此库公开的 Evaluator
特性中计算目标(f1(x) 和 f2(x))。
#[derive(Debug)]
pub struct SCHProblem;
impl SCHProblem {
/// Create the problem for the optimisation.
pub fn create() -> Result<Problem, OError> {
// define the objectives
let objectives = vec![
Objective::new("x^2", ObjectiveDirection::Minimise),
Objective::new("(x-2)^2", ObjectiveDirection::Minimise),
];
// define the variable
let variables = vec![VariableType::Real(BoundedNumber::new(
"x", -1000.0, 1000.0,
)?)];
// the problem has no constraints
let constraints = None;
let e = Box::new(SCHProblem);
Problem::new(objectives, variables, constraints, e)
}
/// The first objective function
pub fn f1(x: f64) -> f64 {
x.powi(2)
}
/// The second objective function
pub fn f2(x: f64) -> f64 {
(x - 2.0).powi(2)
}
}
// Implement the function to evaluate the objectives and constraints. The `evaluate`
// function below receives the individuals which contain the variables/solutions `x`
// proposed by the algorithm. The function must return the evaluated objectives and
// constraints in the `EvaluationResult` struct.
impl Evaluator for SCHProblem {
fn evaluate(&self, i: &Individual) -> Result<EvaluationResult, Box<dyn Error>> {
let x = i.get_variable_value("x")?.as_real()?;
let mut objectives = HashMap::new();
objectives.insert("x^2".to_string(), SCHProblem::f1(x));
objectives.insert("(x-2)^2".to_string(), SCHProblem::f2(x));
Ok(EvaluationResult {
constraints: None,
objectives,
})
}
}
设置和运行遗传算法
以下代码设置了具有 NSGA2
算法,包含 100
个个体,并在达到 250
代种群时停止。
...
fn main() -> Result<(), Box<dyn Error>> {
// Setup the NSGA2 algorithm
let args = NSGA2Arg {
// use 100 individuals and stop the algorithm at 250 generations
number_of_individuals: 100,
stopping_condition: StoppingConditionType::MaxGeneration(MaxGeneration(250)),
// use default options for the SBX and PM operators
crossover_operator_options: None,
mutation_operator_options: None,
// no need to evaluate the objective in parallel
parallel: Some(false),
// do not export intermediate solutions
export_history: None,
resume_from_file: None,
// to reproduce results
seed: Some(10),
};
let mut algo = NSGA2::new(problem, args)?;
// run the algorithm
algo.run()?;
// Export serialised results at last generation
algo.save_to_json(&PathBuf::from("."), Some("SCH_2obj"))?;
Ok(())
}
完整的示例代码可在该存储库的 示例文件夹 中找到,并可以使用以下命令运行:
cargo run --example nsga2_sch --release
这是算法导出的序列化数据: SCH_2obj_NSGA2_gen250.json,以下是绘制的解
依赖项
~7–12MB
~232K SLoC