1. 大M法怎么将非线性问题线性化
大M法? - 知乎
2. Gurobi 中添加数据
我认为你对n的定义没有问题。尽管如此,我还是重写了您的代码,使其更简洁易懂。首先,我们创建给定的集合和常量:
from gurobipy import Model, GRB, quicksum
import numpy as np
m = Model()
demo_coords = np.random.uniform(0, 100, size=(50, 2)) # Just for demonstration
# Sets and Constants
demand = [f"i{k}" for k in range(1, 51)]
facilities = [ f"facility{k}" for k in range(1, 11) ]
dloc = {fac : demo_coords[i] for i, fac in enumerate(demand)}
maxdist = 40
M = 10e6
请注意,dloc是一个字典,因此dloc[i]将为您提供坐标 对于需求点i,则dloc[i][0]是x坐标,dloc[i][1]是 y坐标。在
现在我们可以创建变量并将它们存储在gurobi tubledict:
^{pr2}$
使用m.addConstrs(),约束可以写成
# Constraints
m.addConstrs(((dloc[i][0] - floc[j, 0]) * (dloc[i][0] - floc[j, 0])
+ (dloc[i][1] - floc[j, 1])*(dloc[i][1] - floc[j, 1])
<= maxdist**2 + M * (1 - assign[i, j])
for i in demand for j in facilities), name="distance")
m.addConstrs((quicksum(assign[i, j] for j in facilities) == 1
for i in demand), name="assignDemand")
m.addConstrs((assign[i, j] <= isopen[j] for i in demand for j in facilities),
name="closed")
m.addConstr(n == quicksum(isopen[j] for j in facilities), name="numFacilities")
# zip is needed to iterate over all pairs of consecutive facilites
m.addConstrs((isopen[j] >= isopen[jp1]
for j, jp1 in zip(facilities, facilities[1:])), name="order")
请注意,虽然在距离约束中写入floc[j, 0]不是问题,但不能编写dloc[i, 0],因为dloc是一个python字典,floc是tupledict。在
设置目标函数并调用m.optimize()
# Objective
m.setObjective(n, sense=GRB.MINIMIZE)
m.optimize()
if m.status == GRB.OPTIMAL:
print(f"Optimal Solution is: {m.objVal}")
print(" ")
for var in m.getVars():
print(var.varName, var.X)
给出了最优解n=3。
在Gurobi中添加大小为n的二进制变量 - 问答 - Python中文网
3. Gurobi 添加约束的方式
首先需要添加z作为二进制变量:
z = m.addVars(I, J, vtype=GRB.BINARY, name="z")
然后需要约束来确保z[i, j] = 1当且仅当c[i, j] <= 150。 一种方法是使用指示符约束:
这相当于
c > 150 -> z = 0 c < 150 -> z = 1
添加如下:
m.addConstrs((z[i, j] == 1) >> (c[i][j] <= 150) for i in I for j in J) m.addConstrs((z[i, j] == 0) >> (c[i][j] >= 150) for i in I for j in J)
您也可以自己显式地建模: 如果在c[i][j] - 150的值上有上下界M和{}(即M >= c[i][j] - 150 >= m表示所有i, j),则可以使用以下约束:
M * (1-z) >= c - 150 m * z <= c - 150
如果c > 150,则两个不等式的右边都是正的。第一个强制1 - z = 1,因此{}。第二个不等式将得到满足。在
如果c < 150,则右侧为负数。第一个不等式变得微不足道,而第二个不等式则强制z = 1。在
对于M,c中的最大条目就可以了,对于m,如果所有c[i][j]都是非负的,则可以选择-150。在
按如下方式添加这些约束:
m.addConstrs( M * (1 - z[i, j]) >= c[i][j] - 150 for i in I for j in J ) m.addConstrs( m * z[i,j] <= c[i][j] - 150 for i in I for j in J )
注意,我忽略了c = 150的情况。这是因为对于浮点数,等式总是被认为是在公差范围内满足的,因此没有简单的方法来区分严格和非严格的不等式。你可以用epsilon来近似,例如:
z = 0 -> c >= 150 + epsilon
在Gurobi中添加二进制变量 - 问答 - Python中文网
4. Gurobi 中文网站,可以下载资料
学习资料-Gurobi 中国



