我想比较一下Gurobi和Scipy的线性编程工具,比如linprog。 Scipy 需要以 matrix-list-vector-form 的形式指定问题,而 Gurobi 的工作方式类似于 here 这样
m = Model()
m.addVar(...) %for variables
m.addConstr(..>) %for constraints
m.update() %for updating the model
m.optimize % for optimizing the model
m.params %for getting parameters
m._vars %for getting variables
Scipy
Minimize: c^T * x
Subject to: A_ub * x <= b_ub
A_eq * x == b_eq
c : array_like
Coefficients of the linear objective function to be minimized.
A_ub : array_like, optional
2-D array which, when matrix-multiplied by x, gives the values of the upper-bound inequality constraints at x.
b_ub : array_like, optional
1-D array of values representing the upper-bound of each inequality constraint (row) in A_ub.
A_eq : array_like, optional
2-D array which, when matrix-multiplied by x, gives the values of the equality constraints at x.
b_eq : array_like, optional
1-D array of values representing the RHS of each equality constraint (row) in A_eq.
bounds : sequence, optional
我的目标是仅用一种方法编写代码,并仍然使用两个求解器对结果进行基准测试。为了加快比较求解器的速度:
Scipy 是否存在 Gurobi 式的 LP 问题模型构建?
是否存在一些包可以使这两种方法互换(我可以为 Gurobi 编写 scipy 风格,或者为 Scipy 编写 Gurobi 风格)?
scipy 是否提供任何其他接口来指定线性规划问题?
这听起来需要做很多工作来展示显而易见的内容:
abs(some_vector)
可能会引入辅助变量)
基于您的 gurobi-example 的评论
res = linprog(c, A_ub=Aineq, b_ub=Bineq, A_eq=None if len(Aeq) == 0 else Aeq, b_eq=None if len(Beq) == 0 else Beq, bounds=x_bounds, method="highs", integrality=1)
if not res is None: return np.rint(res.x).astype(np.int64)
翻译为:
m = Model()
v = m.addVars(range(len(c)), lb=[x[0] for x in x_bounds], ub=[x[1] for x in x_bounds], vtype=[GRB.BINARY if x == (0,1) else GRB.INTEGER for x in x_bounds], name=labels)
m.addConstrs((sum(v[i]*a for i, a in enumerate(Aineq[j])) <= Bineq[j] for j in range(len(Aineq))))
m.addConstrs((sum(v[i]*a for i, a in enumerate(Aeq[j])) == Beq[j] for j in range(len(Aeq))))
m.setObjective(sum(v[i]*c[i] for i in range(len(c))), GRB.MINIMIZE)
m.update()
m.optimize()
return [int(v.x) for v in m.getVars()] if m.Status == GRB.OPTIMAL else None
当然,如果不是所有的边界都是整数或二进制,您可能需要更多的变量类型处理,或者 scipy 提供的其他各种可能性,例如列表与标量、无值等。不用说,它可以在几行中完成Python 代码。