簡體   English   中英

如何基於 CPLEX 上的其他兩個約束實現新約束?

[英]How to implement a new constraint based on two other constraints on CPLEX?

我對 Cplex 很陌生。 我有這兩個約束(R 是 20 范圍內的數字集):

        model.add_constraints((model.sum(x[i, j] for j in R2 ) == 2 for i in R),"C1" )
        model.add_constraints((x[i, n1-4] ==x[i, n1-2]  for i in R ),"C2" )

我需要計算同時滿足 C1 和 C2 的數量,然后定義一個新的約束,上面寫着“至少有 10 個我同時滿足 C1 和 C2”

我怎樣才能用 cplex 做到這一點?

讓我給你舉一個動物園例子中的例子

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

在 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 ,而不是 Python sum以避免性能問題。

在下面的代碼中,我創建了兩個包含 100 個整數變量的列表,xi 和 xj。

然后我定義了一個邏輯和約束ctands列表,當 xi[k]>=3 和 yi[k]>=5 時為真。

然后我發布這些邏輯約束的總和正好等於 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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM