Python退火算法在高次方程的应用


Posted in Python onJuly 26, 2018

,简介

退火算法不言而喻,就是钢铁在淬炼过程中失温而成稳定态时的过程,热力学上温度(内能)越高原子态越不稳定,而温度有一个向低温区辐射降温的物理过程,当物质内能不再降低时候该物质原子态逐渐成为稳定有序态,这对我们从随机复杂问题中找出最优解有一定借鉴意义,将这个过程化为算法,具体参见其他资料。

二,计算方程

我们所要计算的方程是f(x) = (x - 2) * (x + 3) * (x + 8) * (x - 9),是一个一元四次方程,我们称为高次方程,当然这个函数的开口是向上的,那么在一个无限长的区间内我们可能找不出最大值点,因此我们尝试在较短区间内解最小值点,我们成为最优解。

解法1:

毫无疑问,数学方法多次求导基本可以解出,但是这个过程较复杂,还容易算错,我就不赘述了,读者有时间自己可以尝试解一下。

解法二:

这个解法就是暴力解决了,我们这里只求解区间[-10,10]上的最优解,直接随机200个点,再除以10(这样可以得到非整数横坐标),再依此计算其纵坐标f(x),min{f(x)}一下,用list的index方法找出最小值对应位置就行了,然后画出图形大致瞄一瞄。

直接贴代码:

import random
 import matplotlib.pyplot as plt
 list_x = []
 # for i in range(1):
 #   #print(random.randint(0,100))
 #   for i in range(0,100):
 #     print("sss",i)
 #
 #   list_x.append(random.randint(0,100))
 for i in range(-100,100):
   list_x.append(i/10)
 print("横坐标为:",list_x)
 print(len(list_x))
 list_y = []
 for x in list_x:
   # print(x)
   #y = x*x*x - 60*x*x -4*x +6
   y = (x - 2) * (x + 3) * (x + 8) * (x - 9)
   list_y.append(y)
 print("纵坐标为:",list_y)
 #经验证,这里算出来的结果6.5和最优解1549都是对的
 print("最小值为:",min(list_y))
 num = min(list_y)
 print("最优解:",list_y.index(num)/10)
 print("第",list_y.index(num)/10-10,"个位置取得最小值")
 plt.plot(list_x, list_y, label='NM')
 #plt.plot(x2, y2, label='Second Line')
 plt.xlabel('X') #横坐标标题
 plt.ylabel('Y') #纵坐标标题
 #plt.title('Interesting Graph\nCheck it out',loc="right")  #图像标题
 #plt.title('Interesting Graph\nCheck it out')
 plt.legend()  #显示Fisrt Line和Second Line(label)的设置
 plt.savefig('C:/Users/zhengyong/Desktop/1.png')
 plt.show()

得到如下结果:

Python退火算法在高次方程的应用 

那么我们得出最优解的坐标是(6.5,-1549.6875),结果先放这里,接下来用退火算法看能不能解出。

解法三:

我们看一张图(解法二中的方法得出的图),然后讲讲退火算法的最核心的思想。

Python退火算法在高次方程的应用 

首先,先随机一个[-10.10]之间的随机解,作为初始解空间,比方说随机了一个位于[-2.5.2.5]中最高的那个点就是点1(横坐标为x1),他有对于的纵坐标的值y1,这时候我们把这个点的横坐标随机加或者减去一个值(注意这个值的大小很重要,我们先叫他随机移动值),加或者减后得到新的横坐标的值x2,再算出这个横坐标的对应纵坐标(y2),对比之前的纵坐标的大小,这里设置

delta = y2-y1,发现无论怎样都是小于原先的纵坐标(前提是随机移动值足够小),这时候我们把新得到的x2赋值给x1,这时候现在的x2的值传给x1,x1是原先随机的值,这个过程可以重复iter_num 次,大小就根据自己的区间来。
上述的整个过程是在一个温度下进行的,这个过程结束后我们用温度更新公式再次的更新温度,再去重复上述步骤。

温度更新我是用的常用的公式是T(t)=aT0(t-1),其中0.85?a?0.99。也可用相应的热能衰减公式来计算,T(t)=T0/(1+lnt),t=1,2,3,...,这都是简单的状态更新方法。

也就是说,不管你随机的是几我都能朝着优化的方向前进(前提是非最优点)。

其次,点2 是同理的,区别在于他是局部最优解,那么跳出这个局部最优解的机制是什么呢?

若初始点是(x3,y3),然后用上述方法得出(x4,y4),在点二处得到的delta肯定是大于0的,那么怎么办呢?当大于0的时候我们每次都有一定的概率来接受这个看起来不是最优的点,叫Metropolis准则,具体是这样的:

Python退火算法在高次方程的应用 

这里的E就是y,T就是当前温度,delta小于0就是百分百接受新值,否者就是按照这个概率接受,当迭代多次的时候,每次向右移动的步长累加到点1 时候他就有可能找到最终的最优解了,步长是累加的但是概率是累成的,意味着这个概率很小,但是一旦迭代次数多久一定会跑出来到最优解处。

最优,点3不解释了哈,和上面一样。

那么我们上代码:

#自己改写的退火算法计算方程(x - 2) * (x + 3) * (x + 8) * (x - 9)的计算方法
 #class没啥用
 import numpy as np
 import matplotlib.pyplot as plt
 from matplotlib import pyplot as plt 
 #设置基本参数
 #T初始温度,T_stop,iter_num每个温度的迭代次数,Q温度衰减次数
 class Tuihuo_alg():
   def __init__(self,T_start,iter_num,T_stop,Q,xx,init_x):
     self.T_start = T_start
     self.iter =iter_num
     self.T_stop = T_stop
     self.Q = Q
     self.xx = xx
     self.init_x = init_x
   # def cal_x2y(self):
   #   return (x - 2) * (x + 3) * (x + 8) * (x - 9)
 if __name__ == '__main__':
   def cal_x2y(x):
     #print((x - 2) * (x + 3) * (x + 8) * (x - 9))
     return (x - 2) * (x + 3) * (x + 8) * (x - 9)
   T_start = 1000
   iter_num = 1000
   T_stop = 1
   Q = 0.95
   K = 1
   l_boundary = -10
   r_boundary = 10
   #初始值
   xx = np.linspace(l_boundary, r_boundary, 300)
   yy = cal_x2y(xx)
   init_x =10 * ( 2 * np.random.rand() - 1)
   print("init_x:",init_x)
   t = Tuihuo_alg(T_start,iter_num,T_stop,Q,xx,init_x)
   val_list = [init_x]
   while T_start>T_stop:
     for i in range(iter_num):
       init_y = cal_x2y(init_x)
       #这个区间(2 * np.random.rand() - 1)本身是(-1,1),所以加上就是一个随机加或者减过程
       new_x = init_x + (2 * np.random.rand() - 1)
       if l_boundary <= new_x <= r_boundary:
         new_y = cal_x2y(new_x)
     #print("new_x:",new_x)
     #print('new_y:',new_y)
         delta = new_y - init_y #新减旧
         if delta < 0:
           init_x = new_x
         else:
           p = np.exp(-delta / (K * T_start))
           if np.random.rand() < p:
             init_x = new_x
       #print("new_x:",new_x)
       #print("当前温度:",T_start)
     T_start = T_start * Q
 print("最优解x是:", init_x)  #这里最初写的是new_x,所以结果一直不对
 print("最优解是:", init_y)
 #比如我加上new_x,真假之间的误差实际就是最后一次的赋值“init_x = new_x”
 print("假最优解x是:", new_x)  #这里最初写的是new_x,所以结果一直不对
 print("假最优解是:", new_y)
 xx = np.linspace(l_boundary,r_boundary,300)
 yy = cal_x2y(xx)
 plt.plot(xx, yy, label='Tuihuo')
 #plt.plot(x2, y2, label='Second Line')
 plt.xlabel('X for tuihuo') #横坐标标题
 plt.ylabel('Y for tuihuo') #纵坐标标题
 #plt.title('Interesting Graph\nCheck it out',loc="right")  #图像标题
 #plt.title('Interesting Graph\nCheck it out')
 plt.legend()  #显示Fisrt Line和Second Line(label)的设置
 plt.savefig('C:/Users/zhengyong/Desktop/1.png')
 plt.show()

这里用了class,发现并不需要,但是不想改了,就这样吧。

最优结果为:

Python退火算法在高次方程的应用 

得出的示意图为:

Python退火算法在高次方程的应用 

三,总结

退火算法的具体思想我没怎么讲,但是核心的点我都写出来了,经过验证发现退火算法得出了(6.551677228904226,-1548.933671426107)的最优解,看看解法二的(6.5,-1549.6875),我们发现,呵呵,差不多,误差来讲的话,能接受,当然读者也可以多跑几个数据出来验证。

我的实验环境是Python3.6,Numpy1.14.3,matplotlib2.2.2,64位win10,1709教育版,OS内核16299.547,就这样吧,尽量讲详细点。

总结

以上所述是小编给大家介绍的Python退火算法在高次方程的应用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
pycharm 使用心得(八)如何调用另一文件中的函数
Jun 06 Python
Python实现获取某天是某个月中的第几周
Feb 11 Python
Python获取网页上图片下载地址的方法
Mar 11 Python
用Python计算三角函数之atan()方法的使用
May 15 Python
python简单获取数组元素个数的方法
Jul 13 Python
Python与R语言的简要对比
Nov 14 Python
python实现学生信息管理系统
Apr 05 Python
解决vscode python print 输出窗口中文乱码的问题
Dec 03 Python
Python使用Pandas对csv文件进行数据处理的方法
Aug 01 Python
浅析pandas 数据结构中的DataFrame
Oct 12 Python
用Python开发app后端有优势吗
Jun 29 Python
Python制作一个仿QQ办公版的图形登录界面
Sep 22 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 #Python
Tensorflow 合并通道及加载子模型的方法
Jul 26 #Python
解决tensorflow测试模型时NotFoundError错误的问题
Jul 26 #Python
tensorflow 恢复指定层与不同层指定不同学习率的方法
Jul 26 #Python
kaggle+mnist实现手写字体识别
Jul 26 #Python
解决tensorflow模型参数保存和加载的问题
Jul 26 #Python
解决tensorflow1.x版本加载saver.restore目录报错的问题
Jul 26 #Python
You might like
关于页面优化和伪静态
2009/10/11 PHP
php基于GD库画五星红旗的方法
2015/02/24 PHP
php实现通用的信用卡验证类
2015/03/24 PHP
WordPress中获取页面链接和标题的相关PHP函数用法解析
2015/12/17 PHP
PHP版微信小店接口开发实例
2016/11/12 PHP
php中请求url的五种方法总结
2017/07/13 PHP
简单实用的PHP文本缓存类实例
2019/03/22 PHP
基于jquery的一行代码轻松实现拖动效果
2010/12/28 Javascript
jQuery中Dom的基本操作小结
2014/01/23 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
微信小程序 前端源码逻辑和工作流详解
2016/10/08 Javascript
利用NPM淘宝的node.js镜像加速nvm
2017/03/27 Javascript
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
vue中v-model动态生成的实例详解
2017/10/27 Javascript
详解Vue中watch的高级用法
2018/05/02 Javascript
vue2.0父子组件间传递数据的方法
2018/08/16 Javascript
vue+axios+mock.js环境搭建的方法步骤
2018/08/28 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
2019/01/30 Javascript
[44:09]DOTA2上海特级锦标赛A组小组赛#1 EHOME VS MVP.Phx第二局
2016/02/25 DOTA
Python 异常处理实例详解
2014/03/12 Python
Django查找网站项目根目录和对正则表达式的支持
2015/07/15 Python
Python下调用Linux的Shell命令的方法
2018/06/12 Python
Python 脚本获取ES 存储容量的实例
2018/12/27 Python
Python flask框架post接口调用示例
2019/07/03 Python
在django-xadmin中APScheduler的启动初始化实例
2019/11/15 Python
django API 中接口的互相调用实例
2020/04/01 Python
美国一家专业的太阳镜网上零售商:Solstice太阳镜
2016/07/25 全球购物
SHEIN台湾:购买最新流行女装服饰
2019/05/18 全球购物
bonprix荷兰网上商店:便宜的服装、鞋子和家居用品
2020/07/04 全球购物
Ajax主要包含了哪些技术
2014/06/12 面试题
行政专员岗位职责
2014/01/02 职场文书
基层党组织整改方案
2014/10/25 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
学校运动会加油词
2015/07/18 职场文书
如何做好工作总结!
2019/04/10 职场文书