栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

第六章 整数规划与非线性规划

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第六章 整数规划与非线性规划

6.1 整数规划

       在线性规划模型中,决策变量只需取连续型数值即可.但还有大量的实际问题,虽然形式上与线性规划类似,却增加了某些约束条件,要求部分甚至全部决策变量必须取离散的非负整数值才有意义.对于限制全部或部分决策变量取离散非负整数值的线性规划,称之为整数线性规划,简称为整数规划.在整数规划中,如果所有决策变量都限制为整数,则称为纯整数规划;如果仅一部分变量限制为整数,则称为混合整数规划,整数规划的一种特殊情形是0-1整数规划,它的决策变量仅限于0或1,也分为纯0-1整数规划和混合0-1整数规划两种形式

       由于cxvpy库安装繁琐,此部分待补。

6.2 非线性规划 6.2.1 非线性规划的Python求解

用scipy.optimize模块的minimize函数求解:

scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)

  • fun:目标函数
  • x0:初步猜测,是一个有n个元素的数组
  • bounds:参数的上下界范围
  • constrains:约束条件,分为“等式”、“不等式”两种

(scipy.optimize.minimize部分内容参考自python数学建模之用scipy.optimize.minimize解决高次非线性规划问题)

例6.2.1 求解非线性规划问题:(无约束)

解:Python程序如下:

from 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)  # 第二个参数为初值
print(res.fun, 'n', res.success, 'n', res.x)  # res.success表示是否成功

输出结果如下:

-0.7736842105263159 
 True 
 [0.9 0.9 0.1]

注:在以下语句中,ones(3)给定了三个初值,相对应地,

res = minimize(obj, ones(3), bounds=bound)

       传入obj函数的是一个有3个元素的一维ndarray,在def()中的语句

x1, x2, x3 = x

        恰好将x的三个元素分别赋值给x1,x2,x3

例6.2.2 求解非线性规划问题:(有约束)

解:Python程序如下:

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)

输出结果如下:

     fun: -51629.92995523618
     jac: array([ -93.        , -196.        ,    3.        , -791.        ,
        -78.80029297])
 message: 'Optimization terminated successfully'
    nfev: 20
     nit: 4
    njev: 3
  status: 0
 success: True
       x: array([5.05000000e+01, 9.90000000e+01, 1.98182086e-10, 9.89999999e+01,
       2.02000000e+01])

注:

  • numpy.dot:向量内积(此处c1,c2,x都是一维的,因此是向量内积)或矩阵乘法
  • 在对obj定义时,x是一个一维ndarray,因此x**2是对x中的每个元素进行平方
  • 矩阵之间用@连接代表矩阵相乘(详见python中矩阵、数组使用@的含义)
  • numpy.array.shape == (row, column)
  • cons中约束条件默认为“表达式 ≧ 0”或“表达式 = 0”
  • 如果不使用numpy库,可以用Python自带数组;或约束条件中既有等式也有不等式,也可以不按照本例代码写,参考python数学建模之用scipy.optimize.minimize解决高次非线性规划问题
6.2.2 飞行管理问题

 

 计算和的Python代码如下:  

import numpy as np
import pandas as pd

x0 = np.array([150, 85, 150, 145, 130, 0])
y0 = np.array([140, 85, 155, 50, 150, 0])
q = np.array([243, 236, 220.5, 159, 230, 52])
d = np.zeros((6, 6))
a0 = np.zeros((6, 6))
b0 = np.zeros((6, 6))
xy0 = np.c_[x0, y0]

for i in range(6):
    for j in range(6):
        d[i, j] = np.linalg.norm(xy0[i]-xy0[j])  # 两飞机之间距离
d[np.where(d == 0)] = np.inf
a0 = np.arcsin(8./d)*180/np.pi
xy1 = x0+1j*y0
xy2 = np.exp(1j*q*np.pi/180)
for m in range(6):
    for n in range(6):
        if n != m:
            b0[m, n] = np.angle((xy2[n]-xy2[m])/(xy1[m]-xy1[n]))
b0 = b0*180/np.pi
f = pd.ExcelWriter('Plane.xlsx')
pd.DataFrame(a0).to_excel(f, "sheet1", index=None)  # 把a0写入Excel的表单1
pd.DataFrame(b0).to_excel(f, "sheet2", index=None)  # 把a0写入Excel的表单2
f.save()

输出结果如下:

表6.1   的值

表6.2   的值

 

注:

  • np.linalg.norm:用来求两点之间距离(详细用法参考np.linalg.norm(求范数))
  • np.where:条件判断语句,满足则进行后续语句(详细用法参考np.where()的使用方法)
  • np.inf:表示无穷大(详细用法参考NumPy库—NAN和INF值)
  • np.angel:计算复数幅角(详细用法参考numpy.angle详解)
  • np.sum:用于矩阵求和(详细用法参考Python_np.sum()函数)

求最优解Python程序如下:

import numpy as np
import pandas as pd
from scipy.optimize import minimize
a0 = pd.read_excel("Plane.xlsx")  # 读入第1表单
b0 = pd.read_excel("Plane.xlsx", 1)  # 读入第2个表单
a0 = a0.values  # 提取数值
b0 = b0.values
obj = lambda x: np.sum(np.abs(x))
bd = [(-30, 30) for i in range(6)]  # 决策向量的界限
cons = []
for i in range(5):
    for j in range(i+1, 6):
        cons.append({'type': 'ineq', 'fun': lambda x: np.abs(b0[i, j]+(x[i]+x[j])/2)-a0[i, j]})
res = minimize(obj, np.ones(6), constraints=cons, bounds=bd)
print(res)

输出结果如下:

     fun: 0.7909172985328354
     jac: array([-1., -1., -1., -1.,  1.,  1.])
 message: 'Optimization terminated successfully'
    nfev: 54
     nit: 6
    njev: 6
  status: 0
 success: True
       x: array([2.53262997e-07, 2.53262998e-07, 2.53262998e-07, 2.53262998e-07,
       3.95458143e-01, 3.95458143e-01])

求得最优解为5号飞机偏转0.3955°,6号飞机偏转0.3955°,其他飞机不偏转,总偏转角度为0.7909°。

暑期编程PK赛 得CSDN机械键盘等精美礼品!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1015696.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号