Python调用Gurobi:简单案例
Python调用Gurobi:Assignment Problem简单案例
原文链接:https://blog.csdn.net/HsinglukLiu/article/details/107827469
1. Assignment Problem Model
我们考虑一个打车订单分配问题,假设有一个乘客rider
集合
R
R
R,一个司机driver
的集合
D
D
D, 我们考虑顾客数量和司机数量相等的情况,来将顾客和司机进行一对一的匹配,这个问题可以建模为一个整数规划Integer Programming
,但是这个问题非常特殊,将binary constraints
松弛掉,依然存在整数最优解。模型如下:
max ∑ ( i , j ) ∈ A x i j p i j ∑ i x i j = 1 , ∀ j ∈ D ∑ j x i j = 1 , ∀ i ∈ R x i j ∈ { 0 , 1 } , ∀ i ∈ R , j ∈ D \max \sum_{\left( i,j \right) \in A}{x_{ij}p_{ij}} \\ \sum_i{x_{ij}}=1, \qquad \forall j\in D \\ \sum_j{x_{ij}}=1, \qquad \forall i\in R \\ x_{ij}\in \left\{ 0,1 \right\} , \qquad \forall i\in R,j\in D max(i,j)∈A∑xijpiji∑xij=1,∀j∈Dj∑xij=1,∀i∈Rxij∈{0,1},∀i∈R,j∈D
首先我们生成一个profit矩阵,也就是两两匹配的收益矩阵
from gurobipy import *
import pandas as pd
import numpy as np
import random
# generate matching value matrix
order_num = 20
profit_matrix = np.zeros((order_num, order_num))
for i in range(order_num):
for j in range(order_num):
if(i == j):
profit_matrix[i][j] = 0
else:
random.seed(i * order_num + j)
profit_matrix[i][j] = round(10 * random.random(), 1)
profit_matrix
P = pd.DataFrame(profit_matrix)
P
具体如下:
Python调用Gurobi建模求解Assignment Problem
我们用python
调用gurobi
建立上述模型,并直接调用gurobi
的算法进行求解,结果如下:
注:这里主要用到的函数有:
model.addVar(lb, ub, vtype, name)
expr.addTerms(coef, var)
model.addConstr()
model.setObjective(expr, GRB.MAXIMIZE)
model.write('model.lp')
model.optimize()
model.getVars()
var.varName
var.x
等常用函数,其中model
是gurobipy.Model
类型的对象,var
是gurobipy.Var
类的对象,
gurobipy.Var
的x
属性表示变量var
在当前求得的结果中的具体值。
当然还涉及到下面几个类:
LinExpr
类: 用来构建线性表达式gurobipy.Model
类,用来构建model
对象
# construct model object
model = Model('Assignment_Problem')
# introduce decision variable by cycling
x = [[[] for i in range(order_num)] for j in range(order_num)]
for i in range(order_num):
for j in range(order_num):
x[i][j] = model.addVar(lb = 0
,ub = 1
,vtype = GRB.CONTINUOUS # decision variable type
,name = "x_" + str(i) + "_" + str(j)
)
# x[i][j] = model.addVar(vtype = GRB.BINARY # decision variable type
# ,name = "x_" + str(i) + "_" + str(j)
# )
# objective function
obj = LinExpr(0)
for i in range(order_num):
for j in range(order_num):
obj.addTerms(profit_matrix[i][j], x[i][j])
model.setObjective(obj, GRB.MAXIMIZE)
# Constraint 1
for j in range(order_num):
expr = LinExpr(0)
for i in range(order_num):
expr.addTerms(1, x[i][j])
model.addConstr(expr == 1, name="D_" + str(i))
# Constraint 2
for i in range(order_num):
expr = LinExpr(0)
for j in range(order_num):
expr.addTerms(1, x[i][j])
model.addConstr(expr == 1, name="R_" + str(i))
# solve the constructed model
model.write('model.lp')
model.optimize()
# print optimal solution
for var in model.getVars():
if(var.x > 0):
print(var.varName, '\t', var.x)
输出结果如下:
可以看到,即使把变量 x i j 的 类 型 由 x_{ij}的类型由 xij的类型由
GRB.BIINARY
改变成GRB.CONTINOUS
,最优解仍然是整数解
Warning: linear constraint 0 and linear constraint 1 have the same name "D_19"
Gurobi Optimizer version 9.0.1 build v9.0.1rc0 (win64)
Optimize a model with 40 rows, 400 columns and 800 nonzeros
Model fingerprint: 0x4f6b3c13
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [1e-01, 1e+01]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 1e+00]
Presolve time: 0.01s
Presolved: 40 rows, 400 columns, 800 nonzeros
Iteration Objective Primal Inf. Dual Inf. Time
0 1.8840000e+02 1.500000e+01 0.000000e+00 0s
9 1.8650000e+02 0.000000e+00 0.000000e+00 0s
Solved in 9 iterations and 0.01 seconds
Optimal objective 1.865000000e+02
x_0_15 1.0
x_1_0 1.0
x_2_16 1.0
x_3_10 1.0
x_4_13 1.0
x_5_19 1.0
x_6_4 1.0
x_7_12 1.0
x_8_18 1.0
x_9_5 1.0
x_10_17 1.0
x_11_8 1.0
x_12_3 1.0
x_13_6 1.0
x_14_9 1.0
x_15_2 1.0
x_16_7 1.0
x_17_11 1.0
x_18_1 1.0
x_19_14 1.0
作者:刘兴禄,清华大学,清华伯克利深圳学院,博士在读
联系方式:hsinglul@163.com
博客主页:https://blog.csdn.net/HsinglukLiu/article/details/107848461
OlittleRer
运小筹公众号是致力于分享运筹优化(LP、MIP、NLP、随机规划、鲁棒优化)、凸优化、强化学习等研究领域的内容以及涉及到的算法的代码实现。编程语言和工具包括Java、Python、Matlab、CPLEX、Gurobi、SCIP 等。
关注我们: 运筹小公众号
也欢迎广大同行投稿!欢迎大家关注我们的公众号“运小筹”以及粉丝群!
微信群:
QQ群:
QQ群里有我们共享的一些书籍、论文、算例等资料,欢迎大家加入。