4

有没有办法在不清除求解器并首先创建约束的情况下从求解器中删除定义的约束?

假设我的问题是最大化三个变量的总和,其中两个约束

约束 1:变量 2 应介于 8 - 10 之间

约束 2:变量 3 应介于 5 - 10 之间

from ortools.linear_solver import pywraplp

solver = pywraplp.Solver('SolveIntegerProblem',
                       pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)

objective = solver.Objective()

Variable[0] = solver.IntVar(0, 5, variable 0 )
Variable[1] = solver.IntVar(0, 10, variable 1 )
Variable[2] = solver.IntVar(0, 20, variable 2 )

objective.SetCoefficient(Variable[0], 1)
objective.SetCoefficient(Variable[1], 1)
objective.SetCoefficient(Variable[2], 1)

objective.SetMaximization() 

constraints.append(solver.Constraint(8,10))
constraints[0].SetCoefficient(variable[1],1) 

constraints.append(solver.Constraint(5,10))
constraints[1].SetCoefficient(variable[2],1)  

现在在第二次运行我的代码时,我想删除约束编号 2,但我找不到任何操作来执行此操作,唯一的方法是清除求解器并首先定义约束。

在这个半代码中,约束的数量是有限的,但实际上,在我的真实代码中,约束的数量很多,我不能从一开始就定义它们。

4

2 回答 2

1

我知道这个问题已经很老了,但是:

  • 据我所知,or-tools 不提供任何移除约束或变量的接口。从工程的角度来看,弄乱内部逻辑以“手动”删除它们是危险的。

  • 我的技术堆栈绝对需要该功能,并在那里尝试了多个 python 线性编程库(实际上是 clp/cbc 的包装器),尽管存在这个缺陷,但我还是选择了 or-tools,原因有两个:1)这是唯一一个最小的库我需要开箱即用的功能支持,2)当时(大约 4-5 年前)它是唯一使用 C 绑定的库。

所有其他人都使用与 cbc 命令行交互的另一种形式,这是一种与 python 交互的可怕方式。由于在磁盘上写入和读取文件的开销,它是不可扩展的。讨厌讨厌讨厌。所以如果我没记错的话,只有 pylp 和 or-tools 有 c 绑定,如果我没记错的话,pylp 不兼容 python 3(从那时起就一直处于困境)所以我选择了 or-tools。

因此,要回答您的问题:要使用 or-tools 来“删除”变量或约束,我必须围绕 or-tools 构建自己的 python 包装器。要停用变量或约束,我会将系数设置为零和自由边界(设置为 +/- 无穷大)并将成本设置为零以有效地停用约束。在我的包装器中,我会保留一个停用的约束/变量列表并回收它们而不是创建新的(这被证明会导致运行时增加和内存泄漏,因为 C++ + python 在这些领域是一场噩梦)。我严重怀疑我在回收中得到浮点噪音,但它在实践中足够稳定以满足我的需要。

因此,在您的代码示例中,要重新运行而不从头开始创建新模型,您需要执行以下操作:

(...)

constr1 = solver.Constraint(8,10)
constraints.append(constr1)
constraints[0].SetCoefficient(variable[1],1) 

constr2 = solver.Constraint(5,10)
constraints.append(constr2)
constraints[1].SetCoefficient(variable[2],1)

constr2.SetBounds(-solver.infinity(), solver.infinity())
constr2.SetCoefficient(variable[2], 0)

# constr2 is now deactivated. If you wanted to add a new constraints, you can
# change the bounds on constr2 to recycle it and add new variables 
# coefficients

话虽如此,最近发布了python-mip,它支持删除变量和约束,并具有 c 绑定。

于 2020-02-08T18:39:03.570 回答
0

您是否尝试使用该MPConstraint::Clear()方法?

声明:https
://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/linear_solver.h#L865 定义:https ://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6 /linear_solver/linear_solver.cc#L101

关于 Python swig 包装器MPConstraint被导出为Constraint对象。
src:https
://github.com/google/or-tools/blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/python/linear_solver.i#L180 但是方法Constraint::Clear()似乎没有暴露 https://github.com/google/or-tools /blob/9487eb85f4620f93abfed64899371be88d65c6ec/ortools/linear_solver/python/linear_solver.i#L270

您可以尝试修补 swig 文件并重新编译make python && make install_python

于 2018-06-19T07:28:36.870 回答