ojalgo - 从 ojalgo 获得良好的次优解以进行线性优化
问题描述
介绍
我正在尝试使用 ojalgo 库来生成一种解决方案,以控制放置在任意位置的推进器以生成整体请求的旋转和平移。有时请求的旋转和平移是不可能的,但我希望在这些情况下试一试。
问题
我已经创建了我设置的 ExpressionsBasedModel 的这个最小示例。
如果我请求一组可能的条件,我会得到一个很好的结果:
Variable thruster1 = new Variable("t1").lower(0).upper(1).weight(0.1);
Variable thruster2 = new Variable("t2").lower(0).upper(1).weight(0.1);
ExpressionsBasedModel model = new ExpressionsBasedModel();
model.addVariable(thruster1);
model.addVariable(thruster2);
double targetXThrust = 2;
model.addExpression("XMotion")
.weight(1)
.set(thruster1, 1)
.set(thruster2, 1).lower(targetXThrust).upper(targetXThrust);
Optimisation.Result minimised = model.minimise();
System.out.println(minimised); //outputs 1,1
但如果我要求一些不太可能的事情
double targetXThrust = 2.1;
model.addExpression("XMotion")
.weight(1)
.set(thruster1, 1)
.set(thruster2, 1).lower(targetXThrust).upper(targetXThrust);
System.out.println(minimised); //outputs 0.5,0.5
理想情况下,我想要一个好的次优解决方案(1,1),但它似乎放弃并返回 0.5,0.5
问题
对于不可能完全解决的问题,是否有可能获得良好的次优解决方案?
可能的问题是我想最小化表达式上的错误,但我认为它实际上最小化了值(同时试图满足约束)
解决方案
实际上,我已经解决了我之前所说的 hacky 问题,因为它把它重新定义为一个实际的优化问题,所以我将它作为一个解决方案发布(尽管仍然可以得到更好的答案)
解决方案
为每个方程引入 positiveError 和negativeError 变量以确保问题有解,但给它们很大的权重,以便求解器避免使用它们
例子
//thrusters at powers between 0 and 1 (hard limits)
Variable thruster1 = new Variable("t1").lower(0).upper(1).weight(0.1); //we'd rather an engine was off if possible so give it a small weight
Variable thruster2 = new Variable("t2").lower(0).upper(1).weight(0.1);
Variable positiveError = new Variable("positiveError").lower(0).weight(10000); //we'd rather a solution was found if at all possible
Variable negativeError = new Variable("negativeError").lower(0).weight(10000);
ExpressionsBasedModel model = new ExpressionsBasedModel();
model.addVariable(thruster1);
model.addVariable(thruster2);
model.addVariable(positiveError);
model.addVariable(negativeError);
double targetXThrust = 2.1;
model.addExpression("XMotion")
.set(thruster1, 1)
.set(positiveError, 1)
.set(negativeError, -1)
.set(thruster2, 1)
.lower(targetXThrust)
.upper(targetXThrust);
Optimisation.Result minimised = model.minimise();
System.out.println(minimised); //prints 1, 1, 0.1, 0
这种方法还允许我定义我更关心的错误,因为我可以为不同的错误变量赋予不同的权重
推荐阅读
- vba - 查找并删除电子邮件第一行中的特定句子
- c# - 在圆形形成中生成的对象的移位旋转 - Unity C#
- sql - DB2 SQL 查找第一个和最后一个招聘日期与 deptno 10 相同的部门编号并计算年份
- mysql - SQL中基于datediff和curdate函数计算列值
- python - 适用于 AWS EC2 多账户的 Powershell 脚本
- javascript - 文本未出现在 SVG 上
- python - 使用多个变量/输入查询数据框列
- angular - 每个 Mat 表数据源
- sql - 如何使用 SQL 为包含相同数据集的所有组生成标识符?
- php - 站点登录后启动会话