我想使用ojAlgo(版本51.4.0(中的单纯形来解决一个线性问题,并能够检索其对偶变量及其降低的成本。我期望Result
中的方法getMultipliers()
返回对偶变量,但在我的示例中情况并非如此(请参阅下面的代码(。
我的问题如下:
- 如何检索对偶变量
- 如何收回降低的成本
- 强制使用一个解算器(在我的情况下为
SimplexSolver
(的最佳方法是什么
对于问题3,我使用了primModel.options.debug(SimplexSolver.class)
,因为addPreferredSolver()
已弃用。工作时,我想知道是否有一种更可取的方式。
我希望能够在ojAlgo fork之外检索这些信息(类PrimalSimplex
和DualSimplex
在这里看起来很有趣,但它们不能使用,因为它们不能从包外部访问(。
/**
* problem from https://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15859-f11/www/notes/lecture05.pdf
*
* problem: maximize 2 * x1 + 3 *x2
* s.t. 4 * x1 + 8 * x2 <= 12
* 2 * x1 + x2 <= 3
* 3 * x1 + 2 * x2 <= 4
* x1, x2 >= 0
*/
ExpressionsBasedModel primModel = new ExpressionsBasedModel(); // problem to solve
Variable x1 = primModel.addVariable("X1").lower(0).weight(2); // maximize 2 * x1
Variable x2 = primModel.addVariable("X2").lower(0).weight(3); // ... + 3 * x2
Expression a1 = primModel.addExpression(); // constraints to respect
Expression a2 = primModel.addExpression();
Expression a3 = primModel.addExpression();
a1.set(x1, 4).set(x2, 8).upper(12); // 4 * x1 + 8 * x2 <= 12
a2.set(x1, 2).set(x2, 1).upper(3); // 2 * x1 + x2 <= 3
a3.set(x1, 3).set(x2, 2).upper(4); // 3 * x1 + 2 * x2 <= 4
// force the use of simplex (question 3)
primModel.options.debug(SimplexSolver.class);
Optimisation.Result result = primModel.maximise();
// does not give the dual variables: no value present within the optional
Optional<Access1D<?>> multipliers = result.getMultipliers();
System.out.println(result.toString());
如有任何帮助,我们将不胜感激。非常感谢。
LinearSolver
确实返回了对偶变量,但是:
-
当从
ExpressionsBasedModel
生成LP时,不会实现从LP约束到模型变量和表达式的下限/上限的反向映射。因此,ExpressionsBasedModel
返回的结果不包含对偶变量。要获得对偶变量,您必须跳过使用ExpressionsBasedModel
,而直接使用LinearSolver
中的构建器。 -
在线性求解器/构造器代码中,有逻辑处理是否需要对偶。不记得这是怎么回事了。我认为当你使用建造者时,你总是会得到对偶。你必须检查一下。
如果要控制ExpressionsBasedModel
将选择哪个解算器,则必须对ExpressionsBasedModel.Integration
的实现进行编码,然后使用ExpressionsBasedModel#addIntegration(Integration<?>)
进行注册。该功能的存在是为了能够使用CPLEX、GUROBI、MOSEK等第三方解算器。