![](/img/trans.png)
[英]How can I add objective for scheduling model to count the present decision variables to be specific value using CPlex Python?
[英]Can I add kpi with maximum values without contraining CPLEX model?
我正在使用 cplex 進行優化 model,以優化飲食成分。 現在我想添加一個額外的變量/KPI,它是 model 中其他 KPI 的總和。 但是,這個總和是一個有最大值的分數,這意味着當每個KPI超過某個上限時,總和不應該考慮超過這個值的值。 分數只是每種食物成分的衡量標准,因此,上限不是 model 的限制,而只是計算分數的限制,因此不應影響 model 結果。 最后,我想最小化總分。
我嘗試使用 mdl.sum 將其添加以對每個指標求和並將它們添加到列表中,然后如果超出上限,我嘗試將總和替換為另一個列表的值。 請參見下面的示例:
# Decision variables, limited to be >= Food.qmin and <= Food.qmax
ftype = mdl.integer_vartype if ints else mdl.continuous_vartype
qty = mdl.var_dict(foods, ftype, lb=lambda f: f.qmin,ub=lambda f: f.qmax, name=lambda f:
"q_%s" % f.name)
# Limit range of nutrients, and mark them as KPIs
for c in constraints:
amount = mdl.sum(qty[f] * food_constraints[f.name, c.name] for f in foods)
mdl.add_range(c.qmin, amount, c.qmax)
mdl.add_kpi(amount, publish_name="Total %s" % c.name)
# add sum of indicators with max values:
score1 = mdl.sum(qty[f] * f.veg for f in foods)
score2 = mdl.sum(qty[f] * f.fruit for f in foods)
score3 = mdl.sum(qty[f] * f.fish for f in foods)
# add sum of indicators without max values:
score4 = mdl.sum(qty[f] * f.sugar for f in foods)
score5 = mdl.sum(qty[f] * f.fats for f in foods)
Score_sum_A = [score1, score2, score3]
max_scores = [10.6, 3.3, 9.7]
# cap values of Score_sum_A to max scores:
for i in range(len(max_scores)):
if Score_sum_A[i] >= max_scores[i]:
Score_sum_A[i] = max_scores[i]
else:
Score_sum_A[i] = Score_sum_A[i]
Score_sum_B = [score4, score5]
total_score_sum = sum(Score_sum_A + Score_sum_B)
mdl.add_kpi(total_score_sum , 'Total food score')
mdl.minimize(total_score_sum)
但是,在運行 model 時,我收到錯誤:“TypeError:無法將線性約束轉換為 boolean 值”,這是因為 if 語句。 因此,model 似乎無法使用 model 內的這種 if 語句進行操作。
有誰知道,是否可以在 cplex 中添加這樣一個具有最大值的指標,而不限制 model 結果?
任何提示將不勝感激。
謝謝
你不能寫
if Score_sum_A[i] >= max_scores[i]:
Score_sum_A[i] = max_scores[i]
因為 Score_sum_A 不是常數。 你應該使用最大值
from docplex.mp.model import Model
mdl = Model(name='buses')
nbKids=300;
buses=[30,40,50]
#decision variables
mdl.nbBus = {b: mdl.integer_var(name="nbBus"+str(b)) for b in buses}
# Constraint
mdl.add_constraint(sum(mdl.nbBus[b]*b for b in buses) >= nbKids, 'kids')
# Objective
# logical constraint is the max of all nbBus
mdl.minimize(mdl.max(mdl.nbBus[b] for b in buses))
mdl.solve(log_output=True,)
mdl.export("c:\\temp\\buses.lp")
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
或來自 docplex 的if_then
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
print()
print("with if nb buses 40 more than 3 then nbBuses30 more than 7")
#if then constraint
mdl.add(mdl.if_then(nbbus40>=3,nbbus30>=7))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
如果我稍微改變https://ibmdecisionoptimization.github.io/docplex-doc/mp/diet.html
從
def nb_products(mdl_, s_):
qvs = mdl_.find_matching_vars(pattern="q_")
return sum(1 for qv in qvs if s_[qv] >= 1e-5)
mdl.add_kpi(nb_products, 'Nb foods')
至
def nb_products(mdl_, s_):
qvs = mdl_.find_matching_vars(pattern="q_")
return sum(1 for qv in qvs if s_[qv] >= 1e-5)
def nb_products_capped(mdl_, s_):
qvs = mdl_.find_matching_vars(pattern="q_")
return mdl_.min(3,sum(1 for qv in qvs if s_[qv] >= 1e-5))
mdl.add_kpi(nb_products, 'Nb foods')
mdl.add_kpi(nb_products_capped,'Nb foods capped to 3')
然后我會得到
* KPI: Nb foods = 5.000000
* KPI: Nb foods capped to 3 = 3.000000
在像zookpi這樣的小例子中
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
nbbus=nbbus30+nbbus40
mdl.add_kpi(nbbus,"nbbus")
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve(log_output=True,)
mdl.export("c:\\temp\\buses.lp")
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
for k in mdl.iter_kpis():
print(k," = ",k.solution_value)
添加
mdl.add_kpi(mdl.min(nbbus,3),"nbbuscapped3")
會給
nbBus40 = 6.0
nbBus30 = 2.0
DecisionKPI(name=nbbus,expr=nbBus40+nbBus30) = 8.0
DecisionKPI(name=nbbuscapped3,expr=min(nbBus40+nbBus30,3)) = 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.