3 回答

TA貢獻1921條經驗 獲得超9個贊
在 Docplex 中,每個線性約束都可以用作一個表達式,其作用類似于布爾變量,如果滿足約束則等于 1,如果不滿足則等于 0。
請注意,當添加到模型時(通過 Mode.add、Model.add_constraint(s)),約束將始終得到滿足。但是,您可以寫:
m.add( (x<=3) + (y>=5) >= 1)
這意味著至少滿足一個(可能是兩個)約束 (x<=3) 和 (y>=5)。
在您的情況下,假設有一個包含 N 個約束 cts[i] 的數組,則編寫:
m.add( m.sum(cts) >= 10)
您還可以在目標中使用這樣的表達式:
m.maximize(m.sum(cts))
將最大化滿足約束的數量
將確保其中至少 10 人滿意
注意:始終使用Model.sum
,而不是 Pythonsum
以避免性能問題。

TA貢獻1797條經驗 獲得超6個贊
讓我舉一個動物園里的例子
from docplex.mp.model import Model
# Data
Buses=[
? ? (40,500),
? ? (30,400),
? ? (35,450),
? ? (20,300)
? ? ]
nbKids=300
# Indexes
busSize=0;
busCost=1;
for b in Buses:
? ? print("buses with ",b[busSize]," seats cost ",b[busCost])
mdl = Model(name='buses')
#decision variables
mdl.nbBus=mdl.integer_var_dict(Buses,name="nbBus")
# Constraint
mdl.add_constraint(sum(mdl.nbBus[b]*b[busSize] for b in Buses) >= nbKids, 'kids')
# Objective
mdl.minimize(sum(mdl.nbBus[b]*b[busCost] for b in Buses))
mdl.solve()
# Display solution
for b in Buses:
? ? print(mdl.nbBus[b].solution_value," buses with ",b[busSize]," seats");
#Add a constraint
# Number of sizes where we have 1 or 2 buses should be at least 3
mdl.add(mdl.sum(mdl.logical_and(1<=mdl.nbBus[b],mdl.nbBus[b]<=2) for b in Buses) >=3)
mdl.solve()
# Display solution
for b in Buses:
? ? print(mdl.nbBus[b].solution_value," buses with ",b[busSize]," seats");
這使
buses with? 40? seats cost? 500
buses with? 30? seats cost? 400
buses with? 35? seats cost? 450
buses with? 20? seats cost? 300
5.0? buses with? 40? seats
1.0? buses with? 30? seats
2.0? buses with? 35? seats
0? buses with? 20? seats
4.0? buses with? 40? seats
1.0? buses with? 30? seats
2.0? buses with? 35? seats
2.0? buses with? 20? seats

TA貢獻1802條經驗 獲得超4個贊
在以下代碼中,我創建了兩個包含 100 個整數變量的列表 xi 和 xj。
然后,我定義一個邏輯和約束列表ctands,當 xi[k]>=3 且 yi[k]>=5 時為 true。
然后我發布這些邏輯約束的總和恰好等于 10,這意味著必須滿足其中的 10 個,因為任何約束都可以用作二進制變量,滿足時等于 1。
目標是最小化 xi 和 xj 的總和,因此結果如預期為 10 * 3 + 10*5 = 80
m = Model()
xi = m.integer_var_list(100, ub=10, name='xi')
xj = m.integer_var_list(100, ub=11, name='xj')
ctands = [((xi[k]>=3) + (xj[k]>=5)==2) for k in range(100)]
# version with logical_and
# ctands = [mdl.logical_and((xi[k]>=3), (xj[k]>=5)==2)) for k in range(100)]
#state that exactly 10 ands are true: the value of an and is 1 when true, 0 when false
m.add(m.sum(ctands) == 10)
# this minimize pulls xs and ys variables to 0
m.minimize(m.sum(xi) + m.sum(xj))
m.solve()
m.print_solution()
添加回答
舉報