【问题标题】:Obtaining a good suboptimal solution from ojalgo for a linear optimisation从 ojalgo 获得良好的次优解以进行线性优化
【发布时间】:2021-08-28 12:30:44
【问题描述】:

简介

我正在尝试使用 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 解决方案,引入了一个额外的变量; badness 允许任何正值(并有助于 XMotion)并且具有非常高的权重。这导致模型仅在确实需要时才使用它,但确保解决方案始终是可能的(从求解器的角度来看)。如果我没有得到答案,我会发布,但感觉不对

标签: ojalgo linear-optimization


【解决方案1】:

实际上,我已经解决了我之前所说的 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

这种方法还允许我定义我更关心的错误,因为我可以为不同的错误变量赋予不同的权重

【讨论】:

  • 一种可能尝试的变体是分两步完成。首先尝试最小化错误。如果有可能把它带到 0.0 然后优化其他的东西。应该可以修改您拥有的 ExpressionsBasedModel 实例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多