在 pyomo 中同时约束或都不约束
Constraint with both or neither in 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 定义为相互依赖,我需要优化器选择它们两者或 none (因为它们具有比 A 和 C 更高的 alpha,最佳解决方案是选择他们)。
这是我最接近定义所需约束的时间:
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
)
以上约束returns出现以下错误:
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.
关于如何定义约束的任何想法都将非常有帮助。
查看一些有关建模逻辑约束和二元变量含义的资源。快速 google 搜索产生了以下资源,这些资源应该会指导您找到有效的公式:
我通过从另一个项目(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
)
我正在尝试设计一个优化器,它根据一些预定义的参数来选择要销售的产品。唯一的限制是要销售的产品的最大数量和产品之间的一些依赖关系(如果你销售产品 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 定义为相互依赖,我需要优化器选择它们两者或 none (因为它们具有比 A 和 C 更高的 alpha,最佳解决方案是选择他们)。
这是我最接近定义所需约束的时间:
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
)
以上约束returns出现以下错误:
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.
关于如何定义约束的任何想法都将非常有帮助。
查看一些有关建模逻辑约束和二元变量含义的资源。快速 google 搜索产生了以下资源,这些资源应该会指导您找到有效的公式:
我通过从另一个项目(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
)