Python实现二分法和黄金分割法
运筹学课上,首先介绍了非线性规划算法中的无约束规划算法。二分法和黄金分割法是属于无约束规划算法的一维搜索法中的代表。
二分法:$$x_{1}^{(k+1)}=\frac{1}{2}(x_{R}^{(k)}+x_{L}^{(k)}-\Delta)$$$$x_{2}^{(k+1)}=\frac{1}{2}(x_{R}^{(k)}+x_{L}^{(k)}+\Delta)$$
黄金分割法:$$x_{1}^{(k+1)}=x_{R}^{(k)}-(\frac{\sqrt{5}-1}{2})(x_{R}^{(k)}-x_{L}^{(k)})$$$$x_{2}^{(k+1)}=x_{L}^{(k)}+(\frac{\sqrt{5}-1}{2})(x_{R}^{(k)}-x_{L}^{(k)})$$
选择的$x_{1}^{(k+1)}$和$x_{2}^{(k+1)}$一定满足$$x_{L}^{(k)}<x_{1}^{(k+1)}<x_{2}^{(k+1)}<x_{R}^{(k)}$$
下面确定新的不确定空间$I^{(k+1)}$
情况1:若$f(x_{1}^{(k+1)})>f(x_{2}^{(k+1)})$,则$I^{(k+1)}=\left[x_{L}^{(k)},x_{2}^{(k+1)}\right]$
情况2:若$f(x_{1}^{(k+1)})<f(x_{2}^{(k+1)})$,则$I^{(k+1)}=\left[x_{1}^{(k+1)},x_{R}^{(k)}\right]$
情况3:若$f(x_{1}^{(k+1)})=f(x_{2}^{(k+1)})$,则$I^{(k+1)}=\left[x_{1}^{(k+1)},x_{2}^{(k+1)}\right]$
下面记录下用Python实现二分法和黄金分割法的代码。
二分法:
import math
import numpy as np def anyfunction(x): # 在这里我们定义任意一个指定初始区间内的单峰函数,以x*cos(x)为例
return x*math.cos(x) Low = float(input("Please enter the lowbound: "))
High = float(input("Please enter the highbound: "))
High = np.pi # 在这里我们取初始上界为π,如果可以输入则注释掉这一行
echos = int(input("Please enter the echos: ")) # 迭代次数
small = float(input("Please enter the smallvalue: ")) # 公式中的Delta for i in range(1, echos + 1):
Lowvalue = anyfunction(0.5*(Low + High - small))
Highvalue = anyfunction(0.5*(Low + High + small))
print("echos: " + str(i))
print('before ' + "Lowbound: " + str(0.5*(Low + High - small)) + " Highbound: " + str(0.5*(Low + High + small)))
print('Lowvalue: ' + str(Lowvalue) + ' ' + 'Highvalue: ' + str(Highvalue))
if(Lowvalue == Highvalue):
Low = 0.5*(Low + High - small)
High = 0.5*(Low + High + small)
elif(Lowvalue < Highvalue):
Low = 0.5*(Low + High - small)
else:
High = 0.5*(Low + High + small)
print("Lowbound: " + str(Low) + " Highbound: " + str(High))
输出结果如下:
5次循环后极值点被限制在[0.7828981633974482,0.8907604338221292]内。
黄金分割法:
from math import sqrt, cos
import numpy as np def anyfunction(x): # 同上以函数x*cos(x)为例
return x*cos(x) Low = float(input("Please enter the lowbound: "))
High = float(input("Please enter the highbound: "))
High = np.pi # 同上,使用时应该注释掉
echos = int(input("Please enter the echos: ")) # 初始化,第一次运算不存在运算简化
uniquevalue = ((sqrt(5)-1)/2)*(High-Low)
value1 = anyfunction(High - uniquevalue)
value2 = anyfunction(Low + uniquevalue) for i in range(1, echos + 1):
print("echos: " + str(i))
print('before ' + "Lowbound: " + str(High - uniquevalue) + " Highbound: " + str(Low + uniquevalue))
print('value1: ' + str(value1) + ' ' + 'value2: ' + str(value2))
# 利用黄金分割法的性质减少一半的运算量
if(value1 == value2):
Low = High - uniquevalue
High = Low + uniquevalue
uniquevalue = ((sqrt(5)-1)/2)*(High-Low)
value1 = anyfunction(High - uniquevalue)
value2 = anyfunction(Low + uniquevalue)
elif(value1 < value2):
Low = High - uniquevalue
uniquevalue = ((sqrt(5)-1)/2)*(High-Low)
value1 = value2
value2 = anyfunction(Low + uniquevalue)
else:
High = Low + uniquevalue
uniquevalue = ((sqrt(5)-1)/2)*(High-Low)
value2 = value1
value1 = anyfunction(High - uniquevalue)
print("Lowbound: " + str(Low) + " Highbound: " + str(High))
输出结果如下:
5次循环后极值点被限制在[0.7416294238611398,1.0249066567190932]
Python实现二分法和黄金分割法的更多相关文章
- 利用python实现二分法和斐波那契序列
利用python实现二分法:我的实现思路如下 1.判断要查找的值是否大于最大值,如果大于则直接返回False 2.判断要查找的值是否小于最小值,如果小于则直接返回False 3.如果要查找的值在最大值 ...
- 二分法和牛顿迭代实现开根号函数:OC的实现
最近有人贴出BAT的面试题,题目链接. 就是实现系统的开根号的操作,并且要求一定的误差,其实这类题就是两种方法,二分法和牛顿迭代,现在用OC的方法实现如下: 第一:二分法实现 -(double)sqr ...
- 一些Python的惯用法和小技巧:Pythonic
Pythonic其实是个模糊的含义,没有确定的解释.网上也没有过多关于Pythonic的说明,我个人的理解是更加Python,更符合Python的行为习惯.本文主要是说明一些Python的惯用法和小技 ...
- Todd's Matlab讲义第5讲:二分法和找根
二分法和if ... else ... end 语句 先回顾一下二分法.要求方程\(f(x)=0\)的根.假设\(c = f(a) < 0\)和\(d = f(b) > 0\),如果\(f ...
- Python实现二分查找
老生常谈的算法了. #!/usr/bin/python # -*- coding:utf-8 -*- # Filename: demo.py # 用python实现二分查找 def binarySea ...
- python实现二分查找算法
二分查找算法也成为折半算法,对数搜索算法,一会中在有序数组中查找特定一个元素的搜索算法.搜索过程是从数组中间元素开始的 如果中间元素正好是要查找的元素,则搜索过程结束:如果查找的数大于中间数,则在数组 ...
- python关于二分查找
楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72 ...
- Python递归函数,二分查找算法
目录 一.初始递归 二.递归示例讲解 二分查找算法 一.初始递归 递归函数:在一个函数里在调用这个函数本身. 递归的最大深度:998 正如你们刚刚看到的,递归函数如果不受到外力的阻止会一直执行下去.但 ...
- Python 实现二分查找(递归版)
二分查找 为什么使用二分查找: python中的列表,一般取值为遍历这个列表,直到取到你想要的值,但是如果你的列表是一个有着百万元素的列表呢,那样for循环遍历列表就会很慢,可能会循环几十万次,才能找 ...
随机推荐
- 基于Unity实现油画风格的着色器
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Cust ...
- [Objective-C] 016_UI篇_UIView(上)
在我们使用app时屏幕上能看到的UI元素(按钮,列表,图片...),我们称之为视图,都是继承与UIView,它们通常有着位置,大小,背景颜色等属性,在appl中视图和窗口展示了应用的用户界面,同时负责 ...
- 派生类Student的构造函数和析构函数 代码参考
#include <iostream> #include <cstring> using namespace std; class Person { private: char ...
- Rocket - 断句 - Diplomatic Design Patterns: A TileLink Case Study
https://mp.weixin.qq.com/s/afRVgTCYs1Mxu898uSmVaQ 整理一篇介绍Diplomacy和TileLink的文章. 原文链接: https://carrv ...
- jchdl - RTL实例 - MOS6502 ALU (Verilog)
https://mp.weixin.qq.com/s/jLUz757FQZjMEYzYb2AIww MOS6502是简单,但是曾经相当流行的一款CPU.网上有很多模拟程序可供学习使用.这里使用一个 ...
- ES 或 Solr 分词器的相关面试题:
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.ES 中的 IK 分词器能分中文和英语的原因是什么? ik分词器为中文分词器,默认可对中文分词:通过 ...
- Java实现 LeetCode 722 删除注释(暴力筛选)
722. 删除注释 给一个 C++ 程序,删除程序中的注释.这个程序source是一个数组,其中source[i]表示第i行源码. 这表示每行源码由\n分隔. 在 C++ 中有两种注释风格,行内注释和 ...
- Java实现 LeetCode 303 区域和检索 - 数组不可变
303. 区域和检索 - 数组不可变 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [-2, 0, 3, ...
- Java实现 蓝桥杯VIP 算法训练 传球游戏
[问题描述] 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每 ...
- Java实现莱布尼兹问题
历史上有许多计算圆周率pai的公式,其中,格雷戈里和莱布尼茨发现了下面的公式: pai = 4*(1-1/3+1/5-1/7 -) 参见[图1.png] 这个公式简单而优美,但美中不足,它收敛的太慢了 ...