通过模拟退火算法求解一元五次方程最值(python代码实现)

大学生速通模拟退火算法_哔哩哔哩_bilibili

通过上面这个视频可以了解到模拟退火算法的基础概念,这个视频也是我看过最通俗易懂的讲解了。

灵活运用视频的方法,用python代码实现一元五次方程的求解,方程如下:

x^5 +10x^3+20x - 4 = 0

对于这个方程,要将其转变为函数,才能进行求解:

minf=\left |x^5 +10x^3+20x - 4 \right |

将这个问题转为求解函数f的最小值问题,注意这里加了一个绝对值符号,这样f最小值的解,才是这个方程的根

然后把函数用代码敲出来:

import numpy as np

def fun(x: float):
    x = x ** 5 + 10 * (x ** 3) + 20 * x - 4
    return np.fabs(x)

定义解的随机获取方式和更新方式(通过random随机得到一个解):

import random

x = random.uniform(-100000, 100000) #得到一个随机浮点数
dx = x + random.uniform(-100000, 100000) * t #每次更新x都受到t都受到温度的影响,温度越高x的变化越大,温度越低x的变化范围越小

做好这两步,就可以带入的模拟退火的框架里求解了,完整代码如下:

import random
import numpy as np
import matplotlib.pyplot as plt

t = 200000
dt = 0.993
eps = 1e-14


def fun(x: float):
    x = x ** 5 + 10 * (x ** 3) + 20 * x - 4
    return np.fabs(x)


n = 0
x = random.uniform(-100000, 100000)
x = float(x)
f = fun(x)

f_values = []  # 存储每次循环后的 f 值
x_values = []  # 存储每次循环后的 x 值

while (t > eps):
    dx = x + random.uniform(-100000, 100000) * t
    df = fun(dx)

    if df < f:
        f = df
        x = dx
    elif np.exp((f - df) / t) * 100000 > random.randint(0, 100000):
        f = df
        x = dx

    t = t * dt
    n += 1

    f_values.append(f)
    x_values.append(x)

    print(f"f = {f},x = {x},第{n}次循环")

# 绘制折线图
plt.figure()
plt.plot(range(1, n + 1), f_values, label='f value')
plt.plot(range(1, n + 1), x_values, label='x value')
plt.xlabel('Iterations')
plt.ylabel('Value')
plt.legend()
plt.show()

我们运行代码,查看结果,并输出折线图:

那么我们看到电脑算到的结果为x=0.1962,这个时候f的值就非常接近与零了,那么在误差允许的范围内,我们就可以认为f等于零

通过模拟退火算法求解一元五次方程最值(python代码实现)_第1张图片

总结

通过模拟退火算法求解函数最小值是具有通用性的,理论上只要把函数f改成你想求的任意一个函数,都能求出最小值(前提,x不受约束的条件下),那么在x受约束的条件下该如何写退火算法进行求解呢?可以看我后续更新

数学建模|通过模拟退火算法求解非线性规划问题(python代码实现)-CSDN博客

你可能感兴趣的:(模拟退火算法,模拟退火算法,算法,机器学习,数学建模,python)