概述
略
网上有很多对二分法的介绍,这里不再多做赘述。
本文为《非线性最优化》中二分法的Python实现。但是目前此代码仅适用于单谷凹函数,可求函数所对应导数的根、根所在区间、x为何值时函数取最值。
稍加修改可求函数最值。
代码展示
from sympy import *
pre_function = input('\n***注意!此函数为测试课本《非线性最优化》二分法,目前只适用于 单谷凹函数 (如函数x**2)!!***\n请输入函数:')
# 求导
x = Symbol("x")
aft_function = diff(pre_function, x)
print(f'函数{pre_function}的一阶导数为:{aft_function}')
# 定义全局变量a, b
a = 0
b = 0
def qiudaoshuzhi(fun, num):
"""求导数值"""
result = float(fun.subs({
x: num}))
print(f'当前一阶导数值为:{result}')
return result
def suan1(t0, h, fun):
"""寻找区间1"""
t1 = t0 + h
result1 = qiudaoshuzhi(fun, t1)
if result1 == 0:
t = t1
print(f'x = {t}时是此函数最值')
exit()
elif result1 > 0:
global a
global b
a = t0
b = t1
return print(f'此函数的根所在区间为[{a},{b}]')
elif result1 < 0:
t0 = t1
suan1(t0, h, fun)
def suan2(t0, h, fun):
"""寻找区间2"""
t1 = t0 - h
result2 = qiudaoshuzhi(fun, t1)
if result2 == 0:
t = t1
print(f'x = {t}时是此函数最值')
exit()
elif result2 < 0:
global a # 修改全局变量
global b
a = t1
b = t0
return print(f'此函数的根所在区间为[{a}, {b}]')
elif result2 > 0:
t0 = t1
suan2(t0, h, fun)
def suan3(num1, num2):
"""二分"""
return float((num1 + num2)/2)
def suan4(num1, num2, fun):
"""求局部极值x坐标"""
e = 0.001 # 误差
c = suan3(num1, num2)
result3 = qiudaoshuzhi(fun, c)
if result3 == 0:
t = round(c)
return print(f'x = {t}时是此函数最值')
elif result3 < 0:
a = c
if abs(a-num2) < e:
t = round(suan3(a, num2))
return print(f'x = {t}时是此函数最值')
else:
suan4(a, num2, fun)
elif result3 > 0:
b = c
if abs(num1-b) < e:
t = round(suan3(num1, b))
return print(f'x = {t}时是此函数最值')
else:
suan4(num1, b, fun)
def quedingqujian(fun):
print('---开始寻找区间----')
t0 = 12
h = 5
result = qiudaoshuzhi(fun, t0)
if result == 0:
t = t0
print(f'x = {t}时是此函数最值')
exit()
elif result < 0:
suan1(t0, h, fun)
elif result > 0:
suan2(t0, h, fun)
def dichotomy(fun):
suan4(a, b, fun)
quedingqujian(aft_function)
print(f'{a},{b}') # 测试全局变量
dichotomy(aft_function)
运行结果展示
总结
以上是编程之家为你收集整理的非线性最优化之二分法Python实现全部内容,希望文章能够帮你解决非线性最优化之二分法Python实现所遇到的程序开发问题。
如果您也喜欢它,动动您的小指点个赞吧