不等式约束二次优化问题问题描述
拉格朗日乘数法
梯度=0求最值,有约束和没有约束的条件;
给函数加了约束条件然后求最值,之前的梯度=0的点就不好用了,只需要对原来的约束做变形,然后加到目标函数中去,其中关键的是引入了拉格朗日乘子lanbuta。
如果约束条件简单,比如只有一个,然后再求梯度等于0,就得到了极值点,对x和y的求偏导,此时偏导中有lanbuda。
如果约束条件复杂,比如有多个,这个时候是没有梯度为零的情况,所以没法用偏导方法了。
松弛lanbuda大于0,求lanbuda的最大值条件下的f(x)最小值,紧致lanbuda=0;
交叉熵就是一个凸问题;
只要是对偶问题,就是凸问题;
拉格朗日松弛法
拉格朗日松弛法是一种优化方法,用于处理具有约束条件的优化问题。它通过将约束条件引入目标函数,将原问题转化为一个无约束问题或一个更简单的约束问题。
拉格朗日松弛法求解不等式约束二次优化问题
基本过程
拉格朗日乘子法通过构造拉格朗日函数并求解优化问题,同时根据约束违反程度更新拉格朗日乘子,逐步逼近原始问题的最优解。KKT条件提供了一套理论框架,确保在最优解处所有条件都得到满足。这种方法在处理不等式约束的优化问题时非常有效,因为它将约束条件直接融入到优化过程中,而不是在事后检查约束是否满足。
KKT理论
优化过程具体步骤
优化算法(如梯度下降、牛顿法、BFGS等)来找到最优解
示例代码
增广拉格朗日函数
增广拉格朗日函数(Augmented Lagrangian Function)确实是拉格朗日松弛法(Lagrange Relaxation)的一种典型情况,以提高在非线性优化问题中的收敛性和稳定性。
GA算法求解增广拉格朗日函数
示例问题
基于python代码求解增广拉格朗日函数示例
import numpy as np
from scipy.optimize import minimize
from scipy.optimize import NonlinearConstraint
import random
# 目标函数
def objective(x, Q, c):
return 0.5 * np.dot(x, np.dot(Q, x)) + np.dot(c, x)
# 不等式约束函数
def inequality_constraints(x, g):
return np.array([g_i(x) for g_i in g])
# 增广拉格朗日函数
def augmented_lagrangian(x, Q, c, lambda_vals, rho, g):
obj_val = objective(x, Q, c)
constraint_vals = inequality_constraints(x, g)
penalty = rho * 0.5 * np.sum(np.maximum(constraint_vals, 0)**2)
lagrangian_term = np.sum(lambda_vals * np.maximum(constraint_vals, 0))
return obj_val + penalty + lagrangian_term
# 遗传算法
def genetic_algorithm(objective, bounds, pop_size=100, generations=100):
# 初始化种群
population = [np.array([random.uniform(b[0], b[1]) for b in bounds]) for _ in range(pop_size)]
for generation in range(generations):
# 计算适应度
fitness_scores = [objective(x) for x in population]
# 选择
selected_indices = np.argsort(fitness_scores)[:int(pop_size * 0.5)]
selected_population = [population[i] for i in selected_indices]
# 交叉
new_population = []
while len(new_population) < pop_size:
parent1, parent2 = random.sample(selected_population, 2)
child = (parent1 + parent2) / 2
new_population.append(child)
# 变异
for x in new_population:
for i in range(len(x)):
if random.random() < 0.1: # 变异概率
x[i] += random.gauss(0, 0.1) # 高斯变异
x[i] = np.clip(x[i], bounds[i][0], bounds[i][1])
population = new_population
# 返回最优解
best_idx = np.argmin(fitness_scores)
return population[best_idx]
# 主函数
def augmented_lagrangian_method(Q, c, g, bounds, rho=1.0, max_iter=100, epsilon=1e-6):
n = len(c)
x = np.zeros(n)
lambda_vals = np.zeros(len(g))
for k in range(max_iter):
# 定义当前的增广拉格朗日函数
current_obj = lambda x: augmented_lagrangian(x, Q, c, lambda_vals, rho, g)
# 使用遗传算法搜索最优解
x = genetic_algorithm(current_obj, bounds)
# 计算约束值
constraint_vals = inequality_constraints(x, g)
# 更新拉格朗日乘子
lambda_vals = np.maximum(lambda_vals + rho * constraint_vals, 0)
# 检查收敛条件
if np.sum(np.maximum(constraint_vals, 0)) < epsilon:
break
# 更新罚参数
rho *= 1.1 # 例如,每次迭代增加10%
return x, objective(x, Q, c), inequality_constraints(x, g)
# 示例问题
Q = np.array([[4, 1], [1, 3]])
c = np.array([1, 2])
g = [
lambda x: x[0]**2 + x[1]**2 - 1, # x1^2 + x2^2 <= 1
lambda x: x[0] - 2 * x[1] + 1 # x1 - 2x2 + 1 <= 0
]
bounds = [(-2, 2), (-2, 2)]
# 求解
x_opt, f_opt, g_opt = augmented_lagrangian_method(Q, c, g, bounds)
print("最优解 x:", x_opt)
print("最优目标函数值 f(x):", f_opt)
print("约束值 g(x):", g_opt)
可视化函数结果示例结果
import numpy as np
import matplotlib.pyplot as plt
# 目标函数
def objective(x, Q, c):
# 确保 x 是一个列向量
if x.ndim == 1:
x = x[:, np.newaxis]
return 0.5 * x.T @ Q @ x + c.T @ x
# 不等式约束函数
def g1(x):
return x[0]**2 + x[1]**2 - 1 # x1^2 + x2^2 <= 1 (单位圆)
def g2(x):
return x[0] - 2 * x[1] + 1 # x1 - 2x2 + 1 <= 0 (直线)
# 绘制函数
def plot_functions(Q, c, bounds):
# 生成 x1, x2 的网格
x1 = np.linspace(bounds[0][0], bounds[0][1], 100)
x2 = np.linspace(bounds[1][0], bounds[1][1], 100)
X1, X2 = np.meshgrid(x1, x2)
# 计算目标函数值
Z_obj = np.zeros(X1.shape)
for i in range(X1.shape[0]):
for j in range(X1.shape[1]):
Z_obj[i, j] = objective(np.array([X1[i, j], X2[i, j]]), Q, c)
# 计算约束函数值
Z_g1 = g1(np.array([X1, X2]))
Z_g2 = g2(np.array([X1, X2]))
# 创建图形
fig, ax = plt.subplots(figsize=(8, 6))
# 绘制目标函数的等高线图
cs_obj = ax.contour(X1, X2, Z_obj, levels=15, cmap='viridis', linestyles='solid')
ax.clabel(cs_obj, inline=1, fontsize=10, fmt=r'$f(x) = %.1f$')
# 绘制 f(x) = 0.46 的等高线
cs_046 = ax.contour(X1, X2, Z_obj, levels=[0.46], colors='m', linestyles='-.')
plt.clabel(cs_046, inline=1, fontsize=10, fmt=r'$f(x) = 0.46$')
# 绘制第一个约束函数的等高线 (g1(x) = x1^2 + x2^2 - 1 <= 0)
cs_g1 = ax.contour(X1, X2, Z_g1, levels=[0], colors='r', linestyles='--')
plt.clabel(cs_g1, inline=1, fontsize=10, fmt=r'$g_1(x) = 0$')
# 绘制第二个约束函数的等高线 (g2(x) = x1 - 2x2 + 1 <= 0)
cs_g2 = ax.contour(X1, X2, Z_g2, levels=[0], colors='b', linestyles='--')
plt.clabel(cs_g2, inline=1, fontsize=10, fmt=r'$g_2(x) = 0$')
# 绘制可行区域 (满足约束条件的区域)
Z_feasible = np.where((Z_g1 <= 0) & (Z_g2 <= 0), 0, np.nan)
ax.contourf(X1, X2, Z_feasible, levels=[-1, 0], colors='gray', alpha=0.5, label='Feasible Region')
# 设置标题和标签
ax.set_title('Objective and Constraint Functions')
ax.set_xlabel('x1')
ax.set_ylabel('x2')
# 添加图例
red_line = plt.Line2D((0,1),(0,0), color='r', linestyle='--', label=r'$g_1(x) = x_1^2 + x_2^2 - 1 = 0$')
blue_line = plt.Line2D((0,1),(0,0), color='b', linestyle='--', label=r'$g_2(x) = x_1 - 2x_2 + 1 = 0$')
gray_patch = plt.Rectangle((0, 0), 1, 1, fc="gray", alpha=0.5, label='Feasible Region')
magenta_line = plt.Line2D((0,1),(0,0), color='m', linestyle='-.', label=r'$f(x) = 0.46$')
ax.legend(handles=[red_line, blue_line, gray_patch, magenta_line], loc='upper right')
# 显示网格
plt.grid(True)
# 显示图表
plt.show()
# 示例问题
Q = np.array([[4, 1], [1, 3]])
c = np.array([1, 2])
bounds = [(-2, 2), (-2, 2)]
# 绘制目标函数和约束函数
plot_functions(Q, c, bounds)
绘制出来的结果如下