目录
2 线性规划的扩展
2.1 运输问题
2.1.1 一般的运算问题
2.1.2 配置问题
2.2 整数线性规划
限制全部或部分决策变量取离散非负整数值的线性规划,称之为整数线性规划,简称为整数规划。整数规划中,如果所有决策变量都限制为整数,则称之为纯整数规划;如果仅一部分变量限制为整数,则称之为混合整数规划。整数规划的一种特殊情形是0-1整数规划,它的决策变量仅限于0或1,也分为纯0-1整数规划和混合0-1整数规划两种形式。
整数规划问题与求解
目前没有一种方法可以有效地求解一切整数规划。常见的整数规划求解算法有:
- 分支定界法:可求纯或混合整数线性规划;
- 割平面法:可求纯或混合整数线性规划;
- 隐枚举法:用于求解0-1整数规划,有过滤隐枚举法和分支隐枚举法;
- 匈牙利法:解决指派问题(0-1规划特殊情形);
- Monte Carlo法:求解各种类型规划。
2.2.1 一般的整数线性规划
(1)问题
易斯特泊恩房地产公司共有200万美元用来购买新的租赁财产。经过初步筛选,其已把投资选项减少为联体别墅和公寓楼。每套联体别墅售价282 000美元,现有5套空闲。每幢公寓楼售价400 000美元,而且开发商可以根据易斯特泊恩的需要数量建造。
易斯特泊恩的财产经理每月用于这些新置的财产上的时间可达140小时。每套联体别墅预计每月要花4小时,每幢公寓楼预计每月40小时。扣除抵押偿还和经营成本后,年现金流预计为每套联体别墅10 000美元和每幢公寓楼15 000美元。易斯特泊恩的股东将要决定分别购买联体别墅和公寓楼的数量以保证年现金流最大。
(2)模型
(3)求解
(4)Python实现
例:
利用cvxpy(先安装库),
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com cvxpy
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com cvxopt
求解代码如下:
import cvxpy as cp
from numpy import array
c = array([40, 90]) # 定义目标向量
a = array([[9, 7], [-7, -20]]) # 定义约束矩阵
b = array([56, -70]) # 定义约束条件的右边向量
x = cp.Variable(2, integer=True) # 定义两个整数决策变量
obj = cp.Minimize(c * x) # 构造目标函数
cons = [a * x <= b, x >= 0] # 构造约束条件
prob = cp.Problem(obj, cons) # 构建问题模型
prob.solve(solver='GLPK_MI', verbose=True) # 求解问题
print("最优值为:", prob.value)
print("最优解为:\n", x.value)
运行结果如下:
指派问题及求解
分派何人去完成哪种任务能够使得总效率最高的问题,通常称为指派问题。
标准指派模型:
这是一个纯0-1整数规划模型。某商业公司新建商店问题,其数学模型如下:
求解代码如下:
import cvxpy as cp
import numpy as np
c = np.array([[4, 8, 7, 15, 12],
[7, 9, 17, 14, 10],
[6, 9, 12, 8, 7],
[6, 7, 14, 6, 10],
[6, 9, 12, 10, 6]])
x = cp.Variable((5, 5), integer=True)
obj = cp.Minimize(cp.sum(cp.multiply(c, x)))
con = [0 <= x, x <= 1, cp.sum(x, axis=0, keepdims=True) == 1,
cp.sum(x, axis=1, keepdims=True) == 1]
prob = cp.Problem(obj, con)
prob.solve(solver='GLPK_MI')
print("最优值为:", prob.value)
print("最优解为:\n", x.value)
运行结果:
(5)程序实现
指派问题的程序实现
管理运筹学3.0
软件下载链接
例(配置问题):
2.2.2 含0-1变量的应用规划
(1)资金预算
(2)固定成本(选读)
(3)分配系统设计
(4)银行选址
(5)招聘问题
2.2.3 0-1整数变量赋予构建模型的灵活性
(1)0-1整数变量的应用
(2)案例
2.3 非线性规划
2.3.1 概念和基础理论
(1)非线性规划概念和理论
通常将非线性规划问题划分为无约束和有约束两大类讨论。
非线性规划模型:
或用向量表示法:
无约束非线性规划模型:
有约束线性规划模型求解:
- 求解有等式约束非线性规划的Lagrange乘数法
- 求解有约束非线性规划的罚函数法
2)非线性规划的Python求解
- scipy.optimize
- cvxopt
- cvxpy(不能求解非凸函数,非凸只能使用scipy.optimize求解)
用scipy.optimize模块的minimize函数求解:
求解代码如下:
rom scipy.optimize import minimize
from numpy import ones
def obj(x):
x1, x2, x3 = x
return (2 + x1) / (1 + x2) - 3 * x1 + 4 * x3
LB = [0.1] * 3
UB = [0.9] * 3
bound = tuple(zip(LB, UB)) # 生成决策向量界限的元组
res = minimize(obj, ones(3), bounds=bound) # 第2个参数为初值
print(res.fun, '\n', res.success, '\n', res.x) # 输出最优值、求解状态、最优解
运行结果:
求解代码:
from scipy.optimize import minimize
import numpy as np
c1 = np.array([1, 1, 3, 4, 2]);
c2 = np.array([-8, -2, -3, -1, -2])
A = np.array([[1, 1, 1, 1, 1], [1, 2, 2, 1, 6],
[2, 1, 6, 0, 0], [0, 0, 1, 1, 5]])
b = np.array([400, 800, 200, 200])
obj = lambda x: np.dot(-c1, x ** 2) + np.dot(-c2, x)
cons = {'type': 'ineq', 'fun': lambda x: b - A @ x}
bd = [(0, 99) for i in range(A.shape[1])]
res = minimize(obj, np.ones(5) * 90, constraints=cons, bounds=bd)
print(res) # 输出解的信息
运行结果:
该例只能求局部最优解.
用cvxopt.solvers模块求解:
利用cvxopt.solvers模块求解二次规划模型。若非线性规划的目标函数为决策向量x的二次函数,约束条件又全是线性的,就称这种规划为二次规划。
cvxopt.solvers模块中二次规划的标准型为:
2.4 作业
移动基站选址问题
有一移动电话运营商计划在一个目前尚未覆盖的区域开展业务,管理层计划投资1000万元为此区域购置安装设备。调查表明,在此区域有7个位置可以安设基站,每个基站只能覆盖一定数目的社区。下图为此区域的示意图,将此区域划分为若干个社区,并标出了可以设置基站的位置,每个候选的位置都用黑点表示,并用数字标号,每个社区表示为一个多边形,多边形中的数字即为此社区的序号。
由于地理位置和拓扑结构的限制,每个位置建造基站的费用不同,且覆盖范围也不同,表1列出了每个基站位置能够覆盖的社区以及每个位置的建造费用。
已知每个社区内的居民数目见表2。问:应在何处设置基站才能够使给定的1000万预算覆盖尽可能多的人口?
表1
位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
费用(百万) 覆盖社区 | 1.8 1,2,4 | 1.3 2,3,5 | 4.0 4,7,8,10 | 3.5 5,6,8,9 | 3.8 8,9,12 | 2.6 7,10,11,12,15 | 2.1 12,13,14,15 |
表2
社区 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
人口(千人) | 2 | 4 | 13 | 6 | 9 | 4 | 8 | 12 | 10 | 11 | 6 | 14 | 9 | 3 | 6 |