问题
Brief background : I am trying to solve an optimization problem where I need to select the best store from where an order can be fulfilled. For this illustration I have 2 orders (O1, O2) and 3 stores (str_1, str_2, str_3). While selecting the best store to fulfill an order, there are 4 factors : A, B, C and D. So for fulfilling order 1, each store will have 4 set of scores corresponding to each factor. Score will be between 0 and 1.
I need to determine the optimal weights for 4 factors (wtA, wtB, wtC, wtD - decision variables) such that sumproduct of weights and the score is maximum. (Weights should be between 0 and 100). For instance, say if we check if store 1 can service order 1, then 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
I am having difficulty in storing the above sumproduct for 6 options : O1-str_1; O1-str_2 ; O1-str_3 ; O2-str_1 ; O2-str_2 ; O2-str_3
I have written some code, but I am stuck at the above point. I am new to stackoverflow and pyomo, any help is highly appreciated
Please see the below code to see what I have done and where I am stuck:
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)
What I expect is model.x2 decison variable (6 of them for each order store combination) to hold the corresponding sumproduct of the optimal weights (model.x1) and the scores (defined in the data - order_str_scores)
I am getting the below error :
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]
I want to hold the sumproduct and then use it further .. e.g. x2[O1,str_1] == 0.88*x1[A] + 0.85*x1[B] + 0.88*x1[C] + 0.93*x1[D] etc..
Then the idea is to pick the maximum of the sumproduct for each order. So for order 1 I will have 3 sumproducts (for each store) and then I will pick the maximum amongst them..but right now I am unable to hold them in a variable..
Thank you!
来源:https://stackoverflow.com/questions/58445375/python-pyomo-how-and-where-to-store-sumproduct-involving-decision-variables-1