【问题标题】:How to solve Gurobi Error Divisor must be a constant如何解决 Gurobi Error Divisor 必须是常数
【发布时间】:2021-09-26 07:18:55
【问题描述】:
from gurobipy import *
import pandas as p
import numpy as np
d={
   (1,1):2,(1,2):3,(1,3):3,(1,4):5,
   (2,1):2,(2,2):3,(2,3):3,(2,4):5,
   (3,1):2,(3,2):3,(3,3):3,(3,4):5,
   (4,1):2,(4,2):3,(4,3):3,(4,4):5,
   (5,1):2,(5,2):3,(5,3):3,(5,4):5,
}
P,p=multidict({1:1,2:1,3:2,4:2,5:2})
W,w=multidict({1:2,2:2,3:2,4:2})
D=100
total_p=sum([i for i in p.values()])
total_w=sum([j for j in w.values()])
if total_w/total_p<1:
    R= total_w/total_p
else :
    R=1
print(R)
model=Model("keibi optimizer")
x={}
for i in P:
    for j in W:
        x[i,j]=model.addVar(vtype="C",name="x(%s,%s)"%(i,j)) 
model.update()
for j in W:
    model.addConstr(quicksum(x[i,j] for i in P) == w[j],name='Demand(%s)' %j) 
for i in P:
    model.addConstr(quicksum(x[i,j] for j in W) <= p[i],name='Capacity(%s)' %i) 
for i in P:
    for j in W:
        model.addConstr(d[i,j]*x[i,j],"<=",D*x[i,j])  
model.setObjective(quicksum(D-(sum((d[i,j]*x[i,j]/x[i,j]) for j in W if x!=0))for i in P),GRB.MAXIMIZE)
model.optimize()
print("Optimal value:", model.ObjVal/(total_p*D))
for(i,j) in x:
        print("sending quantity %10s from factory %3s to customer %3s" %(x[i,j], j, i)) 

我使用 python gurobi9.12 制作了上述程序。但我无法运行程序。

错误信息

Divisor must be a constant

我猜model.setObjective(quicksum(D-(sum((d[i,j]*x[i,j]/x[i,j]) for j in W if x!=0))for i in P),GRB.MAXIMIZE) 很复杂。

我想用下图中的公式作为目标函数来做一个程序。

我该怎么办?请帮我。

【问题讨论】:

  • 我无法理解写d[i,j]*x[i,j]/x[i,j]之类的东西的原因。
  • 对不起。我错了。Σ_j∈W d[i,j]*x[i,j]/Σj∈W x[i,j]。这是平均距离旅行。
  • Gurobi 无法处理除法。但它可以处理二次项。因为z=x/y 可以写成z*y=x,所以我们状态很好。
  • 谢谢。但是 Σj∈W x[i,j] 是一个二维数组和一个变量。此外,总和的计算也是一个障碍。因此,即使将其更改为乘法,我也无法解决它。你有什么想法吗?
  • 不,y[i] = Σj∈W x[i,j] 的结果实际上是一维的。只需添加额外的变量和约束,并且只使用乘法。

标签: python optimization gurobi


【解决方案1】:

所以让我们关注:Σ_j∈W d[i,j]*x[i,j]/Σj∈W x[i,j]。首先,数学很混乱。我从来没有,曾经有一个超过 j 的总和在一个超过 j 的总和中。我们不知道内部和中的 j 是什么。

我将使用符号:

 sum(j, d[i,j]*x[i,j]/y[i])
 y[i] = sum(j, x[i,j])

为我们的问题。现在我们可以这样做了:

 sum(j, d[i,j]*z[i,j])
 y[i]*z[i,j] = x[i,j]   for all i,j
 y[i] = sum(j, x[i,j])  for all i
 y[i],z[i,j] free variables

如您所见,不再有分裂。请注意,我们在这里引入了非凸二次约束。这有点贵,但比 Gurobi 根本无法处理的除法要好。进一步注意,我们在这里允许y[i]=0(允许乘以零,但不允许除以零)。

一般情况下,如果看到z=x/y,则需要考虑使用x=z*y

【讨论】:

  • 谢谢。我试图解决问题
猜你喜欢
  • 2022-08-03
  • 1970-01-01
  • 2019-09-21
  • 1970-01-01
  • 2020-01-27
  • 2017-11-20
  • 1970-01-01
  • 2021-12-07
  • 2021-05-20
相关资源
最近更新 更多