如何用Gurobi求解优化问题并读取Excel?模型写法是否正确?
从Excel读数据用Gurobi求解线性优化问题的完整方案
第一步:先理清楚Excel数据对应关系
你说A列有9个单元格存了数字,刚好对应你问题里的A矩阵(3×2共6个元素)和b向量(3个元素):
- A列前6个单元格:按行放A矩阵的元素,也就是
4,5,6,7,8,9(对应A=[[4,5],[6,7],[8,9]]) - A列后3个单元格:放b向量的元素
5,10,15(对应b=[5,10,15]) - 至于C向量
[1,-2],如果要从Excel读,可以加个B列放前两个单元格;如果是固定值,直接写代码里就行,下面给两种方案。
第二步:完整代码实现(Python)
先确保装了需要的包:
pip install gurobipy pandas openpyxl
可直接运行的代码
import pandas as pd import gurobipy as gp from gurobipy import GRB # 1. 读Excel数据 # 假设你的Excel文件名叫data.xlsx,没有表头 df = pd.read_excel("data.xlsx", usecols="A", header=None) # 把A列数据转成列表 data_list = df[0].tolist() # 拆分出A矩阵和b向量 # A是3行2列,取前6个元素按行拆分 A_matrix = [data_list[0:2], data_list[2:4], data_list[4:6]] # b是3个元素,取后3个(列表索引从0开始,所以是6到8) b_vector = data_list[6:9] # 处理C向量:二选一 # 方案1:从Excel的B列前两个单元格读 # df_c = pd.read_excel("data.xlsx", usecols="B", header=None) # c_vector = df_c[0].tolist()[:2] # 方案2:直接用你给的固定值 c_vector = [1, -2] # 2. 创建Gurobi模型 opt_model = gp.Model("max_cTx") # 3. 定义决策变量x:2个变量,x>=0 x_vars = opt_model.addVars(2, lb=0, name="x") # 4. 设置目标函数:最大化C^T x opt_model.setObjective( gp.quicksum(c_vector[i] * x_vars[i] for i in range(2)), GRB.MAXIMIZE ) # 5. 添加约束:Ax <= b for row_idx in range(3): opt_model.addConstr( gp.quicksum(A_matrix[row_idx][col_idx] * x_vars[col_idx] for col_idx in range(2)) <= b_vector[row_idx], name=f"constraint_{row_idx+1}" ) # 6. 启动求解 opt_model.optimize() # 7. 输出结果 if opt_model.status == GRB.OPTIMAL: print("找到最优解:") for var in x_vars: print(f"x[{var}] = {x_vars[var].X}") print(f"最优目标值:{opt_model.objVal}") else: print(f"求解状态:{opt_model.status}")
第三步:检查你现有代码的常见坑
如果你已经写了部分代码,看看有没有这些问题:
- Excel读取错了:要注意Python列表索引从0开始,别把Excel的行号和代码里的索引搞混,比如Excel的第7行对应列表的第6个元素
- 变量没设下限:x>=0的约束必须通过
lb=0设置,不然Gurobi会允许变量取负值 - 目标函数方向搞反:你要的是最大化,必须写
GRB.MAXIMIZE,写成GRB.MINIMIZE就完全错了 - 约束行列搞混:Ax<=b要逐行构建,别把A矩阵的行和列弄反,比如第一行约束是4x0+5x1<=5
- 忘了调用求解:必须运行
opt_model.optimize()才会开始计算,光定义模型没用
验证结果对不对
这个问题的最优解可以手动算:目标函数是Max x0 -2x1,x1的系数是负的,所以要让x1尽可能小(取0),此时x0最大是5/4=1.25,目标值是1.25。运行代码应该得到这个结果,说明模型是对的。
内容的提问来源于stack exchange,提问作者lbarros
相关产品推荐
相关产品推荐

