目标:熟悉 Gurobi Python API (gurobipy),掌握连续变量的定义、线性目标函数和线性约束的添加,并成功求解一个基础 LP 模型。

🎯 第 1 日目标

任务目标 核心概念 预期产出
I. 环境设置 Python API (gurobipy) 导入与环境创建。 成功运行第一个 Gurobi Python 脚本。
II. 模型核心组件 变量定义 (addVar)、目标函数 (setObjective)、线性约束 (addConstr)。 一个完整的、可求解的线性规划(LP)模型。
III. 求解与结果读取 调用 optimize(),获取结果属性(.objVal.X)。 求解器返回 Optimal 状态,并打印最优解。

💡 任务 I & II & III:构建和求解基础 LP 模型

我们将以一个典型的生产计划问题作为入门案例:

最大化利润:

max⁡x+y+2z\max \quad x + y + 2zmaxx+y+2z

受限于:

x+2y+3z≤4(资源容量)x+y≥1(最低生产要求)x,y,z≥0(连续非负变量)\begin{aligned} x + 2y + 3z &\le 4 \quad & \text{(资源容量)} \\ x + y &\ge 1 \quad & \text{(最低生产要求)} \\ x, y, z &\ge 0 \quad & \text{(连续非负变量)}\end{aligned}x+2y+3zx+yx,y,z410(资源容量)(最低生产要求)(连续非负变量)

💻 完整 Python 代码示例

以下是使用 gurobipy 构建和求解上述模型的完整脚本。

import gurobipy as gp  
from gurobipy import GRB  
  
# --- I. 模型创建 ---# 创建一个名为 "Day1_LP_Production_Plan" 的新模型  
m = gp.Model("Day1_LP_Production_Plan")  
  
# --- II. 变量定义 ---# 定义连续非负变量 x, y, z (默认 vtype=GRB.CONTINUOUS, lb=0.0)x = m.addVar(name="x_product")  
y = m.addVar(name="y_product")  
z = m.addVar(name="z_product")  
  
# --- III. 设定目标函数 ---# 设置目标函数:最大化 x + y + 2zm.setObjective(x + y + 2*z, GRB.MAXIMIZE)  
  
# --- IV. 添加约束 ---# 约束 1: 资源容量限制: x + 2y + 3z <= 4  
m.addConstr(x + 2*y + 3*z <= 4, "c1_capacity")  
  
# 约束 2: 最低生产要求: x + y >= 1  
m.addConstr(x + y >= 1, "c2_min_requirement")  
  
# --- V. 优化模型 ---m.optimize()  
  
# --- VI. 结果读取 ---# 检查求解状态是否为最优 (GRB.OPTIMAL)if m.status == GRB.OPTIMAL:  
    print(f"\n--- ✅ 求解成功 ---")  
    # 获取并打印最优目标值 (.objVal 属性)  
    print(f"最优利润 (Objective Value): {m.objVal:.4f}")  
    # 获取并打印变量值 (.X 属性)  
    print(f"变量 x 的最优值: {x.X:.4f}")  
    print(f"变量 y 的最优值: {y.X:.4f}")  
    print(f"变量 z 的最优值: {z.X:.4f}")  
elif m.status == GRB.INFEASIBLE:  
    print("模型不可行 (Infeasible)")  
else:  
    print(f"未找到最优解。状态代码: {m.status}")

✨ 关键 API 概念总结

Gurobi API/属性 描述 目的
import gurobipy as gp Gurobi Python API 的标准导入方式。 允许通过 gp. 前缀访问所有 Gurobi 功能。
from gurobipy import GRB 导入 Gurobi 的所有常量,如 GRB.MAXIMIZE 简化代码,提高可读性。
gp.Model(name) 创建一个新的模型对象。 优化问题的所有变量、约束和目标函数的容器。
m.addVar(name="x") 向模型中添加单个决策变量。 默认创建连续、非负 (lb=0) 的变量。
m.setObjective(expr, sense) 设定模型的优化目标。 sense 可以是 GRB.MAXIMIZEGRB.MINIMIZE
m.addConstr(lhs <= rhs, name) 向模型中添加约束。 允许使用标准的 Python 运算符 (<=, >=, ==)。
m.optimize() 调用 Gurobi 求解器开始优化。 启动求解过程。
var.X 求解后,读取该变量的最优值。 获取数值结果。
m.objVal 求解后,读取目标函数的最优值。 获取目标函数的数值结果。
# 允许取负值(无下界)
u = m.addVar(lb=-GRB.INFINITY, name="u_unbounded")

# 指定为整数变量
k = m.addVar(vtype=GRB.INTEGER, name="k_integer")

# 显式指定下界和上界
w = m.addVar(lb=0.0, ub=10.0, name="w_bounded")
  • 每个 m.addVar(...) 会在模型中创建一个变量实例,返回一个变量对象.
  • name="x_product" 只是给变量取个可读的名字,便于调试和查看解时识别。
  • Model.addVar 的默认参数有 lb=0.0(下界为 0)和 vtype=GRB.CONTINUOUS,所以不显式指定时得到的是连续且下界为 0 的变量(即非负连续变量)。物理意义上常用于表示产量、数量等不能为负的量
   # 约束 1: 资源容量限制: x + 2y + 3z <= 4
   m.addConstr(x + 2*y + 3*z <= 4, "c1_capacity")

   # 约束 2: 最低生产要求: x + y >= 1
   m.addConstr(x + y >= 1, "c2_min_requirement")
  • 调试与诊断:通常定义约束时会为约束命名,这样求不可行时生成的 IIS(最小不可行子集)会用名字标出,便于定位问题。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐