首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何读取MPS文件

如何读取MPS文件
EN

Stack Overflow用户
提问于 2022-08-07 09:01:01
回答 1查看 169关注 0票数 1

现在,Scipy1.9支持挤奶。这是个好消息,但要使用它,我需要在MPS文件中指定问题。在MPS文件中,西西似乎没有读取的功能。

我怎么能这么做?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-07 17:21:39

正如注释中提到的,这个特性还没有实现。作为解决办法,您可以使用建模框架(如PuLPpython )读取PuLP文件,然后提取底层MILP的所有数据。

下面是通过python来实现这种方法的幼稚(因此速度慢):

代码语言:javascript
复制
import numpy as np
from mip import Model
from scipy.sparse import csr_matrix

def read_mps(file: str):
    """
    Reads a .mps and saves all the data of the MILP:

    min c^T * x

    s.t. b_l <= A*x <= b_u
          lb <=   x <= ub
                x_i integer if integrality[i] = 1
    """
    mdl = Model(solver_name="CBC")
    mdl.read(file)

    # model parameters
    num_vars = len(mdl.vars)
    num_cons = len(mdl.constrs)

    # variable types and bounds
    lb = np.zeros(num_vars)
    ub = np.inf*np.ones(num_vars)
    integrality = np.zeros(num_vars)
    for i, var in enumerate(mdl.vars):
        lb[i] = var.lb
        ub[i] = var.ub
        if var.var_type != "C":
            integrality[i] = 1

    # objective
    c = np.zeros(num_vars)
    for i, var in enumerate(mdl.vars):
        if var in mdl.objective.expr:
            c[i] = mdl.objective.expr[var]
    if mdl.sense != "MIN":
        c *= -1.0

    # constraint coefficient matrix
    b_l = -np.inf*np.ones((num_cons))
    b_u = np.inf*np.ones((num_cons))
    row_ind = []
    col_ind = []
    data    = []
    for i, con in enumerate(mdl.constrs):
        if con.expr.sense == "=":
            b_l[i] = con.rhs
            b_u[i] = con.rhs
        elif con.expr.sense == "<":
            b_u[i] = con.rhs
        elif con.expr.sense == ">":
            b_l[i] = con.rhs
        for j, var in enumerate(mdl.vars):
            if var in (expr := con.expr.expr):
                coeff = expr[var]
                row_ind.append(i)
                col_ind.append(j)
                data.append(coeff)
    A = csr_matrix((data, (row_ind, col_ind)), shape=(num_cons, num_vars))
    return c, b_l, A, b_u, lb, ub, integrality

然后,您可以读取所有数据并将其传递给milp,如下所示:

代码语言:javascript
复制
from scipy.optimize import milp, Bounds, LinearConstraint

c, b_l, A, b_u, lb, ub, integrality = read_mps("example.mps")
bounds = Bounds(lb, ub)
constraints = LinearConstraint(A, b_l, b_u)

res = milp(c=c, constraints=constraints, bounds=bounds, integrality=integrality)

尽管如此,上述解决方法仅适用于中小型模型文件。

顺便提一句,值得一提的是,scipy.optimize.milp使用的是引擎盖下的HiGHS求解器,最近还在PuLP中构建了一个接口,并计划对python进行同样的操作。这两种建模框架都可以读取.lp和.mps文件,并将它们传递给接口求解器,因此不迫切需要在can中等待此特性。但是,公平地说,PuLP只对某些解决程序的可执行文件进行接口,而不是将它们与python包一起传送,并进一步假定最终用户已经安装了它们。海事组织,这真的不是一个方便的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73266140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档