VBA: 最优化算法(二分法、黄金分割法、循环迭代法)的代码实现
2023-06-13 09:12:58 时间
文章背景:在工程计算中,经常会遇到求解一元非线性方程的问题,如给定一个区间,求解非线性方程的根,或者求最值(最大值或最小值)。下面介绍三种比较简单的算法。
(1)二分法
(2)黄金分割法
(3)循环迭代法
(1)二分法
对于一元非线性方程f(x)=0,如果已经知道在区间[a,b]内,方程存在零点,可以采用二分法
得到x的近似解。如对于f(x)=x^3+x-17,通过作图可以得出,f(x)在区间[0,6]内存在零点。
二分法的程序框图如下:
二分法的代码实现:(function)
Option Explicit
Function Bisection(a As Double, b As Double, fxn As String) As Double
Dim i As Integer, mid As Double, fa As Double, fmid As Double
For i = 1 To 20
mid = (a + b) / 2
fa = Evaluate(Replace(fxn, "x", a))
fmid = Evaluate(Replace(fxn, "x", mid))
If fa * fmid < 0 Then
b = mid
Else
a = mid
End If
Next i
Bisection = FormatNumber((a + b) / 2, 2)
End Function
示例:
=Bisection(0,6,"x^3+x-17")
2.44
(2)黄金分割法
对于一元函数f(x),如果已知在区间[a,b]内,方程存在最小值
,可以采用黄金分割法
得到x的近似解。如对于f(x)=x^2-6x+15,通过作图可以得出,f(x)在区间[0,6]内存在最小值。
黄金分割法的程序框图如下:
黄金分割法的代码实现:(function)
Function GoldenSearch(a As Double, b As Double, fxn As String) As Double
Dim i As Integer, GR As Double, d As Double
Dim x1 As Double, x2 As Double, fx1 As Double, fx2 As Double
GR = (Sqr(5) - 1) / 2
For i = 1 To 20
d = GR * (b - a)
x1 = a + d
x2 = b - d
fx1 = Evaluate(Replace(fxn, "x", x1))
fx2 = Evaluate(Replace(fxn, "x", x2))
If fx1 < fx2 Then
a = x2
Else
b = x1
End If
Next i
GoldenSearch = FormatNumber((a + b) / 2, 2)
End Function
示例:
=GoldenSearch(0,6,"x^2-6*x+15")
3.00
(3)循环迭代法
对于可以转化为x=f(x)形式的一元非线性方程,有时可以采用循环迭代法
,得到x的近似解。
循环迭代法求解的程序框图如下:
循环迭代法的代码实现:(function)
Function Iteration(x As Double, fxn As String) As Double
Dim i As Integer
For i = 1 To 20
x = Evaluate(Replace(fxn, "x", x))
Next i
Iteration = FormatNumber(x, 2)
End Function
示例:(先给定一个初值x,再进行循环迭代计算)
=Iteration(1,"1/sin(x)")
1.11
参考资料:
[1] Excel/VBA for Creative Problem Solving, Part 1(https://www.coursera.org/learn/excel-vba-for-creative-problem-solving-part-1/lecture/vvdl5/implementing-targeting-and-optimization-algorithms-in-vba-subroutines)
相关文章
- Vue之循环遍历
- C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理「建议收藏」
- MySQL存储过程-循环结构
- 面试官:说说Event Loop事件循环、微任务、宏任务
- eventLoop事件循环机制
- while循环导致的CPU暴涨问题优化实践
- 带头双向循环链表增删查改实现(C语言)
- 【Java 虚拟机原理】垃圾回收算法 ( Java 虚拟机内存分区 | 垃圾回收机制 | 引用计数器算法 | 引用计数循环引用弊端 )
- Linux循环遍历目录的简单方法(linux循环目录)
- for循环的特殊写法详解编程语言
- 「MySQL日期循环」:利用MySQL的日期函数实现日期的循环操作(mysql日期循环)
- 处理Linux中日期循环处理技巧(linux日期循环)
- 使用 Oracle 构建循环语句的实战技巧(oracle使用循环语句)
- vs中通过剪切板循环来循环粘贴不同内容
- Smartyforeach控制循环次数的实现详解
- jquery$.each和for怎么跳出循环终止本次循环
- JavaMap的几种循环方式总结