Skip to content

Latest commit

 

History

History
184 lines (128 loc) · 6.93 KB

几种优化算法.md

File metadata and controls

184 lines (128 loc) · 6.93 KB
title date tags categories
几种优化算法
2024-05-14 18:20:00 -0700
算法
优化
数学
数学

梯度下降

梯度下降算法是一种常用的优化算法,用于求解函数的最小值。梯度下降算法的基本思想是:在函数的梯度方向上进行搜索,以找到函数的最小值点。

以查询函数 $f(x)$ 的最小值为例,梯度下降算法的迭代公式如下:

$$ x_{n+1} = x_n - \alpha \cdot \nabla f(x_n) $$

其中,$\alpha$ 为学习率,$\nabla f(x_n)$ 为函数 $f(x)$ 在点 $x_n$ 处的梯度。

梯度的定义: 梯度是一个向量,它的方向是函数在某一点上升最快的方向,它的模表示函数在该点上升的速率。 $\nabla f(x) = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \cdots, \frac{\partial f}{\partial x_n} \right)$

举个例子,当我们要求解函数 $f(x) = x^2$ 的最小值时,梯度下降算法的迭代公式如下:

$$ \begin{aligned} x_{n+1} & = x_n - \alpha \cdot \nabla f(x_n) \\ & = x_n - \alpha \cdot 2x_n \\ & = (1 - 2\alpha) \cdot x_n \end{aligned} $$

从上面的迭代公式可以看出,当 $\alpha < 0.5$ 时,梯度下降算法可以收敛到函数 $f(x) = x^2$ 的最小值点 $x = 0$

所以也可以得到这样的结论:梯度下降算法的收敛性与学习率 $\alpha$ 有关,学习率过大或过小都会导致梯度下降算法无法收敛。

牛顿法

牛顿法是一种求解函数的最小值的优化算法,它的基本思想是:在函数的二阶导数方向上进行搜索,以找到函数的最小值点。

以查询函数 $f(x)$ 的最小值为例,牛顿法的迭代公式如下:

$$ x_{n+1} = x_n - \frac{f'(x_n)}{f''(x_n)} $$

这个公式的直观解释是:在点 $x_n$ 处,用这个点处切线的零点作为下一个点的位置,这样可以更快地找到函数的最小值点。直到切线的斜率为0,此时就是极值点。

因此迭代停止于 $f'(x) = 0$ 的点。

举个例子,当我们要求解函数 $f(x) = x^2$ 的最小值时,从$x = 1$开始,牛顿法的迭代公式如下:

$$ \begin{aligned} x_0 &= 1 \\ x_1 & = x_0 - \frac{f'(x_0)}{f''(x_0)} \\ & = 1 - \frac{2}{2} \\ & = 0 \end{aligned} $$

此时,$f'(0) = 0$,所以 $x = 0$ 是函数 $f(x) = x^2$ 的最小值点。

这个方法一般情况下收敛很快,适合已知函数,并且容易求导和求二阶导数的情况。

模拟退火

模拟退火是一种求解函数的最小值的优化算法,它的基本思想是:在函数的梯度方向上进行搜索,以找到函数的最小值点。

与梯度下降算法不同的是,模拟退火算法引入了一个随机因素,用于跳出局部最优解,从而更好地找到全局最优解。这种算法一般对于一些比较抽象的函数。

模拟退火算法的迭代公式如下:

$$ x_{n+1} = x_n - \alpha \cdot \nabla f(x_n) + \epsilon $$

其中,$\epsilon$ 为随机因素,用于跳出局部最优解。 $\alpha$ 为学习率,即步长。

这种算法使用 Python 实现如下(以求解函数 $f(x) = x^2$ 的最小值为例):

import random

f = lambda x: x**2

def simulated_annealing(f, x0, alpha, epsilon, max_iter):
    x = x0
    for i in range(max_iter):
        x = x - alpha * 2 * x + random.uniform(-epsilon, epsilon)
    return x

x0 = 1          # 初始值
alpha = 0.1     # 学习率
epsilon = 0.1   # 随机因素
max_iter = 1000 # 最大迭代次数

x = simulated_annealing(f, x0, alpha, epsilon, max_iter)
print(x)

遗传算法

遗传算法是一种求解函数的最小值的优化算法,它的基本思想是:通过模拟生物进化的过程,从种群中选择出适应度高的个体,并通过交叉和变异操作,产生新的个体,以找到函数的最小值点。

遗传算法的基本步骤如下:

  1. 初始化种群:随机生成一定数量的个体,作为种群。
  2. 评估适应度:计算每个个体的适应度,以评估个体的优劣。
  3. 选择操作:根据适应度选择出适应度高的个体,作为下一代的种群。
  4. 交叉操作:对选择出的个体进行交叉操作,产生新的个体。
  5. 变异操作:对交叉后的个体进行变异操作,产生新的个体。
  6. 重复步骤 2-5,直到满足终止条件。

遗传算法的 Python 实现如下(以求解函数 $f(x) = x^2$ 的最小值为例):

import random

f = lambda x: x**2

def genetic_algorithm(f, population_size, max_iter):
    population = [random.uniform(-10, 10) for _ in range(population_size)]  # 初始化种群,随机生成个体
    for i in range(max_iter):
        fitness = [f(x) for x in population]
        population = sorted(population, key=lambda x: f(x)) # 根据适应度排序
        new_population = []
        for j in range(population_size):
            parent1 = random.choice(population)
            parent2 = random.choice(population)
            child = (parent1 + parent2) / 2 + random.uniform(-0.05, 0.05) # 交叉和变异操作
            new_population.append(child)
        population = new_population
    return population[0]

population_size = 100 # 种群大小
max_iter = 1000       # 最大迭代次数

x = genetic_algorithm(f, population_size, max_iter)
print(x)

蚁群算法

蚁群算法是一种求解函数的最小值的优化算法,它的基本思想是:模拟蚂蚁在寻找食物的过程,通过蚂蚁之间的信息交流,找到函数的最小值点。

蚁群算法的基本步骤如下:

  1. 初始化信息素:随机生成信息素,用于表示蚂蚁在路径上的信息。
  2. 选择路径:蚂蚁根据信息素选择路径,以找到函数的最小值点。
  3. 更新信息素:根据蚂蚁的选择,更新信息素,以增加蚂蚁选择的概率。
  4. 重复步骤 2-3,直到满足终止条件。

其中信息素的更新公式如下:

$$ \tau_{ij} = \tau_{ij} + \frac{1}{f(x_{best})} $$

其中,$\tau_{ij}$ 为路径 $i$ 上的信息素,$f(x_{best})$ 为蚂蚁选择的最优路径的函数值。

蚁群算法的 Python 实现如下(以求解函数 $f(x) = x^2$ 的最小值为例):

import random

f = lambda x: x**2

def ant_colony_algorithm(f, num_ants, max_iter):
    pheromone = [random.uniform(0, 1) for _ in range(num_ants)]  # 初始化信息素
    for i in range(max_iter):
        ants = [random.uniform(-10, 10) for _ in range(num_ants)] # 选择路径
        best_ant = min(ants, key=lambda x: f(x))
        pheromone = [p + 1 / f(best_ant) for p in pheromone] # 更新信息素
    return best_ant

num_ants = 100 # 蚂蚁数量
max_iter = 1000 # 最大迭代次数

x = ant_colony_algorithm(f, num_ants, max_iter)
print(x)

需要注意的是,这些算法都是一种启发式算法,不能保证一定能找到函数的最小值点,但是可以在一定程度上提高搜索效率。这种方式尤其适用于一些复杂的函数,如多维函数、非线性函数等;或者一些难以在有限时间内求解的问题,如旅行商问题、背包问题等。