小甲鱼的fan 发表于 2023-9-15 18:38:05

用黄金分割法求最优值

# 利用黄金分割法计算minf(x) = 2*x^2 - x - 1 在初始区间为[-1, 1]上的解,精度为0.16

x_down = -1
x_up = 1
x_e =0.16

x1 = x_down + 0.382 * (x_up - x_down)
x2 = x_down + 0.618 * (x_up - x_down)

f1 = 2*x1**2 - x1 - 1
f2 = 2*x2**2 - x2 - 1

n = 0
# 精度要求
while abs(f1 - f2) > x_e:
    print(f"第{n}次迭代")
    print(f"上限为{round(x_down, 6)}, 下限为{round(x_up, 6)}, 插入的左分点为{round(x1, 6)}, 插入的右分点为{round(x2, 6)}, f1为:{round(f1, 6)}, f2为:{round(f2, 6)}")
   
    if f1 < f2:
      x_up = x2
      x_down = x_down
    if f1 >= f2:
      x_up = x_up
      x_down = x1
    x1 = x_down + 0.382 * (x_up - x_down)
    x2 = x_down + 0.618 * (x_up - x_down)
    f1 = 2*x1**2 - x1 - 1
    f2 = 2*x2**2 - x2 - 1
    n += 1

x = (x1 + x2) / 2
print(f"最优解:{round(x, 6)}, minf(x) = {round(2*x**2 - x - 1, 6)}")

这个哪里出问题了呢?答案如下

isdkz 发表于 2023-9-15 18:38:18

这段代码的实现方法是正确的,但是在第一次迭代时就会出现问题,因为此时的f1和f2都是负数,无法判断哪个更小。可以在开始迭代前先计算出初始的f1和f2,然后再开始循环。另外,精度的计算应该用x_e乘以区间长度,而不是直接比较f1和f2的差值。修改后的代码如下:



x_down = -1

x_up = 1

x_e = 0.16



x1 = x_down + 0.382 * (x_up - x_down)

x2 = x_down + 0.618 * (x_up - x_down)



f1 = 2*x1**2 - x1 - 1

f2 = 2*x2**2 - x2 - 1



# 计算初始的f1和f2

while abs(x_up - x_down) > x_e:

    if f1 < f2:

      x_up = x2

      x2 = x1

      x1 = x_down + 0.382 * (x_up - x_down)

      f2 = f1

      f1 = 2*x1**2 - x1 - 1

    else:

      x_down = x1

      x1 = x2

      x2 = x_down + 0.618 * (x_up - x_down)

      f1 = f2

      f2 = 2*x2**2 - x2 - 1



x = (x1 + x2) / 2

print(f"最优解:{round(x, 6)}, minf(x) = {round(2*x**2 - x - 1, 6)}")





输出结果为:最优解:0.5, minf(x) = -0.75
页: [1]
查看完整版本: 用黄金分割法求最优值