Python Gurobi为可忽略的约束生成不同的解决方案

Python Gurobi为可忽略的约束生成不同的解决方案,python,linear-programming,gurobi,Python,Linear Programming,Gurobi,我试图将不同产品的单元分配到不同的商店。由于本玩具示例中不存在但在全面实现中是必需的原因,我需要一个二进制变量,用于指示是否将特定产品的任何单元分配给每个特定商店。 因为这是一个玩具示例,所以该变量在其当前实现中本质上是“附带现象”——即,它由通知我的目标函数的变量定义/约束,但它不会对任何其他内容产生任何影响。我假设,正因为如此,无论我如何定义这个变量,古洛比都会以完全相同的方式求解。然而,情况并非如此。每次,代码都会运行并生成MIPs范围内的解决方案。但解决方案的目标值在数值上是不同的。此外

我试图将不同产品的单元分配到不同的商店。由于本玩具示例中不存在但在全面实现中是必需的原因,我需要一个二进制变量,用于指示是否将特定产品的任何单元分配给每个特定商店。 因为这是一个玩具示例,所以该变量在其当前实现中本质上是“附带现象”——即,它由通知我的目标函数的变量定义/约束,但它不会对任何其他内容产生任何影响。我假设,正因为如此,无论我如何定义这个变量,古洛比都会以完全相同的方式求解。然而,情况并非如此。每次,代码都会运行并生成MIPs范围内的解决方案。但解决方案的目标值在数值上是不同的。此外,结果看起来在质量上有所不同,一些解决方案将大量产品分配给商店,而其他解决方案则将产品数量在所有商店中严重分割。 为什么会这样?古洛比是如何实现这一点的,以至于我遇到了这个问题?有解决办法吗

我使用的是Python3.5.5 64位和gurobi 7.0.2

# each entry is the number of units of that item in that store
x = [] 
for i in prod_range:
    x.append([])
    for j in loc_range:
        x[i].append( GRBmodel.addVar(vtype=GRB.INTEGER, obj=1, name='x_{}_{}'.format(i,j)) )
        var_name_list.append('x_{}_{}'.format(i,j))
    x[i].append( GRBmodel.addVar(vtype=GRB.INTEGER, obj=0, name='x_{}_{}'.format(i,j+1)) ) # the last loc is "unallocated" and incurs no revenue nor cost
    var_name_list.append('x_{}_{}'.format(i,j+1))
    GRBmodel.addConstr( x[i][j] >= 0, "constraint_0.{}_{}".format(i,j) )

# binary mask version of x
# should be 1 if there's any amount of that product in that store
y = []
for i in prod_range:
    y.append([])
    for j in loc_range:
        y[i].append( GRBmodel.addVar(vtype=GRB.BINARY, name='y_{}_{}'.format(i,j)) )
        var_name_list.append('y_{}_{}'.format(i,j))

GRBmodel.modelSense = GRB.MAXIMIZE

# all items assigned to some locations, including the "unallocated" loc
for i in prod_range: 
    GRBmodel.addConstr( sum(x[i][j] for j in loc_range) <= units_list[i], "constraint_1.1_{}".format(i) ) # notice in this "<=" way, x[i][unallocated] is free.

# not exceeding storage upper bounds or failing to meet lower bounds for each store
for j in loc_range:
    GRBmodel.addConstr( sum(x[i][j] for i in prod_range) <= max_units_relax * UB_units_list[j], "constraint_1.3_{}".format(j) ) # Update p9
    GRBmodel.addConstr( sum(x[i][j] for i in prod_range) >= LB_units_list[j], "constraint_1.4_{}".format(j) ) 

# test y. not sure why the answer is different when using 0.5 rather than 1
testInt = -10 # placeholder for break point
for i in prod_range:
    for j in loc_range:
        GRBmodel.addGenConstrIndicator( y[i][j], True, x[i][j], GRB.GREATER_EQUAL, 1 ) 
        GRBmodel.addGenConstrIndicator( y[i][j], False, x[i][j], GRB.LESS_EQUAL, 1 ) ```
#每个条目都是该商店中该商品的单位数
x=[]
对于产品范围内的i:
x、 追加([])
对于loc_范围内的j:
x[i].append(GRBmodel.addVar(vtype=GRB.INTEGER,obj=1,name='x_{}}{}.格式(i,j)))
var_name_list.append('x_{}{}'.格式(i,j))
x[i].append(GRBmodel.addVar(vtype=GRB.INTEGER,obj=0,name='x{{}}}{}.format(i,j+1))#最后一个loc是“未分配的”,既不产生收入也不产生成本
var_name_list.append('x_{}{}'.格式(i,j+1))
GRBmodel.addConstr(x[i][j]>=0,“constraint_0.{}{}”.format(i,j))
#x的二进制掩码版本
#如果那家商店里有任何数量的那种产品,应该是1
y=[]
对于产品范围内的i:
y、 追加([])
对于loc_范围内的j:
y[i].append(GRBmodel.addVar(vtype=GRB.BINARY,name='y{}}{}'。格式(i,j)))
var_name_list.append('y_{}{}.format(i,j))
GRBmodel.modelSense=GRB.MAXIMIZE
#分配给某些位置的所有项目,包括“未分配”loc
对于产品范围内的i:

GRBmodel.addConstr(loc_范围内j的和(x[i][j])您描述的是Gurobi和其他MIP解算器的正常行为。它寻找最优解。我们称“最优解”而不是“最优解”,因为在存在多个具有相同目标值的可行解的情况下(甚至是在最优性公差范围内的目标值),没有“最佳解决方案”这样的东西。除了一些重要的例外,Gurobi是确定性的,因为如果您在同一平台上使用相同的库版本运行相同的精确模型,它将给出相同的结果,但即使更改约束的顺序也可能会显著改变结果,只要解具有相似的目标函数值。 甚至在考虑到某些MIP将在合理的时间内解决之前

本例中的“解决方法”是找出您更喜欢的解决方案,量化一个解决方案优于另一个解决方案的原因,然后将其添加到目标函数中