利用python处理整数规划问题


(例题和部分解答思路来自清风老师)

pulp库

linprog库主要用于处理线性规划问题,对于整数规划问题,可以使用pulp库进行处理。
导入模块

import pulp

模块功能
PuLP 是一个用于线性规划和整数规划的 Python 库,旨在简化建模和求解线性优化问题。它提供了一个简单且直观的接口,可以与多种求解器(如 CBC、GLPK、CPLEX、Gurobi 等)配合使用。

主要函数
①LpProblem
LpProblem 是创建线性规划问题的主要类。

LpProblem(name, sense)

name: 问题的名称(字符串)。
sense: 优化的目标,使用 LpMinimize(最小化)或 LpMaximize(最大化)。

②LpVariable
LpVariable 用于定义模型中的决策变量。

LpVariable(name, lowBound=None, upBound=None, cat='Continuous')

name: 变量的名称(字符串)。
lowBound: 变量的下界(可选)。
upBound: 变量的上界(可选)。
cat: 变量的类型,可以是 ‘Continuous’(连续)、‘Integer’(整数)、‘Binary’(二进制)等

可以看出,pulp库可用于解决线性规划、整数规划以及0-1规划问题

③ lpSum
lpSum 是一个用于创建线性表达式的函数,通常用于构造目标函数和约束。

lpSum([expr1, expr2, ...])

接受一个可迭代对象,包含线性表达式(如变量、常数或表达式的组合)。
示例:设置问题的目标函数和约束函数(其中objective、constraint都是表达式,+=添加这些表达式)

# 目标函数
objective = pulp.lpSum(prices[i] * vars[i] for i in range(10))
model += objective

# 约束条件
constraint = pulp.lpSum(weights[i] * vars[i] for i in range(10)) <= 30
model += constraint

④solve
solve 方法用于求解定义的线性规划问题。

problem.solve()

在调用 solve 方法后,可以使用以下属性来获取优化结果:
①LpStatus:
用于获取求解状态的描述(如 “Optimal”, “Infeasible”, “Unbounded”, 等)。

from pulp import LpStatus
print("状态:", LpStatus[problem.status])

②varValue:每个变量的最优值。

print("x1 =", x1.varValue)
print("x2 =", x2.varValue)

③value:用于获取目标函数的最优值。

from pulp import value
print("目标函数的最优值:", value(problem.objective))

典型例题

例一:背包问题

在这里插入图片描述

建模
在这里插入图片描述

代码

import pulp
import numpy as np
# 创建一个LP问题模型
model = pulp.LpProblem('0-1 Problem', pulp.LpMaximize)

# 定义权重和价格
weights = np.array([6, 3, 4, 5, 1, 2, 3, 5, 4, 2])
prices = np.array([540, 200, 180, 350, 60, 150, 280, 450, 320, 120])

# 定义决策变量
vars = np.zeros(10, dtype=object)
for i in range(10):
    vars[i] = pulp.LpVariable(f'x{i+1}', cat='Binary')

# 打印决策变量
print("决策变量:", vars)

# 目标函数
objective = pulp.lpSum(prices[i] * vars[i] for i in range(10))
model += objective, "Objective Function"

# 约束条件
constraint = pulp.lpSum(weights[i] * vars[i] for i in range(10)) <= 30
model += constraint

# 求解
model.solve()

# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Objective Value:", pulp.value(model.objective))

for i in range(10):
    print(f'x{i+1} = {pulp.value(vars[i])}')

结果

决策变量: [x1 x2 x3 x4 x5 x6 x7 x8 x9 x10]
Status: Optimal
Objective Value: 2410.0
x1 = 1.0
x2 = 1.0
x3 = 0.0
x4 = 1.0
x5 = 0.0
x6 = 1.0
x7 = 1.0

例二:指派问题

在这里插入图片描述

建模
在这里插入图片描述
在这里插入图片描述

代码(难点:双下标与单下标转化)

import pulp
import numpy as np
#混合泳队员选拔,5名队员
swimmer_times=np.array([[66.8,75.6,87,58.6],[57.2,66,66.4,53],[78,67.8,84.6,59.4],[70,74.2,69.6,57.2],
                      [67.4,71,83.8,62.4]])

# 创建一个LP问题模型
model = pulp.LpProblem('0-1 Problem', pulp.LpMinimize)

# 定义决策变量
vars = np.zeros((5,4), dtype=object)
for i in range(5):
    for j in range(4):
        k=5*i+j
        vars[i,j] = pulp.LpVariable(f'x{i+1}_{j+1}', cat='Binary')

#打印决策变量
print(f'决策变量:{vars}')

# 目标函数
objective = pulp.lpSum(swimmer_times*vars)
model += objective

#约束条件
#每个项目都要有1人游
for i in range(4):
    constraint1=pulp.lpSum(np.ones(5)*vars[:,i]) == 1
    model += constraint1
#每个人游0/1个项目
for i in range(5):
    constraint2=pulp.lpSum(np.ones(4)*vars[i]) <= 1
    model+=constraint2

# 求解
model.solve()

# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Objective Value:", pulp.value(model.objective))

for i in range(5):
    for j in range(4):
        if pulp.value(vars[i, j]) == 1:
            print(f'Swimmer_{i+1} will swim in event {j+1} with time {swimmer_times[i, j]}')  

结果

 [x2_1 x2_2 x2_3 x2_4]
 [x3_1 x3_2 x3_3 x3_4]
 [x4_1 x4_2 x4_3 x4_4]
 [x5_1 x5_2 x5_3 x5_4]]
Status: Optimal
Objective Value: 253.20000000000002
Swimmer_1 will swim in event 4 with time 58.6
Swimmer_2 will swim in event 1 with time 57.2
Swimmer_3 will swim in event 2 with time 67.8
Swimmer_4 will swim in event 3 with time 69.6

例三:钢管切割问题

在这里插入图片描述
建模
在这里插入图片描述

代码(难点:双下标与单下标转化)

import numpy as np
import pulp

#6.9m原材料,2.9m、2.1m、1m钢管
cut_ways=[]
for i in range(3):
    for j in range(4):
        for k in range(7):
            if i*2.9+j*2.1+k*1<=6.9 and i*2.9+j*2.1+k*1>=6:
                cut_ways.append([i,j,k])
                print(f'切割方式:2.9m:{i},2.1m:{j},1m:{k}')

#共7种切割方式,因此每种原材料有7种切割方法 

----------------------------------------------------------------------------------------------

#6.9m原材料,2.9m、2.1m、1m钢管
cut_ways=[]
for i in range(3):
    for j in range(4):
        for k in range(7):
            if i*2.9+j*2.1+k*1<=6.9 and i*2.9+j*2.1+k*1>=6:
                cut_ways.append([i,j,k])
                print(f'切割方式:2.9m:{i},2.1m:{j},1m:{k}')

#共7种切割方式,因此每种原材料有7种切割方法

----------------------------------------------------------------------------------------------

#切割方式数组
cut_ways=np.array(cut_ways)
#定义规划模型
model=pulp.LpProblem('钢管切割问题',pulp.LpMinimize)
#定义决策变量
vars=np.zeros(7,dtype='object')
for i in range(7):
    vars[i]=pulp.LpVariable(f'x{i+1}',0,None,cat='Integer')
print(f'决策变量:{vars}')
#定义目标函数
objective=pulp.lpSum(vars)
model+=objective
#定义约束条件
for j in range(3):
    constraint=pulp.lpSum(cut_ways[:,j]*vars) >= 100
    model+=constraint
# 求解
model.solve()

# 输出结果
print("Status:", pulp.LpStatus[model.status])
print("Objective Value:", pulp.value(model.objective))

for i in range(7):
    print(f'x{i+1} = {pulp.value(vars[i])}')

结果

决策变量:[x1 x2 x3 x4 x5 x6 x7]
Status: Optimal
Objective Value: 91.0
x1 = 0.0
x2 = 0.0
x3 = 11.0
x4 = 26.0
x5 = 8.0
x6 = 0.0
x7 = 46.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值