约束公式的solver.Add("x + y < 5") 字符串表示的替代方案

问题描述

我在 Linux Azure Function 上的 Python 中运行了 OR-Tools。

我想让它成为一个 API 端点,在那里我可以发布一个整数编程问题的 JSON 表示并收到一个解决方案。

# Grab the POST data as an object
req_json = req.get_json()

# Create the MIP solver BOP/SAT/CBC
solver = pywraplp.solver.CreateSolver('BOP')

# Create the variables
x = {}
for i in range(len(req_json['Variables'])):
    x[i] = solver.Intvar(0,req_json['Variables'][i]['UpperBound'],req_json['Variables'][i]['Name'])
print('Number of variables =',solver.NumVariables())

# Create the constraints
for j in range(len(req_json['Constraints'])):
    solver.Add(req_json['Constraints'][j]['Formula'])
print('Number of constraints =',solver.NumConstraints())

然而,solver.Add() 似乎不支持公式的字符串表示形式,它需要一个solver.Add(x + y < 5) 这样的对象,那么还有其他方法可以做到这一点吗?

我的变量和约束公式是动态的,将由另一个系统提供。我曾考虑使用 Arrays to define the model 代替,但我的公式非常复杂,我不确定我是否能够将它们简化为一组约束系数。

解决方法

你必须自己解析约束,一种肮脏的方式是这样的:

formula = "x + y + z == 0"
formula = re.sub(
    r"[^\s]+",lambda m: f'x["{m.group(0)}"]' if m.group(0).isalpha() else m.group(0),formula,)
solver.Add(eval(formula))

但不推荐使用 eval

在变量 dict 中查找每个术语并对运算符 (Turn string into operator) 执行相同操作,或者尝试使用 LoadModelFromProto+ExportModelToProtoExportModelAsMpsFormat 之类的方法。>