更新 docplex 中的约束集 rhs。

huangapple go评论56阅读模式
英文:

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] &lt;= z_bar[j], ctname=&#39;constraint_name{0}{1}&#39;.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(&#39;constraint_name{0}{1}&#39;.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 &lt;= 0
 constraint12: x_1_2 &lt;= 0
 constraint13: x_1_3 &lt;= 0
 constraint14: x_1_4 &lt;= 0
 constraint15: x_1_5 &lt;= 1
 constraint16: x_1_6 &lt;= 1
 constraint17: x_1_7 &lt;= 0
 constraint18: x_1_8 &lt;= 0
 constraint19: x_1_9 &lt;= 0
 constraint110: x_1_10 &lt;= 0
 constraint111: x_1_11 &lt;= 1
 constraint112: x_1_12 &lt;= 1
 constraint113: x_1_13 &lt;= 1
 constraint114: x_1_14 &lt;= 1
 constraint115: x_1_15 &lt;= 1
 constraint21: x_2_1 &lt;= 0
 constraint22: x_2_2 &lt;= 0
 constraint23: x_2_3 &lt;= 0
 constraint24: x_2_4 &lt;= 0
 constraint25: x_2_5 &lt;= 1
 constraint26: x_2_6 &lt;= 1
 constraint27: x_2_7 &lt;= 0
 constraint28: x_2_8 &lt;= 0
 constraint29: x_2_9 &lt;= 0
 constraint210: x_2_10 &lt;= 0
 constraint211: x_2_11 &lt;= 1
 constraint212: x_2_12 &lt;= 1
 constraint213: x_2_13 &lt;= 1
 constraint214: x_2_14 &lt;= 1
 constraint215: x_2_15 &lt;= 1

How it should look:

constraint11: x_1_1 &lt;= 0
 constraint12: x_1_2 &lt;= 0
 constraint13: x_1_3 &lt;= 0
 constraint14: x_1_4 &lt;= 0
 constraint15: x_1_5 &lt;= 1
 constraint16: x_1_6 &lt;= 1
 constraint17: x_1_7 &lt;= 0
 constraint18: x_1_8 &lt;= 0
 constraint19: x_1_9 &lt;= 0
 constraint110: x_1_10 &lt;= 0
 constraint111: x_1_11 &lt;= 0
 constraint112: x_1_12 &lt;= 0
 constraint113: x_1_13 &lt;= 0
 constraint114: x_1_14 &lt;= 0
 constraint115: x_1_15 &lt;= 0
 constraint21: x_2_1 &lt;= 0
 constraint22: x_2_2 &lt;= 0
 constraint23: x_2_3 &lt;= 0
 constraint24: x_2_4 &lt;= 0
 constraint25: x_2_5 &lt;= 1
 constraint26: x_2_6 &lt;= 1
 constraint27: x_2_7 &lt;= 0
 constraint28: x_2_8 &lt;= 0
 constraint29: x_2_9 &lt;= 0
 constraint210: x_2_10 &lt;= 0
 constraint211: x_2_11 &lt;= 0
 constraint212: x_2_12 &lt;= 0
 constraint213: x_2_13 &lt;= 0
 constraint214: x_2_14 &lt;= 0
 constraint215: x_2_15 &lt;= 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=&#39;buses&#39;)
nbbus40 = mdl.integer_var(name=&#39;nbBus40&#39;)
nbbus30 = mdl.integer_var(name=&#39;nbBus30&#39;)
mdl.add_constraint(nbbus40*40 + nbbus30*30 &gt;= 300, &#39;kids&#39;)
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v,&quot; = &quot;,v.solution_value)

#now 350 kids instead of 300

print()
print(&quot;now 350 kids instead of 300&quot;)    
    
mdl.get_constraint_by_name(&quot;kids&quot;).rhs=350;
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v,&quot; = &quot;,v.solution_value)

# no more than 4 buses 40 seats

print()
print(&quot;no more than 4 buses 40 seats&quot;)


mdl.get_var_by_name(&quot;nbBus40&quot;).ub=4
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v,&quot; = &quot;,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(&quot;change the objective so that cost for 40 seats is 450&quot;)
print(&quot;and remove the limit on the number of buses 40 seats  &quot;)  
    
mdl.get_var_by_name(&quot;nbBus40&quot;).ub=1000
mdl.set_objective(&quot;min&quot;,nbbus40*450 + nbbus30*400);
mdl.solve()

for v in mdl.iter_integer_vars():
    print(v,&quot; = &quot;,v.solution_value)

Now let me change this into a loop:

from docplex.mp.model import Model

# original model

mdl = Model(name=&#39;buses&#39;)
nbbus40 = mdl.integer_var(name=&#39;nbBus40&#39;)
nbbus30 = mdl.integer_var(name=&#39;nbBus30&#39;)
for i in range(0,10):
   mdl.add_constraint(nbbus40*40 + nbbus30*30*i &gt;= 300+i,&#39;kids&#39;+str(i))
   
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v,&quot; = &quot;,v.solution_value)

#now 350 kids instead of 300

for i in range(0,10):    
   mdl.get_constraint_by_name(&quot;kids&quot;+str(i)).rhs=350+i;
   mdl.export(&quot;zoo.lp&quot;)
mdl.solve()

and then in zoo.lp I get

Minimize
 obj: 500 nbBus40 + 400 nbBus30
Subject To
 kids0: 40 nbBus40 &gt;= 350
 kids1: 40 nbBus40 + 30 nbBus30 &gt;= 351
 kids2: 40 nbBus40 + 60 nbBus30 &gt;= 352
 kids3: 40 nbBus40 + 90 nbBus30 &gt;= 353
 kids4: 40 nbBus40 + 120 nbBus30 &gt;= 354
 kids5: 40 nbBus40 + 150 nbBus30 &gt;= 355
 kids6: 40 nbBus40 + 180 nbBus30 &gt;= 356
 kids7: 40 nbBus40 + 210 nbBus30 &gt;= 357
 kids8: 40 nbBus40 + 240 nbBus30 &gt;= 358
 kids9: 40 nbBus40 + 270 nbBus30 &gt;= 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&quot;x{ij[0]+1}{ij[1]+1}&quot;)
right = [33] * M

for i in range(N):
    for j in range(M):
        m.add_constraint(xs[i, j ] &lt;= right[j], f&quot;K{i+1}{j+1}&quot;)

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&quot;K{i+1}{j+1}&quot;)
        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.

huangapple
  • 本文由 发表于 2023年2月6日 15:48:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358577.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定