在pyomo中

时间:2019-06-05 14:39:25

标签: python python-3.x pyomo

我正在尝试设计一个优化器,该优化器根据一些预定义的参数来选择要出售的产品。唯一的限制是要出售的最大产品数量和产品之间的某些依存关系(如果您出售产品B,则必须出售产品D f.e.)。我在定义后一个约束时遇到问题。

下面是问题的简化版本:

import numpy as np 
from pyomo import environ as pe    

## define articles
article_list=('A','B','C','D')

## and their values ("sales")
alphas=(0,1,2,3)
alphas_input=dict(zip(article_list,alphas))


## generate compatibility matrix, 1 means article pair is dependant
compatibilities=dict(
    ((article_a,article_b),0)
    for article_a in article_list
    for article_b in article_list
)

## manually assign compatibilities so that 
## every product is dependant on itself and D and B are dependant on each other
comp_arr=[1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,1]
compatibilities=dict(zip(compatibilities.keys(),comp_arr))

## indices: articles
model_exp.article_list = pe.Set(
    initialize=article_list)

定义模型

## create model
model_exp = pe.ConcreteModel()

## parameters: fixed values
model_exp.alphas=pe.Param(
    model_exp.article_list,
    initialize=alphas_input,
    within=pe.Reals)

model_exp.compatibilities=pe.Param(
    model_exp.article_list*model_exp.article_list,
    initialize=compatibilities,
    within=pe.Binary
)


## variables: selected articles -> 0/1 values
model_exp.assignments=pe.Var(
    model_exp.article_list,
    domain=pe.Binary
)


## objective function
model_exp.objective=pe.Objective(
    expr=pe.summation(model_exp.alphas,model_exp.assignments),
    sense=pe.maximize
)

定义约束

def limit_number_articles(model):
    n_products_assigned=sum(
        model_exp.assignments[article]
        for article in model.article_list
        )
    return n_products_assigned<=2

model_exp.limit_number_articles=pe.Constraint(
    rule=limit_number_articles
)

现在有问题的约束。没有此约束,优化器将选择C和D作为这两篇文章,因为它们具有较高的alpha。但是由于我已将D和B定义为相互依赖,因此我需要优化器选择它们两者,或者都不选择它们(因为它们的alpha值高于A和C,因此最佳解决方案是选择它们)。 / p>

这是我最需要定义的约束条件

def control_compatibilities(model,article_A):
    sum_list=[]
    #loopo over article pairs
    for article_loop in model_exp.article_list:
        # check whether the article pair is dependant
        if model_exp.compatibilities[article_A,article_loop]==1:
            # sum the amount of articles among the pair that are included
            # if none are (0) or both are (2) return True
            sum_list.append(sum([model_exp.assignments[article_A]==1,
                model_exp.assignments[article_loop]==1]) in [0,2])
        else:
            #if they are not dependant, no restruction applies
            sum_list.append(True)

    sum_assignments=sum(sum_list)

    return sum_assignments==4


model_exp.control_compatibilities=pe.Constraint(
    model_exp.article_list,
    rule=control_compatibilities
)

上面的约束返回以下错误:

Invalid constraint expression. The constraint expression resolved to a 
trivial Boolean (True) instead of a Pyomo object. Please modify your rule to 
return Constraint.Feasible instead of True.

任何有关如何定义约束的想法都会很有帮助。

2 个答案:

答案 0 :(得分:0)

查看一些有关对逻辑约束和二进制变量含义进行建模的资源。快速的Google搜索产生了以下资源,这些资源应指导您制定有效的公式:

a good book

http://ben-israel.rutgers.edu/386/Logic.pdf

答案 1 :(得分:0)

我解决了它从另一项(0-0 = 0和1-1 = 0)中减去一项的选择,并遍历所有相关产品对的问题。

def control_compatibilities(model,article_A):
    compatible_pairs=[k for k,v in compatibilities.items() if v==1]
    compatible_pairs_filt=[a for a in compatible_pairs if a[0]==article_A]
    sum_assignments=sum(model_exp.assignments[a[0]]-model_exp.assignments[a[1]]
    for a in compatible_pairs_filt)
    return sum_assignments==0

model_exp.control_compatibilities=pe.Constraint(
    model_exp.article_list,
    rule=control_compatibilities
)