Python pyomo:如何以及在何处存储涉及决策变量(一维数组)和固定数据(矩阵)的求和积

时间:2019-10-18 06:49:08

标签: pyomo

背景简介:我正在尝试解决一个优化问题,我需要从中选择可以执行订单的最佳商店。在此示例中,我有2个订单(O1,O2)和3个商店(str_1,str_2,str_3)。 在选择最佳商店满足订单时,有4个因素:A,B,C和D。因此,对于满足订单1的情况,每个商店将具有与每个因素相对应的4组分数。得分在0到1之间。

我需要确定4个因子(wtA,wtB,wtC,wtD-决策变量)的最佳权重,以使权重和得分的总和最大。 (权重应在0到100之间)。例如,假设我们检查商店1是否可以为订单1服务,则sumproduct = wtA * score_O1_str_1_A + wtB * score_O1_str_1_B + wtC * score_O1_str_1_C + wtD * score_O1_str_1_D

我很难为6个选项存储以上sumproduct:O1-str_1; O1-str_2; O1-str_3; O2-str_1; O2-str_2; O2-str_3

我已经写了一些代码,但是我被卡在了上面。我是stackoverflow和pyomo的新手,非常感谢您的帮助

请参见下面的代码,以查看我的工作以及卡住的地方:

from pyomo.environ import *

model = ConcreteModel(name="(weights)")

# scores for factors A, B, C and D for each order and store combination
order_str_scores = {
('O1', 'str_1') : [0.88, 0.85, 0.88, 0.93], # if order 1 is fulfilled from store 2 then these are the scores
('O1', 'str_2'): [0.93, 0.91, 0.95, 0.86],
('O1', 'str_3') : [0.83, 0.83, 0.87, 0.9],
('O2', 'str_1') : [0.85, 0.86, 0.84, 0.98],
('O2', 'str_2') : [0.87, 0.8, 0.85, 0.87],
('O2', 'str_3') : [0.91, 0.87, 0.95, 0.83],
}

model.orders = list(set([i[0] for i in order_str_scores.keys()]))
model.stores = list(set([i[1] for i in order_str_scores.keys()]))

# 4 factors (A, B, C & D) whose scores are mentioned in 'order_str_wts' dictionary. These will be indices for decision variables
model.factors = ['A', 'B', 'C','D']

# below 4 decision variables (one for each factor) will hold the optimal number between 0 - 100

def dv_bounds(m, i):
    return (0, 100)
model.x1 = Var(model.factors, within=NonNegativeReals, bounds=dv_bounds)

#Sum of these 4 decision variables should be equal to 100
def sum_wts(m):
   return sum(m.x1[i] for i in model.factors) == 100
model.sum_wts = Constraint(rule=sum_wts)

# BELOW IS WHERE I AM FACING THE PROBLEM :
# here i want to store the sumproduct of decision variables - model.x1 and scores from order_str_scores
# for e.g. if O1 is fulfilled by Store 1 then = 0.88*model.x1['A'] + 0.85*model.x1['B'] + 0.88*model.x1['C'] + 0.93*model.x1['D']
# similarly for the remaining 5 options - O1 -> S2 ; O1 -> S3 ; O2 -> S1 ; O2 -> S2 ; O3 -> S3

model.x2 = Var(model.orders, model.stores, within=NonNegativeReals)

def sum_product(m,i,j):
    return m.x2[i,j] == sum(m.x1[n] * order_str_scores[i,j][q] for n,q in zip(model.factors,range(4)))
model.sum_product = Var(model.orders,model.stores, rule=sum_product)


# THIS IS WHAT I WILL DO LATER, IF ABOVE GETS RESOLVED:
# then for each order, I want to store the maximum score
model.x3 = Var(model.orders, within=NonNegativeReals, bounds=dv_bounds)

model.cons = ConstraintList()
for i in model.orders:
    for j in model.stores:
        model.cons.add(model.x3[i] >= model.x2[i,j])

# I want to maximize the sum of the maximum score I get for each order
def obj_rule(m):
    return sum(m.x3[i] for i in model.orders)

model.obj = Objective(rule=obj_rule, sense=maximize)


我期望的是model.x2决策变量(每个订单存储组合有6个决策变量),以保存相应的最佳权重(model.x1)和得分(在数据中定义-order_str_scores)

我遇到以下错误:

ERROR: evaluating object as numeric value: x2[O1,str_1]
(object: <class 'pyomo.core.base.var._GeneralVarData'>)
No value for uninitialized NumericValue object x2[O1,str_1]
ERROR: evaluating object as numeric value: x2[O1,str_1]  ==  0.88*x1[A] +
0.85*x1[B] + 0.88*x1[C] + 0.93*x1[D]
(object: <class 'pyomo.core.expr.logical_expr.EqualityExpression'>)
No value for uninitialized NumericValue object x2[O1,str_1]
ERROR: Constructing component 'sum_product' from data=None failed: ValueError:
No value for uninitialized NumericValue object x2[O1,str_1]

我想保留sumproduct,然后进一步使用它。例如 x2 [O1,str_1] == 0.88 * x1 [A] + 0.85 * x1 [B] + 0.88 * x1 [C] + 0.93 * x1 [D] 等等。

然后,该想法是为每个订单选择总和的最大值。因此,对于订单1,我将有3个sumproduct(每个商店),然后从中选择最大值。但是现在我无法将它们保存在变量中。

谢谢!

0 个答案:

没有答案