Python调用Gurobi:Assignment Problem简单案例

Python调用Gurobi:Assignment Problem简单案例

1. Assignment Problem Model

我们考虑一个打车订单分配问题,假设有一个乘客rider集合 R R ,一个司机driver的集合 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

首先我们生成一个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
    等常用函数,其中modelgurobipy.Model类型的对象,vargurobipy.Var类的对象,
    gurobipy.Varx属性表示变量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 optinal solution 
for var in model.getVars():
    if(var.x > 0):
        print(var.varName, '\t', var.x)  

输出结果如下:

可以看到,即使把变量 x i j x_{ij}的类型由 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

猜你喜欢

转载自blog.csdn.net/HsinglukLiu/article/details/107827469