在Gurobi中添加大小为n的二进制变量

2024-05-23 18:35:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试在Gurobi(Python接口)中实现一个设施位置优化模型。我翻译这个模型有些困难。数学模型如下:

enter image description here

其中,dloc、floc是需求(客户)和设施(仓库)位置的(x,y)坐标。dloc的量是常数(即50),而floc是决策变量:这些由解算器计算。另外,x,y坐标是介于0和100之间的浮点数。在

其中一个关键问题是我不知道如何添加facility变量,它的数量可以是0到n之间的任意值

目前我的代码:

from gurobipy import *
import numpy as np
import math


def distance(a, b):
    dx = a[0] - b[0]
    dy = a[1] - b[1]
    return math.sqrt(dx ** 2 + dy ** 2)

customer = np.random.uniform(0,100,[50,2])
print(customer)

m = Model()

n = m.addVar(lb=0.0, ub=GRB.INFINITY,vtype=GRB.INTEGER) #number of candidate facilities

facility={}
for j in range(n):
    facility[j] = m.addVar(vtype=GRB.BINARY, name="facility%d" % j) #certainly this is not correct, as an error is reported as 'Var' object cannot be interpreted as an integer

floc = ? 

因此,我尝试了另一种方法,手动设置固定数量的候选设施作为临时解决方案:

^{pr2}$

任何人都可以用古罗比来演示模型的翻译,这将是一个很大的帮助。在


Tags: 模型import数量asnpmathcustomer设施
1条回答
网友
1楼 · 发布于 2024-05-23 18:35:52

我认为你对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。在

相关问题 更多 >