英文:
Updating constraint set rhs in docplex
问题
我尝试在docplex中的while循环下迭代更新约束的右侧,但它无法正常工作。通过分析输出文本文件,我发现虽然有些约束按照我希望的方式更新了,但其他一些没有。
z_bar是一个包含y+1个元素的列表,并在每次迭代时进行更新。我想要更改右侧的约束集包括(x+1)*(y+1)个约束。z_bar与j指数相关,但由于每个约束涉及i和j指数,我必须更新它们全部。你认为我做错了什么?
原始约束集:
for i in range(1, x + 1):
for j in range(1, y + 1):
sub_cbd.add_constraint(x_cbd[i, j] <= z_bar[j], ctname='constraint_name{0}{1}'.format(i, j))
尝试更新约束集的右侧:
for i in range(1, x + 1):
for j in range(1, y + 1):
sub_cbd.get_constraint_by_name('constraint_name{0}{1}'.format(i, j)).rhs = z_bar[j]
对于更新后的z_bar:[0, 0, 0, 0, 1, 1, 0...0],总共15个元素,两个1和13个0。
现在的情况:
constraint11: x_1_1 <= 0
constraint12: x_1_2 <= 0
constraint13: x_1_3 <= 0
constraint14: x_1_4 <= 0
constraint15: x_1_5 <= 1
constraint16: x_1_6 <= 1
constraint17: x_1_7 <= 0
constraint18: x_1_8 <= 0
constraint19: x_1_9 <= 0
constraint110: x_1_10 <= 0
constraint111: x_1_11 <= 1
constraint112: x_1_12 <= 1
constraint113: x_1_13 <= 1
constraint114: x_1_14 <= 1
constraint115: x_1_15 <= 1
constraint21: x_2_1 <= 0
constraint22: x_2_2 <= 0
constraint23: x_2_3 <= 0
constraint24: x_2_4 <= 0
constraint25: x_2_5 <= 1
constraint26: x_2_6 <= 1
constraint27: x_2_7 <= 0
constraint28: x_2_8 <= 0
constraint29: x_2_9 <= 0
constraint210: x_2_10 <= 0
constraint211: x_2_11 <= 1
constraint212: x_2_12 <= 1
constraint213: x_2_13 <= 1
constraint214: x_2_14 <= 1
constraint215: x_2_15 <= 1
应该如何看起来:
constraint11: x_1_1 <= 0
constraint12: x_1_2 <= 0
constraint13: x_1_3 <= 0
constraint14: x_1_4 <= 0
constraint15: x_1_5 <= 1
constraint16: x_1_6 <= 1
constraint17: x_1_7 <= 0
constraint18: x_1_8 <= 0
constraint19: x_1_9 <= 0
constraint110: x_1_10 <= 0
constraint111: x_1_11 <= 0
constraint112: x_1_12 <= 0
constraint113: x_1_13 <= 0
constraint114: x_1_14 <= 0
constraint115: x_1_15 <= 0
constraint21: x_2_1 <= 0
constraint22: x_2_2 <= 0
constraint23: x_2_3 <= 0
constraint24: x_2_4 <= 0
constraint25: x_2_5 <= 1
constraint26: x_2_6 <= 1
constraint27: x_2_7 <= 0
constraint28: x_2_8 <= 0
constraint29: x_2_9 <= 0
constraint210: x_2_10 <= 0
constraint211: x_2_11 <= 0
constraint212: x_2_12 <= 0
constraint213: x_2_13 <= 0
constraint214: x_2_14 <= 0
constraint215: x_2_15 <= 0
英文:
I am trying to update the rhs of a constraint iteratively under a while loop in docplex, however, it does not work properly. As I analyze the output text file, while some constraints are updated as I want, others are not.
z_bar is a list consists of y+1 elements and is updated at each iteration. Constraint set I want to change the RHS of consists of (x+1)*(y+1) constraints. z_bar is related to the j indice, however since each constraint involves i and j indices, I have to update all. What do you think I am doing wrong?
Original constraint set:
for i in range(1, x + 1):
for j in range(1, y + 1):
sub_cbd.add_constraint(x_cbd[i, j] <= z_bar[j], ctname='constraint_name{0}{1}'.format(i, j))
Updating constraint set rhs attempt:
for i in range(1, x + 1):
for j in range(1, y + 1):
sub_cbd.get_constraint_by_name('constraint_name{0}{1}'.format(i, j)).rhs = z_bar[j]
For the updated z_bar: [0, 0, 0, 0, 1, 1, 0...0], 15 elements in total, two 1s and 13 0s.
How it looks now:
constraint11: x_1_1 <= 0
constraint12: x_1_2 <= 0
constraint13: x_1_3 <= 0
constraint14: x_1_4 <= 0
constraint15: x_1_5 <= 1
constraint16: x_1_6 <= 1
constraint17: x_1_7 <= 0
constraint18: x_1_8 <= 0
constraint19: x_1_9 <= 0
constraint110: x_1_10 <= 0
constraint111: x_1_11 <= 1
constraint112: x_1_12 <= 1
constraint113: x_1_13 <= 1
constraint114: x_1_14 <= 1
constraint115: x_1_15 <= 1
constraint21: x_2_1 <= 0
constraint22: x_2_2 <= 0
constraint23: x_2_3 <= 0
constraint24: x_2_4 <= 0
constraint25: x_2_5 <= 1
constraint26: x_2_6 <= 1
constraint27: x_2_7 <= 0
constraint28: x_2_8 <= 0
constraint29: x_2_9 <= 0
constraint210: x_2_10 <= 0
constraint211: x_2_11 <= 1
constraint212: x_2_12 <= 1
constraint213: x_2_13 <= 1
constraint214: x_2_14 <= 1
constraint215: x_2_15 <= 1
How it should look:
constraint11: x_1_1 <= 0
constraint12: x_1_2 <= 0
constraint13: x_1_3 <= 0
constraint14: x_1_4 <= 0
constraint15: x_1_5 <= 1
constraint16: x_1_6 <= 1
constraint17: x_1_7 <= 0
constraint18: x_1_8 <= 0
constraint19: x_1_9 <= 0
constraint110: x_1_10 <= 0
constraint111: x_1_11 <= 0
constraint112: x_1_12 <= 0
constraint113: x_1_13 <= 0
constraint114: x_1_14 <= 0
constraint115: x_1_15 <= 0
constraint21: x_2_1 <= 0
constraint22: x_2_2 <= 0
constraint23: x_2_3 <= 0
constraint24: x_2_4 <= 0
constraint25: x_2_5 <= 1
constraint26: x_2_6 <= 1
constraint27: x_2_7 <= 0
constraint28: x_2_8 <= 0
constraint29: x_2_9 <= 0
constraint210: x_2_10 <= 0
constraint211: x_2_11 <= 0
constraint212: x_2_12 <= 0
constraint213: x_2_13 <= 0
constraint214: x_2_14 <= 0
constraint215: x_2_15 <= 0
答案1
得分: 1
以下是代码的中文翻译部分:
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)
# 现在是350名儿童而不是300名
print()
print("现在是350名儿童而不是300名")
mdl.get_constraint_by_name("kids").rhs = 350;
mdl.solve()
for v in mdl.iter_integer_vars():
print(v, " = ", v.solution_value)
# 不超过4辆40座巴士
print()
print("不超过4辆40座巴士")
mdl.get_var_by_name("nbBus40").ub = 4
mdl.solve()
for v in mdl.iter_integer_vars():
print(v, " = ", v.solution_value)
# 更改目标,使得40座位的成本为450
# 并去掉40座位巴士数量的限制
print()
print("更改目标,使得40座位的成本为450")
print("并去掉40座位巴士数量的限制")
mdl.get_var_by_name("nbBus40").ub = 1000
mdl.set_objective("min", nbbus40*450 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v, " = ", v.solution_value)
然后让我将其转换成一个循环:
from docplex.mp.model import Model
# 原始模型
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
for i in range(0, 10):
mdl.add_constraint(nbbus40*40 + nbbus30*30*i >= 300+i, 'kids'+str(i))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v, " = ", v.solution_value)
# 现在是350名儿童而不是300名
for i in range(0, 10):
mdl.get_constraint_by_name("kids"+str(i)).rhs = 350+i;
mdl.export("zoo.lp")
mdl.solve()
然后在zoo.lp文件中得到以下内容:
Minimize
obj: 500 nbBus40 + 400 nbBus30
Subject To
kids0: 40 nbBus40 >= 350
kids1: 40 nbBus40 + 30 nbBus30 >= 351
kids2: 40 nbBus40 + 60 nbBus30 >= 352
kids3: 40 nbBus40 + 90 nbBus30 >= 353
kids4: 40 nbBus40 + 120 nbBus30 >= 354
kids5: 40 nbBus40 + 150 nbBus30 >= 355
kids6: 40 nbBus40 + 180 nbBus30 >= 356
kids7: 40 nbBus40 + 210 nbBus30 >= 357
kids8: 40 nbBus40 + 240 nbBus30 >= 358
kids9: 40 nbBus40 + 270 nbBus30 >= 359
Bounds
Generals
nbBus40 nbBus30
End
希望这些翻译对您有帮助。
英文:
Full working example in https://github.com/AlexFleischerParis/zoodocplex/blob/master/zooincremental.py
from docplex.mp.model import Model
# original 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)
#now 350 kids instead of 300
print()
print("now 350 kids instead of 300")
mdl.get_constraint_by_name("kids").rhs=350;
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
# no more than 4 buses 40 seats
print()
print("no more than 4 buses 40 seats")
mdl.get_var_by_name("nbBus40").ub=4
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
#change the objective so that cost for 40 seats is 450
#and remove the limit on the number of buses 40 seats
print()
print("change the objective so that cost for 40 seats is 450")
print("and remove the limit on the number of buses 40 seats ")
mdl.get_var_by_name("nbBus40").ub=1000
mdl.set_objective("min",nbbus40*450 + nbbus30*400);
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
Now let me change this into a loop:
from docplex.mp.model import Model
# original model
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
for i in range(0,10):
mdl.add_constraint(nbbus40*40 + nbbus30*30*i >= 300+i,'kids'+str(i))
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
#now 350 kids instead of 300
for i in range(0,10):
mdl.get_constraint_by_name("kids"+str(i)).rhs=350+i;
mdl.export("zoo.lp")
mdl.solve()
and then in zoo.lp I get
Minimize
obj: 500 nbBus40 + 400 nbBus30
Subject To
kids0: 40 nbBus40 >= 350
kids1: 40 nbBus40 + 30 nbBus30 >= 351
kids2: 40 nbBus40 + 60 nbBus30 >= 352
kids3: 40 nbBus40 + 90 nbBus30 >= 353
kids4: 40 nbBus40 + 120 nbBus30 >= 354
kids5: 40 nbBus40 + 150 nbBus30 >= 355
kids6: 40 nbBus40 + 180 nbBus30 >= 356
kids7: 40 nbBus40 + 210 nbBus30 >= 357
kids8: 40 nbBus40 + 240 nbBus30 >= 358
kids9: 40 nbBus40 + 270 nbBus30 >= 359
Bounds
Generals
nbBus40 nbBus30
End
答案2
得分: 0
以下是翻译好的部分:
我尝试使用以下代码,似乎可以工作。请您更新它以显示问题。
N = 2
M = 15
m = Model()
xs = m.continuous_var_matrix(N, M, name=lambda ij: f"x{ij[0]+1}{ij[1]+1}")
right = [33] * M
for i in range(N):
for j in range(M):
m.add_constraint(xs[i, j ] <= right[j], f"K{i+1}{j+1}")
print(m.lp_string)
zbar = [0] * M
zbar[1] = 1
zbar[2] = 2
for i in range(N):
for j in range(M):
ct = m.get_constraint_by_name(f"K{i+1}{j+1}")
assert ct is not None
ct.rhs = zbar[j]
print(m.lp_string)
作为一个附注,我本来会在变量名称中使用分隔符,以避免名称重复,尽管在您的情况下似乎不会发生这种情况。然而,对于一个方阵,x111 是不明确的,可以是 (1,11) 或 (11,1)。请注意,DOcplex 可以为您生成非模糊的名称;如果我将 `x` 传递给 `continuous_var_matrix`,DOcplex 将为所有 (i,j) 对生成诸如 x_i_j 这样的名称。
英文:
I tried with the following code, which seems to work. Please can you update it so that it shows the issue.
N = 2
M = 15
m = Model()
xs = m.continuous_var_matrix(N, M, name=lambda ij: f"x{ij[0]+1}{ij[1]+1}")
right = [33] * M
for i in range(N):
for j in range(M):
m.add_constraint(xs[i, j ] <= right[j], f"K{i+1}{j+1}")
print(m.lp_string)
zbar = [0] * M
zbar[1] = 1
zbar[2] = 2
for i in range(N):
for j in range(M):
ct = m.get_constraint_by_name(f"K{i+1}{j+1}")
assert ct is not None
ct.rhs = zbar[j]
print(m.lp_string)
As a side remark, I would have used separators in the variable names, to avoid name duplicates, though this does not seem to happen in your case.
However, for a square matrix x111 is ambiguous, can be (1,11) or (11,1).
Note that DOcplex can generate non_ambiguous names for you; if I had passed x
to continuous_var_matrix
, DOcplex will have generated names such as x_i_j for all (i,j) pairs.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论