PYOMO:使用集合和参数定义数据集以解决优化问题 [英] PYOMO: Defining dataset using Sets and Parameters for solving an optimization problem

查看:85
本文介绍了PYOMO:使用集合和参数定义数据集以解决优化问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将一些数据公式化为 PYOMO 模型以解决优化问题.

I am trying to formulate some data into a PYOMO model for an optimization problem.

materials = ['steel', 'alum', 'carbon', 'cheese']

每种材料都有 2 个属性 - 密度和电导率,它们的值定义如下.

Each material has 2 properties - density and conductivity and their values are defined as follows.

density =   {   'steel' : 1.2,
            'alum'  : 0.8,
            'carbon': 1.8,
            'cheese': 0.7}

conductivity = {'steel' : 6.4,
               'alum'  : 3.1,
               'carbon': 4.4,
               'cheese': 0.3}

目标函数计算 2 个矩形板的重量,如下所示:

The objective function calculates the weight of 2 rectangular plates as given below:

Objective function = Area_1 * thickness_1 * density_1 + Area_2 * thickness_2 * density_2

其中,Area_1、thickness_1 和 density_1 为板 1 的面积、厚度和密度.

Where, the Area_1, thickness_1, and density_1 are area, thickness and density of plate 1.

每块板的面积和厚度是固定的.但是密度值取决于求解器选择的材料以获得最佳结果.该模型还具有如下定义的约束:

Area and thickness are fixed for each plates. But the density value depends on the material chosen by the solver to get the best results. The model also have a constraint defined as follows:

(conductivity_1/thickness_1) + (conductivity_2/thickness_2)  => 22

因此,求解器在为板选择密度值时,还必须选择相同材料的电导率值.

如果有人能帮助我解决这个问题,我将不胜感激.如果您有不同的想法来解决这个问题,我也欢迎.谢谢.

I would appreciate it if someone can help me with this problem. I also welcome if you have different ideas to solve this problem. Thank you.

推荐答案

这是一个我认为可以满足您所有问题的示例模型.

Here is an example model that I think meets all of your questions.

一旦您将第二个索引设置为车牌 P = {1, 2, 3} 在这种情况下为 3 个车牌,那么我们需要对我们的决策变量进行双重索引以表示分配材料 m 到板 p.在这个例子中,4 个材料,3 个板.

Once you set up the second index to be the plates P = {1, 2, 3} in this case for 3 plates, then we need to double index our decision variable to represent the assignment of material m to plate p. In this example, 4 materials, 3 plates.

此处可能存在许多其他约束条件,但我添加的约束条件回答了您关于总体电导率的问题.请注意,我还添加了一个约束,以确保为每个板分配 1 种且仅 1 种材料.根据模型中的其他约束,您可能/可能不需要这个,但它是防止虚假答案的良好保证.这也是for each"的一个例子.pyomo 中使用函数-规则组合的约束样式.

Many other variations of constraints are possible here, but the ones I added answer your question about conductivity in aggregate. Note that I have also added a constraint to ensure that 1 and only 1 material is assigned to each plate. You may/may not need this depending on other constraints in your model, but it is good insurance against bogus answers. This is also an example of the "for every" style of constraint using the function - rule combo in pyomo.

结果……铝和奶酪三明治……:)

The result... an aluminum and cheese sandwich... :)

# material selection model

import pyomo.environ as pyo

# data
materials = ['steel', 'alum', 'carbon', 'cheese']

density =   {   'steel' : 1.2,
                'alum'  : 0.8,
                'carbon': 1.8,
                'cheese': 0.7}

conductivity = {'steel' : 40.8,
                'alum'  : 30.1,
                'carbon': 42.4,
                'cheese': 15.3}

price =     {   'steel' : 2.3,
                'alum'  : 3.5,
                'carbon': 5.8,
                'cheese': 6.0}

                  # t     area
plate_dims = {  1: (10,   150), 
                2: (12.5, 200),
                3: (8,    125)}

mdl = pyo.ConcreteModel('material selector')

# SETS (used to index the decision variable and the parameters)
mdl.M = pyo.Set(initialize=materials)
mdl.P = pyo.Set(initialize=plate_dims.keys())

# VARIABLES
mdl.x = pyo.Var(mdl.M, mdl.P, domain=pyo.Binary)  # select material M for plate P

# PARAMETERS
mdl.density =       pyo.Param(mdl.M, initialize=density)
mdl.conductivity =  pyo.Param(mdl.M, initialize=conductivity)
mdl.price =         pyo.Param(mdl.M, initialize=price)
mdl.p_thickness =   pyo.Param(mdl.P, initialize= {k:v[0] for k,v in plate_dims.items()})
mdl.p_area =        pyo.Param(mdl.P, initialize= {k:v[1] for k,v in plate_dims.items()})

# OBJ (minimize total density)
mdl.obj = pyo.Objective(expr=sum(mdl.x[m, p] * mdl.p_thickness[p] 
                        * mdl.p_area[p] * mdl.density[m] 
                        for m in mdl.M for p in mdl.P))

# CONSTRAINTS
# minimum conductivity
mdl.c1 = pyo.Constraint(expr=sum(mdl.x[m, p] * mdl.conductivity[m]/mdl.p_thickness[p]
                        for m in mdl.M for p in mdl.P) >= 5.0)

# must populate all plates with 1 material
def c2(model, plate):
    return sum(mdl.x[m, plate] for m in mdl.M) == 1
mdl.c2 = pyo.Constraint(mdl.P, rule=c2)

# solve it
solver = pyo.SolverFactory('glpk')
result = solver.solve(mdl)
mdl.display()

产量:

Model material selector

  Variables:
    x : Size=12, Index=x_index
        Key           : Lower : Value : Upper : Fixed : Stale : Domain
          ('alum', 1) :     0 :   0.0 :     1 : False : False : Binary
          ('alum', 2) :     0 :   0.0 :     1 : False : False : Binary
          ('alum', 3) :     0 :   1.0 :     1 : False : False : Binary
        ('carbon', 1) :     0 :   0.0 :     1 : False : False : Binary
        ('carbon', 2) :     0 :   0.0 :     1 : False : False : Binary
        ('carbon', 3) :     0 :   0.0 :     1 : False : False : Binary
        ('cheese', 1) :     0 :   1.0 :     1 : False : False : Binary
        ('cheese', 2) :     0 :   1.0 :     1 : False : False : Binary
        ('cheese', 3) :     0 :   0.0 :     1 : False : False : Binary
         ('steel', 1) :     0 :   0.0 :     1 : False : False : Binary
         ('steel', 2) :     0 :   0.0 :     1 : False : False : Binary
         ('steel', 3) :     0 :   0.0 :     1 : False : False : Binary

  Objectives:
    obj : Size=1, Index=None, Active=True
        Key  : Active : Value
        None :   True : 3600.0

  Constraints:
    c1 : Size=1
        Key  : Lower : Body              : Upper
        None :   5.0 : 6.516500000000001 :  None
    c2 : Size=3
        Key : Lower : Body : Upper
          1 :   1.0 :  1.0 :   1.0
          2 :   1.0 :  1.0 :   1.0
          3 :   1.0 :  1.0 :   1.0

这篇关于PYOMO:使用集合和参数定义数据集以解决优化问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆