首页 > 解决方案 > 计算机租赁问题 - Pyomo 中的线性优化。我的解决方案在 AMPL 中运行,但 Pyomo 说它没有 Bound - 可能出了什么问题

问题描述

我正在尝试在 Pyomo 中建模一个简单的线性问题。我在 AMPL 中完成了建模并得到了正确的答案,但出于某种奇怪的原因,Pyomo 说它没有界限。

如果有人能很好地观察我所做的事情,看看为什么它在 pyomo 中不起作用。所有数据和代码如下。

这是最初的问题: BCoE 已确定,在接下来的 12 个月中,每个月都需要下表中给出的笔记本电脑数量。为满足这些要求,BCoE 会租用笔记本电脑一、二或三个月。租一台笔记本电脑一个月需要 100 美元,两个月需要 180 美元,三个月需要 250 美元。第 1 月初,BCOE 拥有 70 台笔记本电脑。以最低成本确定满足未来 12 个月要求的租赁计划。为这个问题写一个数学程序,并使用你选择的求解器来解决它。

笔记本电脑要求
1 700
2 1100
3 500
4 600
5 1100
6 500
7 700
8 700
9 300
10 600
11 700
12 700

这是我在 PYOMO 中编码的内容:

# IMPORT THE NECESSARY CLASSES
from pyomo.environ import *
infinity = float('inf')

# CREATE THE MODEL
model=ConcreteModel()


# GENERAL VARIABLES:
borrowPeriod = [1,2,3]   # Number of Months you can Borrow The laptops
Months = [1,2,3,4,5,6,7,8,9,10,11,12]  # Ind
demandPerMonth = [700,1100,500,600,1100,500,700,700,300,600,700,700]


# Variables Month1 - Month12 are meant to just know which Indices to use for each Month when I code the constraints

Month1 = []
for i in range(1,2):
    for j in borrowPeriod:
        tmp = i,j
        Month1.append(tmp)        

Month2 = []
for i in range(1,3):
    for j in borrowPeriod:
        tmp = i,j
        Month2.append(tmp)

Month2 = Month2[-5:]


Month3 = []
for i in range(1,4):
    for j in borrowPeriod:
        tmp = i,j
        Month3.append(tmp)

Month3 = Month3[-5:]
Month3.append(Month1[-1])


Month4 = []
for i in range(1,5):
    for j in borrowPeriod:
        tmp = i,j
        Month4.append(tmp)

Month4 = Month4[-5:]
Month4.append(Month2[-1])


Month5 = []
for i in range(1,6):
    for j in borrowPeriod:
        tmp = i,j
        Month5.append(tmp)

Month5 = Month5[-5:]
Month5.append(Month3[-2])


Month6 = []
for i in range(1,7):
    for j in borrowPeriod:
        tmp = i,j
        Month6.append(tmp)

Month6 = Month6[-5:]
Month6.append(Month4[-2])


Month7 = []
for i in range(1,8):
    for j in borrowPeriod:
        tmp = i,j
        Month7.append(tmp)

Month7 = Month7[-5:]
Month7.append(Month5[-2])


Month8 = []
for i in range(1,9):
    for j in borrowPeriod:
        tmp = i,j
        Month8.append(tmp)

Month8 = Month8[-5:]
Month8.append(Month6[-2])


Month9 = []
for i in range(1,10):
    for j in borrowPeriod:
        tmp = i,j
        Month9.append(tmp)

Month9 = Month9[-5:]
Month9.append(Month7[-2])


Month10 = []
for i in range(1,11):
    for j in borrowPeriod:
        tmp = i,j
        Month10.append(tmp)

Month10 = Month10[-5:]
Month10.append(Month8[-2])


Month11 = []
for i in range(1,12):
    for j in borrowPeriod:
        tmp = i,j
        Month11.append(tmp)

Month11 = Month11[-5:]
Month11.append(Month9[-2])


Month12 = []
for i in range(1,13):
    for j in borrowPeriod:
        tmp = i,j
        Month12.append(tmp)

Month12 = Month12[-5:]
Month12.append(Month10[-2])


# FULLDATA is meant to hold all actual variables I would be manipulating in the constraints and Objective Function.

fullData = []
for i in Months:
    for j in borrowPeriod:
        tmp = i,j
        fullData.append(tmp)

fullData
model.full = Var(fullData, initialize=0)



# THE OBJECTIVE FUNCTION:
model.value = Objective(expr = 100*sum(model.full[x] for _,x in enumerate(fullData) if x[1] == 1) + 180*sum(model.full[x] for _,x in enumerate(fullData) if x[1] == 2) + 250*sum(model.full[x] for _,x in enumerate(fullData) if x[1] == 3), sense=minimize)



# THE CONSTRAINTS - These Contraints are as per the question

model.month1 = Constraint(expr = 70 + sum(model.full[x] for _,x in enumerate(Month1)) >= 700)
model.month2 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month2)) >= 1100)
model.month3 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month3)) >= 500)
model.month4 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month4)) >= 600)
model.month5 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month5)) >= 1100)
model.month6 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month6)) >= 500)
model.month7 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month7)) >= 700)
model.month8 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month8)) >= 700)
model.month9 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month9)) >= 300)
model.month10 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month10)) >= 600)
model.month11 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month11)) >= 700)
model.month12 = Constraint(expr = sum(model.full[x] for _,x in enumerate(Month12)) >= 700)

这是我得到的结果

[    0.00] Setting up Pyomo environment
[    0.00] Applying Pyomo preprocessing actions
[    0.01] Creating model
[    0.01] Applying solver
[    0.05] Processing results
    Number of solutions: 0
    Solver results file: results.json
[    0.05] Applying Pyomo postprocessing actions
[    0.05] Pyomo Finished
errorcode: 0
retval: instance: <pyomo.core.base.PyomoModel.ConcreteModel object at 0x0000020CD402C9F8>
local:
    time_initial_import: 0.0059854984283447266
    usermodel: <module 'HW5' from 'C:\\Users\\aizuw\\Documents\\Schools\\UTK -\\Classes\\Second Semester\\IE 522\\Assignments\\HW 5\\HW5.py'>
options: <pyomo.common.config.ConfigDict object at 0x0000020CD3F59688>
results: {'Problem': [{'Name': 'unknown', 'Lower bound': -inf, 'Upper bound': inf, 'Number of objectives': 1, 'Number of constraints': 13, 'Number of variables': 37, 'Number of nonzeros': 69, 'Sense': 'minimize'}], 'Solver': [{'Status': 'ok', 'Termination condition': 'unbounded', 'Statistics': {'Branch and bound': {'Number of bounded subproblems': 0, 'Number of created subproblems': 0}}, 'Error rc': 0, 'Time': 0.021906614303588867}]}

结果.json 文件输出:

{
    "Problem": [
        {
            "Lower bound": -Infinity,
            "Name": "unknown",
            "Number of constraints": 13,
            "Number of nonzeros": 69,
            "Number of objectives": 1,
            "Number of variables": 37,
            "Sense": "minimize",
            "Upper bound": Infinity
        }
    ],
    "Solver": [
        {
            "Error rc": 0,
            "Statistics": {
                "Branch and bound": {
                    "Number of bounded subproblems": 0,
                    "Number of created subproblems": 0
                }
            },
            "Status": "ok",
            "Termination condition": "unbounded",
            "Time": 0.021906614303588867
        }
    ]
}

标签: pythonlinear-programmingpyomoampl

解决方案


这个问题在构造时是无界的,因为您没有限制变量的域,因此允许它变为负数,并且求解器正变得疯狂,因为它也在尝试对“负购买”进行建模。这解决了问题。(注意:您也不必初始化变量):

model.full = Var(fullData, domain=NonNegativeReals)

此外,如果你在这方面做一些工作,你可以稍微加强你的模型构造。您应该能够使用约束的 RHS 值列表,并通过循环将它们全部生成,而不是单独写出它们。您创建月度指数也是如此。你能想出一个数学表达式来表示“n”月中手头的计算机数量吗?如果是这样,您可以使用一些列表推导和简单条件即时创建索引。:)


推荐阅读