gurobi是由美国Gurobi公司开发的新一代大规模数学规划优化器,在 Decision Tree for Optimization Software 网站举行的第三方优化器评估中,展示出更快的优化速度和精度,成为优化器领域的新翘楚。
通过一个简单的整数规划实例,感受一下gurobi的魅力。

本文中仅仅展示了一个最简单的整数规划实例 . 如果您想进一步了解gurobi的相关操作 , 可以下载

下载链接简介
经典TSP问题求解包含了gurobi求解和粒子群算法求解
MDVRP多车场车辆路径规划求解与论文中的遗传算法求解结果对比
列生成算法求解航班人员调度包含了问题说明、数据、详细的gurobi列生成算法求解代码
gurobi生产计划调度案例_生产切换生产调度中的生产切换问题
gurobi生产计划调度案例_装配计划生产调度中的装配计划问题
gurobi的数值双层规划问题求解双层规划数值问题求解

均有完整的python代码 . 非常不错的学习资料!

一. 问题描述

题目图片中缺少一个约束条件——每部电影至少放映一次。

题目

二. 建立模型

变量

其中 x i j k x_{ijk} xijk为01变量, 表示时段 i i i在影厅 j j j是否放映电影 k k k

参数

r a t e i k rate_{ik} rateik 为时段 i i i电影 k k k的上座率
a l l j k all_{jk} alljk为电影 k k k在影厅 j j j满座时的收益

约束条件

s t . st. st.
约束1: 每部电影至少放映一次
∑ i ∈ I , j ∈ J x i j k ≥ 1 , ∀ k ∈ K \sum_{i\in I,j\in J}x_{ijk}\geq 1,\forall k\in K iI,jJxijk1,kK
约束2: 每个影厅每个时段只能放映一部电影
∑ k ∈ K x i j k = 1 , ∀ i ∈ I , ∀ j ∈ J \sum_{k\in K}x_{ijk}= 1,\forall i\in I,\forall j\in J kKxijk=1,iI,jJ

目标函数

目标函数: 全天收益最大
m a x ( ∑ i ∈ I , j ∈ J , k ∈ K x i j k ∗ r a t e i k ∗ a l l j k ) max(\sum_{i\in I,j\in J,k\in K}x_{ijk}*rate_{ik}*all_{jk}) max(iI,jJ,kKxijkrateikalljk)

三.代码

from gurobipy import *
# 8部电影
# 7个影厅
# 8个时段
I = list(range(8))  # 时段
J = list(range(7))  # 影厅
K = list(range(8))  # 电影

seat_j = [118, 86, 116, 85, 156, 142, 156]
# 一行为一个影厅,一列为一部电影
price_jk = [[60, 60, 65, 60, 65, 90, 60, 65],
            [65, 65, 85, 75, 60, 75, 85, 80],
            [60, 70, 75, 80, 75, 80, 80, 75],
            [65, 65, 80, 75, 80, 75, 75, 80],
            [60, 65, 65, 60, 75, 80, 80, 75],
            [60, 65, 65, 80, 75, 75, 80, 75],
            [60, 60, 75, 80, 75, 70, 60, 75]]
# 一行为一个时段,一列为一部电影
rate_ik = [[0.50, 0.55, 0.45, 0.50, 0.60, 0.46, 0.55, 0.45],
           [0.42, 0.43, 0.41, 0.43, 0.45, 0.30, 0.53, 0.36],
           [0.58, 0.63, 0.67, 0.64, 0.70, 0.64, 0.54, 0.57],
           [0.62, 0.67, 0.70, 0.65, 0.75, 0.64, 0.53, 0.66],
           [0.65, 0.65, 0.73, 0.68, 0.75, 0.74, 0.67, 0.72],
           [0.66, 0.69, 0.78, 0.78, 0.78, 0.75, 0.74, 0.70],
           [0.67, 0.92, 0.87, 0.87, 0.75, 0.59, 0.68, 0.68],
           [0.67, 0.92, 0.87, 0.87, 0.75, 0.59, 0.68, 0.68]]
# 计算满座的票房二维列表,lt_all
all_jk = [[0 for col in K] for row in J]
for j in J:
    for k in K:
        all_jk[j][k] = price_jk[j][k] * seat_j[j]
# 创建模型
m = Model("ass_mov")
# 创建变量.第i个时段在第j个影厅放映第k部电影
x = m.addVars(I, J, K, vtype=GRB.BINARY)
# 更新变量环境
m.update()
# 创建目标函数
m.setObjective(sum(x[i, j, k] * rate_ik[i][k] * all_jk[j][k]
                   for i in I for j in J for k in K),
                   GRB.MAXIMIZE)
# 创建约束条件约束条件
# 每部电影至少放映一次
m.addConstrs(sum(x[i,j,k] for i in I for j in J) >= 1 for k in K) 
# 每个时段每个影厅只能放映一部电影
m.addConstrs(sum(x[i,j,k] for k in K) == 1 for i in I for j in J)
# 求解规划模型
m.optimize()

# 输出结果
result = [[0 for col in J] for row in I]
solution = m.getAttr('x',x)
# 得到排片矩阵
for k,v in solution.items():
    if v == 1:
        result[k[0]][k[1]] = k[2] + 1
# 得到最大收益值
max_get = sum(
    x[i, j, k].x * rate_ik[i][k] * all_jk[j][k] 
    for i in I for j in J for k in K
)
# 打印最大收益值,和排片矩阵
print('最大收益为:',max_get)
print('最佳排片方法:')
print('\n影厅j|', J)
print('-'*28)
for idx,l in enumerate(result) :
    print(f'时段{idx}|',l)

四.求解结果

即可得到排片最优解。
求解结果

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐