python 使用乘法的混合整数编程

shyt4zoc  于 2022-12-21  发布在  Python
关注(0)|答案(2)|浏览(114)

我想最小化一个简单的函数其中x1是连续的,i1是整数。
下面的示例提供了一个Can not multiply with type <class 'mip.entities.LinExpr'>
MIP真的不能处理乘法运算吗?

from mip import Model, CONTINUOUS, INTEGER, minimize, xsum
import numpy as np

m = Model()

def func(x1, i1):
  return (x1 - .5) * (i1 - 1)
print(func(0, 0))
print(func(.5, 1))

x1 = m.add_var(var_type=CONTINUOUS)
i1 = m.add_var(var_type=INTEGER)

# constraint
m += x1 + i1 >= 0

m.objective = func(x1, i1)
# m.objective = minimize(xsum((x1 - .5) * (i1 - 1)))

status = m.optimize()
print(status)
print(m.objective_value)

for v in m.vars:
  print(v.name, v.x)
c9qzyr3d

c9qzyr3d1#

你需要使用一个不同的求解器来处理非线性表达式,你可以使用学术求解器PySCIPOpt,也可以使用商业的、免费的学术求解器Gurobi--这两个都有一个非常好的、直观的Python界面,看起来和你的代码非常相似。

arknldoa

arknldoa2#

你可以使用Google-ortools CP-SAT solver。它有一些约束,可以很容易地处理非线性表达式。你可以很容易地通过 pip install ortools 安装。一个缺点是-它只能处理整数值。但是我们可以通过将连续值缩放为整数,然后在报告解决方案之前将其缩放回来来绕过这个问题。请查看下面的代码清单

from ortools.sat.python import cp_model as cp

model = cp.CpModel()

scaling_factor = 100  # higher value for more numerical precision

i1 = model.NewIntVar(0, 100, "")
x1 = model.NewIntVar(0, 100 * scaling_factor, "")

model.Add(x1 + i1 >= 0)

# (x1 - .5)
dv_x1_part = model.NewIntVar(0, 100 * scaling_factor, "")
model.Add(dv_x1_part == x1 - int(0.5 * scaling_factor)) # scaling 0.5 also, since we are scaling x1

# (i1 - 1)
dv_i1_part = model.NewIntVar(0, 100, "")
model.Add(dv_i1_part == i1 - 1)

objective_function = model.NewIntVar(0, 10000000000, "")

# (x1 - .5) * (i1 - 1)
model.AddMultiplicationEquality(objective_function, [dv_x1_part, dv_i1_part])

model.Minimize(objective_function)

solver = cp.CpSolver()
solver.Solve(model) # 4 means optimal

objective_fun_value = solver.ObjectiveValue() / scaling_factor

# inspect decision variable values
x1_value = solver.Value(x1) / scaling_factor
i1_value = solver.Value(i1)

相关问题