如何在 or-tools 中定义复杂的目标函数?

Posted

技术标签:

【中文标题】如何在 or-tools 中定义复杂的目标函数?【英文标题】:How to define complex objective functions in or-tools? 【发布时间】:2020-04-09 04:00:45 【问题描述】:

我想知道如何使用 or-tools 定义一个复杂的目标函数(如果可能的话)。

下面的基本示例展示了如何在 python 中使用 Or-tools 解决基本的线性问题:

solver = pywraplp.Solver('lp_pricing_problem', pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

# Define variables with a range from 0 to 1000.
x = solver.NumVar(0, 1000, 'Variable_x')
y = solver.NumVar(0, 1000, 'Variable_y')

# Define some constraints.
solver.Add(x >= 17)
solver.Add(x <= 147)
solver.Add(y >= 61)
solver.Add(y <= 93)

# Minimize 0.5*x + 2*y
objective = solver.Objective()
objective.SetCoefficient(x, 0.5)
objective.SetCoefficient(y, 2)
objective.SetMinimization()

status = solver.Solve()

# Print the solution
if status == solver.OPTIMAL:
    print("x: , y: ".format(x.solution_value(), y.solution_value())) # x: 17.0, y: 61.0 

在这个非常基本的例子中,目标函数是Minimize(0.5*x + 2*y)。 例如,获得最小二乘法Minimize(x^2 + y^2) 或变量绝对值Minimize(abs(x) + y) 的语法是什么?

是否可以定义一个子函数并将其调用到目标函数中?还是我应该采取其他方式?

非常感谢,

罗曼

【问题讨论】:

【参考方案1】:

你已经用linear-programming标记了这个问题,所以你已经有了在这里找出答案的材料。

如果您查看this page,您会发现 OR-Tools 解决了线性程序,以及少数其他优化问题系列。

所以你提到的第一个目标函数,Minimize(0.5*x + 2*y) 是可解的,因为它是线性的。

您提到的第二个目标---Minimize(x^2 + y^2)--- 无法使用 OR-Tools 解决,因为它是非线性的:这些平方项使其成为二次项。要解决这个问题,您需要能够做到quadratic programming、second-order cone programming 或quadratically constrained quadratic programming 的东西。所有这些方法都将线性规划作为子集。我推荐用于解决这类问题的工具是cvxpy,它提供了一个强大而优雅的界面。 (或者,您可以将二次近似为分段线性,但您会遇到更多约束。)

您提到的最后一个目标,Minimize(c*abs(x) + y) 可以作为线性程序求解,即使 abs(x) 本身是非线性的。为此,我们将目标重写为min( c*(t1-t2) +y) 并添加约束t1,t2&gt;=0。只要c 是正数并且您正在最小化(或c 是负数并且您正在最大化),它就可以工作。更长的解释是here。

您可以执行许多这样的转换,而数学程序员/运筹学研究人员的一项技能就是记住其中的许多。

【讨论】:

我认为 OR-tools 可以与支持二次问题的 Gurobi 一起使用。是不是OR-tools API的限制? @Stradivari:很好的发现! 非常感谢@Stradivari!我将在接下来的几周内检查如何切换到 Gurobi。我们已经在考虑使用它了。现在,它成为强制性的。 @Romain:我仍然建议查看 cvxpy。它还可以卸载到 Gurobi 并解决广泛的问题。

以上是关于如何在 or-tools 中定义复杂的目标函数?的主要内容,如果未能解决你的问题,请参考以下文章

OR-Tools MIP Solver - 根据 int 定义目标,而不是 IntVar

在 C# 中使用 Google OR-Tools 寻找目标?

Google OR-Tools(使用 SCIP 求解器) - 如何访问求解器找到的中间解决方案?

OR-TOOLS - 如何解决有序分配问题?

如何在 AWS Lambda 上安装 Google or-tools?

如何在 Google OR-Tools Route Optimization 中限制每辆车的位置数量