无法解决整数线性规划最小化问题求助(附Spyder运行失败代码)
搞定整数线性规划最小化问题的正确姿势
兄弟,你用scipy.optimize.linprog失败完全在情理之中——这个函数只支持连续变量的线性规划求解,压根没法处理整数变量的约束。要解决整数线性规划(ILP)问题,得用专门的工具才行,我给你推荐两个实用的方案,都是业内常用的:
方案一:用PuLP(简单易上手,开源免费)
PuLP是专门做线性规划/整数规划的Python库,语法直观,新手也能快速上手。
第一步:先装库
打开终端跑这个命令:
pip install pulp
第二步:改写你的代码
我把你的问题适配成PuLP的格式了,记得把你没写完的约束矩阵A和对应的右侧向量b补全(你原来的代码里A没写完):
from pulp import LpProblem, LpMinimize, LpVariable, lpSum # 目标函数系数(和你原来的一致) c = [2, 3, 4, 6, 7, 5, 7, 8, 9, 9, 8, 9] # 约束矩阵A——把你没写完的行补在这里! A = [ [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0], [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1], [1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1], [0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0], # 这里补你剩下的约束行 ] # 约束右侧的b向量——替换成你实际的数值,长度要和A的行数一致! b = [b1, b2, b3, b4, b5, b6, b7, b8, ...] # 创建最小化问题实例 prob = LpProblem("ILP_Minimization_Problem", LpMinimize) # 创建12个非负整数变量(如果是0-1变量,把cat改成'Binary'就行) x = [LpVariable(f"x{i+1}", lowBound=0, cat='Integer') for i in range(12)] # 添加目标函数:最小化c·x prob += lpSum([c[i] * x[i] for i in range(12)]), "Total_Cost" # 添加约束条件:A·x ≤ b for i in range(len(A)): prob += lpSum([A[i][j] * x[j] for j in range(12)]) <= b[i], f"Constraint_{i+1}" # 求解问题(PuLP默认用开源的CBC求解器,足够应付大多数中小规模问题) prob.solve() # 输出结果 print(f"求解状态: {prob.status}") print(f"最优目标值: {prob.objective.value()}") print("最优变量取值:") for var in x: print(f"{var.name}: {var.value()}")
方案二:用scipy的milp函数(适合坚持用scipy生态的同学)
如果你不想装新库,而且你的scipy版本在1.9.0及以上,可以用scipy.optimize.milp——这个函数专门支持混合整数线性规划。代码示例如下:
from scipy.optimize import milp, LinearConstraint import numpy as np c = np.array([2, 3, 4, 6, 7, 5, 7, 8, 9, 9, 8, 9]) # 补全你的约束矩阵A A = np.array([ [1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0], [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0], [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1], [1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1], [0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0], # 补全剩余约束行 ]) # 补全约束右侧的b向量 b = np.array([b1, b2, b3, b4, b5, b6, b7, b8, ...]) # 定义约束:A·x ≤ b constraints = LinearConstraint(A, lb=-np.inf, ub=b) # 指定所有变量都是整数(如果只有部分变量是整数,这里对应位置设为True即可) integrality = np.ones_like(c, dtype=bool) # 求解,变量默认非负 res = milp(c=c, constraints=constraints, integrality=integrality, bounds=(0, None)) print(f"最优目标值: {res.fun}") print(f"最优变量取值: {res.x}") print(f"求解状态: {res.message}")
关键提示
- 不管用哪个方案,一定要把你没写完的
A矩阵和b向量补全,否则约束不完整,求解结果肯定不对。 - 如果你的问题规模很大,PuLP的CBC求解器速度不够,可以考虑用商业求解器比如Gurobi或CPLEX(需要授权,但学术用途免费)。
内容的提问来源于stack exchange,提问作者Jirattapong
相关产品推荐
相关产品推荐

