斐波那契搜索是一种基于比较的算法.它使用斐波那契数列来搜索有序数组中的元素.斐波那契算法是基于分治算法的二分搜索算法的另一种变体.
1.原理:
1.1定义两个变量.Fm和Fm-1.其中Fm是第m个斐波那契数.m-1是第m-1个.令m为Fm大于或等于数组长度的最小整数.
1.2将offset和index两个变量初始化为0.并将mid设置为min(offset+Fm-1,n-1).
1.3如果mid索引处的元素等于查找元素.则返回mid.
1.4如果查找元素小于mid索引处元素.则丢弃mid+1~n-1的元素.将Fm-2设置为Fm-1.将Fm-1设置为Fm-Fm-2.将mid设置为min(offset+Fm-2,n-1).
1.5重复步骤3-5直到找到元素或数组末尾.
2.使用场景:
优化:
斐波那契算法可用于在给定区间内找到函数的最优值..可用于优化产品设计或为机器学习模型寻找最佳参数.
数据分析:
斐波那契搜索算法可用于在大型数据集中搜索特定数据点.当数据按待定顺序排序时.效果最明显.
机器学习:
斐波那契搜索算法可用于优化机器学习模型的超参数.可以帮助提高模型的性能并减少过度拟合.
3.实现:
3.1方法:
package data
func FibonacciSearch(array []int) []int {
if len(array) < 2 {
return array
}
//创建一个覆盖数组长度的斐波那契队列.
fibM2, fibM1, fibM := 0, 1, 1
for fibM < len(array) {
fibM2, fibM1 = fibM1, fibM
fibM = fibM1 + fibM2
}
offset := -1
for fibM2 > 1 {
i := min2(offset+fibM2-fibM1, len(array)-1)
if i > 0 && array[i] < array[offset+fibM2-fibM1] {
fibM2, fibM1 = fibM1, fibM2-fibM1
offset = i
} else {
fibM2, fibM1 = fibM2-fibM1, fibM1
}
}
//使用插入排序对数组进行排序.
for i := offset + 1; i < len(array); i++ {
tmp := array[i]
j := i - 1
for j >= 0 && array[j] > tmp {
array[j+1] = array[j]
j--
}
array[j+1] = tmp
}
return array
}
func min2(x, y int) int {
if x < y {
return x
}
return y
}
3.2main方法:
func main() {
array := []int{66, 8, 88, 55, 5, 28}
search := data.FibonacciSearch(array)
fmt.Printf("search array %v\n", search)
}
4.实战:
4.1方法:
func min2(x, y int) int {
if x < y {
return x
}
return y
}
func FirstBadVersion(n int) int {
fibM2 := 0
fibM1 := 1
fibM := fibM2 + fibM1
//找到大于或等于n的最小斐波那契数.
for fibM < n {
fibM2 = fibM1
fibM1 = fibM
fibM = fibM1 + fibM2
}
index := -1
//使用斐波那契数列执行搜索.
for fibM > 1 {
//计算指标
i := min2(index+fibM2, n-1)
//如果当前没有错误.则丢弃左侧部分向右移动.
if !isBadVersion(i) {
fibM = fibM1
fibM1 = fibM2
fibM2 = fibM - fibM1
index = i
} else {
fibM = fibM2
fibM1 = fibM1 - fibM2
fibM2 = fibM - fibM1
}
}
if fibM1 > 0 && index < (n-1) && isBadVersion(index+1) {
return index + 1
}
return n
}
func isBadVersion(i int) bool {
return i >= 5
}
4.2main方法:
func main() {
n := 8
version := data.FirstBadVersion(n)
fmt.Printf("Version: %v \n", version)
}
东风不与周郎便.
如果大家喜欢我的分享的话.可以关注我的微信公众号
念何架构之路