Python implementation of dichotomy in nonlinear optimization

Algorithm principle

slightly

dichotomy

There are many introductions to the dichotomy on the Internet, so I won't repeat them here.

This article is the Python implementation of the dichotomy in "Nonlinear Optimization". But at present, this code is only applicable to the single-valley concave function. It can find the root of the derivative corresponding to the function, the interval where the root is located, and what value of x is the maximum value of the function.
With a little modification, the maximum value of the function can be found.

code display

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)

Display of running results

insert image description here

Guess you like

Origin blog.csdn.net/weixin_44097539/article/details/111682900