求有效解的几种常用方法
- 线性加权法√
根据目标的重要性确定一个权重,以目标函数的加权平均值为评价函数,使其达到最优。 - ɛ约束法
根据决策者的偏好,选择一个主要关注的参考目标 - 理想点法
以每个单目标最优解为该目标的理想值,使每个目标函数值与理想值得差得加权平方和最小 - 优先级法
先求优先级高的目标函数的最优值,在确保优先级高的目标获得不低于最优解的条件下,再求优先级低的目标函数
例题:化工厂生产问题
某化工厂今年拟生产两种新产品A和B,其生产费用分别为2万元/吨和5万元/吨。这两种产品均将造成环境污染,每生产一吨A产品会产生0.4吨的污染,每生产一吨B产品会产生0.3吨的污染。由于条件限制,工厂生产产品A和B的最大生产能力各为每月5吨和6吨,而市场需要这两种产品的总量每月不少于7吨。该工厂决策认为,这两个目标中环境污染应该优先考虑,且根据经验生产费用的参考值为30万元,污染量参考值为2吨。试问工厂如何安排生产计划,在满足市场需要的前提下,使设备的花费和产生的污染均达到最小。
解:设工厂每月产品A生产 x 1 x_1 x1吨,B生产 x 2 x_2 x2吨,那么产生的污染分别为0.4 x 1 x_1 x1吨和0.3 X 2 X_2 X2吨
{ min f 1 = 2 x 1 + 5 x 2 min f 2 = 0.4 x 1 + 0.3 x 2 s t . { x 1 + x 2 ≥ 7 0 ≤ x 1 ≤ 5 0 ≤ x 2 ≤ 6 \begin{cases}\min f_1=2x_1+5x_2\\\min f_2=0.4x_1+0.3x_2\\st.\begin{cases}x_1+x_2\geq7\\0\leq x_1\leq5\\0\leq x_2\leq6\end{cases}\end{cases} ⎩ ⎨ ⎧minf1=2x1+5x2minf2=0.4x1+0.3x2st.⎩ ⎨ ⎧x1+x2≥70≤x1≤50≤x2≤6
[!info]
st.
是subject to
,即约束条件的缩写
下面将其转换为一个单目标规划问题,即对上面的两个目标函数进行加权,由于该工厂决策认为环境污染应优先考虑,因此我们可以选取f1和f2的权重分别为0.4和0.6。注意到两个目标函数的单位不同,一个为“万元”,一个为“吨”,因此需要首先对目标函数进行标准化来消除量纲的影响,然后再进行加权,由于题目中已经给了产品费用和污染量的参考值,因此我们将这两个目标函数分别处以其参考值来消除量纲。
加权组合后的目标函数
f = 0.4 × f 1 30 + 0.6 × f 2 2 = 0.4 30 × ( 2 x 1 + 5 x 2 ) + 0.6 2 × ( 0.4 x 1 + 0.3 x 2 ) f=0.4\times\frac{f_{1}}{30}+0.6\times\frac{f_{2}}{2}=\frac{0.4}{30}\times(2x_{1}+5x_{2})+\frac{0.6}{2}\times(0.4x_{1}+0.3x_{2}) f=0.4×30f1+0.6×2f2=300.4×(2x1+5x2)+20.6×(0.4x1+0.3x2)
得到一个单目标规划问题,通过linprog函数进行求解可以得到
x 1 = 5 , x 2 = 2 , f 1 = 20 , f 2 = 2.6 x_{1}=5\:,x_{2}=2\:,f_{1}=20\:,f_{2}=2.6 x1=5,x2=2,f1=20,f2=2.6
敏感性分析
下面对结果进行敏感性分析,敏感性分析是指从定量分析的角度研究有关因素发生某种变化对某一个或一组关键指标影响程度的一种不确定分析技术。其实质是通过逐一改变相关变量数值的方法来解释关键指标受这些因素变动影响大小的规律。
附 Python代码
import numpy as np
from scipy.optimize import linprog
import matplotlib.pyplot as plt
from matplotlib import rcParams
# ======= 多目标规划问题 =======
# 两个目标函数的权重以及对应的x1和X2的值
weights = [
(0.4, 0.6), # w1=0.4, w2=0.6
(0.5, 0.5), # w1=0.5, w2=0.5
(0.3, 0.7), # w1=0.3, w2=0.7
]
# 定义约束条件
A = [[-1, -1]] # 不等式约束A*x <= b
b = [-7]
lb = [0, 0] # 下界
ub = [5, 6] # 上界
bounds = [(lb[0], ub[0]), (lb[1], ub[1])]
# 遍历不同权重组合,求解线性规划
for w1, w2 in weights:
# 构造目标函数系数
c = [w1/30*2 + w2/2*0.4, w1/30*5 + w2/2*0.3]
# 求解线性规划
result = linprog(c, A_ub=A, b_ub=b, bounds=bounds, method='highs')
x = result.x # 变量X的最优解
fval = result.fun # 目标函数的最优值
# 计算目标函数值
f1 = 2 * x[0] + 5 * x[1]
f2 = 0.4 * x[0] + 0.3 * x[1]
# 打印结果
print(f"\n权重组合:w1={w1}, w2={w2}")
print(f"最优解:x1={x[0]:.2f}, x2={x[1]:.2f}")
print(f"目标函数值:f1={f1:.2f}, f2={f2:.2f}, 综合指标={fval:.2f}")
# ======= 敏感性分析 =======
# 权重范围
W1 = np.arange(0.1, 0.501, 0.001)
W2 = 1 - W1
n = len(W1)
# 初始化结果存储数组
F1 = np.zeros(n)
F2 = np.zeros(n)
X1 = np.zeros(n)
X2 = np.zeros(n)
FVAL = np.zeros(n)
# 遍历不同权重,执行敏感性分析
for i in range(n):
w1 = W1[i]
w2 = W2[i]
c = [w1/30*2 + w2/2*0.4, w1/30*5 + w2/2*0.3] # 修正此处
# 求解线性规划
result = linprog(c, A_ub=A, b_ub=b, bounds=bounds, method='highs')
x = result.x
F1[i] = 2 * x[0] + 5 * x[1]
F2[i] = 0.4 * x[0] + 0.3 * x[1]
X1[i] = x[0]
X2[i] = x[1]
FVAL[i] = result.fun
# ======= 绘图 =======
# 设置字体为支持中文的字体,例如SimHei(黑体)
rcParams['font.sans-serif'] = ['SimHei'] # 选择黑体
rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 图1:权重与目标函数的关系
plt.figure()
plt.plot(W1, F1, label='f1')
plt.plot(W1, F2, label='f2')
plt.xlabel("f1的权重(w1)")
plt.ylabel("目标函数值")
plt.legend()
plt.title("目标函数值随权重变化的关系")
plt.grid()
# 图2:权重与决策变量的关系
plt.figure()
plt.plot(W1, X1, label='x1')
plt.plot(W1, X2, label='x2')
plt.xlabel("f1的权重(w1)")
plt.ylabel("决策变量值")
plt.legend()
plt.title("决策变量随权重变化的关系")
plt.grid()
# 图3:权重与综合指标的关系
plt.figure()
plt.plot(W1, FVAL)
plt.xlabel("f1的权重(w1)")
plt.ylabel("综合指标值")
plt.title("综合指标随权重变化的关系")
plt.grid()
# 显示所有图
plt.show()