使用 ojAlgo 求解线性规划(LP)问题
ojAlgo 是一个专注于数值计算和优化的 Java 开源库,提供了简洁直观的 API 来求解线性规划(LP)、整数规划(IP)等问题。相比其他工具,ojAlgo 的代码可读性强,配置灵活,特别适合在 Java 项目中集成。本文以具体示例介绍如何使用 ojAlgo 求解 LP 问题。
问题定义
我们需要求解以下整数线性规划问题(变量为整数):
目标函数:minimize 5x₁ + 6x₂ + 23x₃ + 5x₄ + 24x₅ + 6x₆ + 23x₇ + 5x₈(最小化加权和)
约束条件:
2x₁ + x₂ + x₃ + x₄ ≥ 100
2x₂ + x₃ + 3x₅ + 2x₆ + x₇ ≥ 150
x₁ + x₃ + 3x₄ + 2x₆ + 3x₇ + 5x₈ ≥ 100
变量约束:所有变量为非负整数(xᵢ ≥ 0且为整数)
环境配置
引入 ojAlgo 依赖
在 Maven 项目的pom.xml中添加依赖:
1 2 3 4 5
| <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo</artifactId> <version>51.4.1</version> </dependency>
|
代码实现与解析
核心步骤
- 创建模型:初始化
ExpressionsBasedModel(ojAlgo 的优化模型容器)。
- 定义变量:添加目标函数中的变量,指定类型(整数)、下界(非负)和权重(目标函数系数)。
- 定义约束:通过
Expression对象添加约束条件(不等式)。
- 求解优化:调用
minimise()方法求解最小值,获取结果。
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| import org.ojalgo.optimisation.ExpressionsBasedModel; import org.ojalgo.optimisation.Optimisation; import org.ojalgo.optimisation.Variable;
public class LpWithOjAlgo { public static void main(String[] args) { ExpressionsBasedModel model = new ExpressionsBasedModel();
model.addVariable(Variable.makeInteger("x1").lower(0).weight(5)); model.addVariable(Variable.makeInteger("x2").lower(0).weight(6)); model.addVariable(Variable.makeInteger("x3").lower(0).weight(23)); model.addVariable(Variable.makeInteger("x4").lower(0).weight(5)); model.addVariable(Variable.makeInteger("x5").lower(0).weight(24)); model.addVariable(Variable.makeInteger("x6").lower(0).weight(6)); model.addVariable(Variable.makeInteger("x7").lower(0).weight(23)); model.addVariable(Variable.makeInteger("x8").lower(0).weight(5));
Expression constraint1 = model.addExpression("constraint1"); constraint1.set(0, 2); constraint1.set(1, 1); constraint1.set(2, 1); constraint1.set(3, 1); constraint1.lower(100);
Expression constraint2 = model.addExpression("constraint2"); constraint2.set(1, 2); constraint2.set(2, 1); constraint2.set(4, 3); constraint2.set(5, 2); constraint2.set(6, 1); constraint2.lower(150);
Expression constraint3 = model.addExpression("constraint3"); constraint3.set(0, 1); constraint3.set(2, 1); constraint3.set(3, 3); constraint3.set(5, 2); constraint3.set(6, 3); constraint3.set(7, 5); constraint3.lower(100);
Optimisation.Result result = model.minimise();
System.out.println("优化结果状态:" + result.getState()); System.out.println("目标函数最小值:" + result.getValue()); System.out.println("变量最优解:"); for (Variable var : model.getVariables()) { System.out.println(var.getName() + " = " + var.getValue()); } } }
|
结果解析
输出结果
1 2 3 4 5 6 7 8 9 10 11
| 优化结果状态:OPTIMAL 目标函数最小值:600.0 变量最优解: x1 = 30.0 x2 = 40.0 x3 = 0.0 x4 = 0.0 x5 = 0.0 x6 = 35.0 x7 = 0.0 x8 = 0.0
|
结果验证
- 目标函数值:
5×30 + 6×40 + 23×0 + 5×0 + 24×0 + 6×35 + 23×0 + 5×0 = 150 + 240 + 210 = 600。
- 约束满足性:
- 约束 1:
2×30 + 40 + 0 + 0 = 100(满足≥100)。
- 约束 2:
2×40 + 0 + 3×0 + 2×35 + 0 = 80 + 70 = 150(满足≥150)。
- 约束 3:
30 + 0 + 3×0 + 2×35 + 3×0 + 5×0 = 30 + 70 = 100(满足≥100)。
ojAlgo 的优势
- 可读性强:通过
Variable和Expression类直观定义变量和约束,代码逻辑清晰。
- 类型灵活:支持整数变量(
makeInteger())、二进制变量(makeBinary())和连续变量(默认),无需手动转换约束格式。
- 集成便捷:纯 Java 实现,无外部依赖,适合嵌入 Java 应用程序。
- 结果丰富:
Result对象包含优化状态(是否最优)、目标值和变量解,便于后续处理。
总结
ojAlgo 为 Java 开发者提供了简洁高效的线性规划求解方案,通过面向对象的 API 简化了变量和约束的定义过程。对于整数规划、混合整数规划等问题,ojAlgo 同样能提供稳定的求解能力。相比 JOptimizer,ojAlgo 的代码可读性更强,更适合复杂约束场景的开发。在实际项目中,可根据问题规模和类型选择合适的优化库,ojAlgo 是中小型整数规划问题的理想选择
v1.3.10