PYOMO:使用集合和参数定义数据集以解决优化问题

2024-09-24 00:33:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图将一些数据转化为优化问题的PYOMO模型

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

每种材料都有两个特性-密度和导电性,其值定义如下

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块矩形板的重量,如下所示:

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

其中,面积_1、厚度_1和密度_1是板1的面积、厚度和密度

每个板的面积和厚度都是固定的。但是密度值取决于解算器为获得最佳结果而选择的材质。该模型还有一个定义如下的约束:

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

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

如果有人能帮我解决这个问题,我将不胜感激。我也欢迎你有不同的想法来解决这个问题。多谢各位


Tags: 模型定义areadensity密度算器材料steel
1条回答
网友
1楼 · 发布于 2024-09-24 00:33:30

下面是一个我认为符合您所有问题的示例模型

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

这里还有许多其他的约束条件,但我添加的这些约束条件回答了您关于骨料导电性的问题。请注意,我还添加了一个约束,以确保为每个板指定1种且仅指定1种材质。根据模型中的其他约束条件,您可能需要/可能不需要此选项,但它可以很好地防止虚假答案。这也是使用pyomo中的函数-规则组合的“for-every”约束样式的一个示例

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

# 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

相关问题 更多 >