PYOMO: Defining dataset using Sets and Parameters for solving an optimization problem

二次信任 提交于 2020-12-12 05:40:47

问题


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

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

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}

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

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

So, when the solver chooses a density value for a plate, it must also choose the conductivity value of the same material.

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.


回答1:


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

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.

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()

Yields:

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


来源:https://stackoverflow.com/questions/65201147/pyomo-defining-dataset-using-sets-and-parameters-for-solving-an-optimization-pr

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!