这里在Jupter Notebook环境下实现618法求取函数极小值
展示函数:
下面,先给大家展示这个函数的图象,然后根据图象,我们将得到这个函数的极小值应当处于的区间,这个区间便是我们后续使用618法时给定的区间。
import numpy as np %matplotlib notebook from pylab import * plt.rcParams['font.sans-serif'] = [u'SimHei'] plt.rcParams['axes.unicode_minus'] = False x_points = np.arange(100) y_points1 = 1 / (1+np.e**(-0.28*x_points+9.88)) y_points2 = 1 / (1+np.e**(0.16*x_points-2.99)) y_points3 = 1 / (1+np.e**(-0.28*x_points+9.88)) + 1 / (1+np.e**(0.16*x_points-2.99)) xlim(20,40) ylim(0.10,0.7) plt.plot(x_points, y_points1, 'b') plt.plot(x_points, y_points2, 'g') plt.plot(x_points, y_points3, 'r') plt.show
运行图象为
下面展示使用618法求取极小值,由图可知,初始区间为(25,28),需要注意的是,红色的这条线才是我们要探究的。
import numpy as np
def sixoneeight(a,b,c):
'''
传入一个起始区间的两个端点,
参数a表示左端点,
参数b表示右端点,
参数c表示最终的误差控制
'''
k = 1 # 迭代的起始次数
def function(x):
'''
定义一个题目要求的函数,
后期希望实现:
用户只需输入函数的相关参数即可创建一个函数
'''
return 1 / (1+np.e**(-0.28*x+9.88)) + 1 / (1+np.e**(0.16*x-2.99)) # 求其它函数的话,在这里修改函数关系式即可
mylambda = a + 0.382 * (b-a)
mymu = a + 0.618 * (b-a)
while (b-a) >= c:
if function(mylambda)>function(mymu):
a = mylambda
mylambda = mymu
mymu = a + 0.618 * (b - a)
k = k + 1
else:
b = mymu
mymu = mylambda
mylambda = a + 0.382 * (b-a)
k = k + 1
print("最小点可选用区间({0},{1})中任意一个数".format(a,b))
print("这里选用区间中点:即所求最优值为{0}".format((a+b)/2))
print("是否查看迭代的次数呢?")
string = input("如果是则输入Y/y,")
if string == 'Y' or string == 'y':
print("迭代次数总共为:{0}".format(k))
sixoneeight(25,28,0.001)
运行结果图如下
当然了,实际上python是提供了求取函数极小值的方式的,见下面代码
import numpy as np from scipy import signal #滤波等 x_points = np.arange(100) y_points1 = 1 / (1+np.e**(-0.28*x_points+9.88)) y_points2 = 1 / (1+np.e**(0.16*x_points-2.99)) y_points3 = 1 / (1+np.e**(-0.28*x_points+9.88)) + 1 / (1+np.e**(0.16*x_points-2.99)) peak_ind = signal.argrelextrema(y_points3,np.less)[0] print(peak_ind)
运行结果图如下



