#优化 #非线性 #约束 #牛顿 #上界 #下界

ipopt

Rust语言绑定Ipopt非线性约束优化库

12个版本

0.5.4 2020年3月9日
0.5.2 2019年9月10日
0.5.1 2019年4月23日
0.5.0 2019年3月28日
0.1.0 2018年3月1日

#537 in 算法

Download history 29/week @ 2024-03-12 21/week @ 2024-03-19 23/week @ 2024-03-26 37/week @ 2024-04-02 36/week @ 2024-04-09 66/week @ 2024-04-16 118/week @ 2024-04-23 54/week @ 2024-04-30 110/week @ 2024-05-07 63/week @ 2024-05-14 8/week @ 2024-05-21 34/week @ 2024-05-28 43/week @ 2024-06-04 37/week @ 2024-06-11 34/week @ 2024-06-18 29/week @ 2024-06-25

每月156次下载

MIT/Apache

160KB
3K SLoC

Rust 2.5K SLoC // 0.1% comments C++ 410 SLoC // 0.0% comments

ipopt-rs

Ipopt非线性优化库的安全Rust接口。

On crates.io On docs.rs Build status

来自Ipopt网页

Ipopt (Interior Point OPTimizer,发音为eye-pea-Opt) 是一个用于大规模非线性优化的软件包。它旨在求解数学优化问题的(局部)解,形式如下

   min     f(x)
   x in R^n

   s.t.       g_L <= g(x) <= g_U
              x_L <=  x   <= x_U

其中 f(x): R^n --> R 是目标函数,而 g(x): R^n --> R^m 是约束函数。向量 g_Lg_U 表示约束的下界和上界,而向量 x_Lx_U 是变量 x 的界限。函数 f(x)g(x) 可以是非线性和非凸的,但应该具有二阶连续可微性。注意,可以通过将 g_Lg_U 的相应分量设置为相同的值,在上述公式中表达等式约束。

本crate旨在

  • 减少样板代码,尤其是对于设置简单的无约束问题
  • 保持高级用例的灵活性
  • 通过类型系统和错误检查尽早定义优化问题以防止常见错误。

示例

使用L-BFGS求解一个简单的无约束问题:最小化 (x - 1)^2 + (y -1)^2

use approx::*;
use ipopt::*;

struct NLP {
}

impl BasicProblem for NLP {
    // There are two independent variables: x and y.
    fn num_variables(&self) -> usize {
        2
    }    
    // The variables are unbounded. Any lower bound lower than -10^9 and upper bound higher
    // than 10^9 is treated effectively as infinity. These absolute infinity limits can be
    // changed via the `nlp_lower_bound_inf` and `nlp_upper_bound_inf` Ipopt options.
    fn bounds(&self, x_l: &mut [Number], x_u: &mut [Number]) -> bool {
        x_l.swap_with_slice(vec![-1e20; 2].as_mut_slice());
        x_u.swap_with_slice(vec![1e20; 2].as_mut_slice());
        true
    }

    // Set the initial conditions for the solver.
    fn initial_point(&self, x: &mut [Number]) -> bool {
        x.swap_with_slice(vec![0.0, 0.0].as_mut_slice());
        true
    }

    // The objective to be minimized.
    fn objective(&self, x: &[Number], obj: &mut Number) -> bool {
        *obj = (x[0] - 1.0)*(x[0] - 1.0) + (x[1] - 1.0)*(x[1] - 1.0);
        true
    }

    // Objective gradient is used to find a new search direction to find the critical point.
    fn objective_grad(&self, x: &[Number], grad_f: &mut [Number]) -> bool {
        grad_f[0] = 2.0*(x[0] - 1.0);
        grad_f[1] = 2.0*(x[1] - 1.0);
        true
    }
}

fn main() {
    let nlp = NLP { };
    let mut ipopt = Ipopt::new_unconstrained(nlp).unwrap();

    // Set Ipopt specific options here a list of all options is available at
    // https://www.coin-or.org/Ipopt/documentation/node40.html
    ipopt.set_option("tol", 1e-9); // set error tolerance
    ipopt.set_option("print_level", 5); // set the print level (5 is the default)

    let solve_result = ipopt.solve();

    assert_eq!(solve_result.status, SolveStatus::SolveSucceeded);
    assert_relative_eq!(solve_result.objective_value, 0.0, epsilon = 1e-10);
    let solution = solve_result.solver_data.solution;
    assert_relative_eq!(solution.primal_variables[0], 1.0, epsilon = 1e-10);
    assert_relative_eq!(solution.primal_variables[1], 1.0, epsilon = 1e-10);
}

请参阅测试以获取更多示例,包括约束优化。

获取Ipopt二进制文件

目前,这个库在平台支持方面还不够成熟。正在进行改进工作。例如,Windows目前不支持,直到我获得一台Windows机器或者有人提供支持;)

有关如何获取Ipopt二进制文件的详细信息,请参阅ipopt-sys

许可

本存储库采用以下任一许可:

由您选择。

依赖关系

~0–4.5MB
~75K SLoC