非启发式算法——二分、三分搜索算法

简介: 非启发式算法——二分、三分搜索算法

非启发式算法第一练——二分、三分搜索算法

非启发式算法是一类不依赖于启发式信息或领域知识的问题解决方法。其中,二分搜索和三分搜索算法是两个经典且广泛应用的技术。在本篇博客中,我们将深入了解这两种搜索算法的原理、应用场景以及如何在实际问题中使用它们。

二分搜索算法

原理

二分搜索算法,又称为二分查找,是一种高效的搜索方法。它基于分治思想,适用于已排序的数组或列表。其核心思想是在每一步中将搜索区间缩小一半,直到找到目标或区间为空。

步骤

  1. 确定搜索区间的左右边界。
  2. 计算中间位置的索引。
  3. 检查中间元素是否是目标。
  4. 如果中间元素等于目标,搜索完成。
  5. 如果中间元素大于目标,将搜索区间缩小为左半部分。
  6. 如果中间元素小于目标,将搜索区间缩小为右半部分。
  7. 重复步骤2-6,直到找到目标或区间为空。

应用场景

二分搜索广泛应用于需要在有序数据集中查找元素的场景,例如查找特定值、判定某个条件是否满足等。

示例代码

python

def binary_search(arr, target):
    left, right = 0, len(arr) - 1

    while left <= right:
        mid = (left + right) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return -1  # Target not found

Java 实现

public class BinarySearch {

    // 二分搜索算法
    static int binarySearch(int[] arr, int target) {
        int left = 0, right = arr.length - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;

            if (arr[mid] == target) {
                return mid; // 找到目标,返回索引
            } else if (arr[mid] < target) {
                left = mid + 1; // 缩小搜索区间为右半部分
            } else {
                right = mid - 1; // 缩小搜索区间为左半部分
            }
        }

        return -1; // 目标不在数组中
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int target = 5;

        int result = binarySearch(arr, target);

        if (result != -1) {
            System.out.println("Target found at index: " + result);
        } else {
            System.out.println("Target not found in the array.");
        }
    }
}

C++ 实现

#include <iostream>
#include <vector>

using namespace std;

// 二分搜索算法
int binarySearch(vector<int>& arr, int target) {
    int left = 0, right = arr.size() - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {
            return mid; // 找到目标,返回索引
        } else if (arr[mid] < target) {
            left = mid + 1; // 缩小搜索区间为右半部分
        } else {
            right = mid - 1; // 缩小搜索区间为左半部分
        }
    }

    return -1; // 目标不在数组中
}

int main() {
    vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int target = 5;

    int result = binarySearch(arr, target);

    if (result != -1) {
        cout << "Target found at index: " << result << endl;
    } else {
        cout << "Target not found in the array." << endl;
    }

    return 0;
}

三分搜索算法

原理

三分搜索算法是二分搜索的扩展,用于在凸函数上寻找极值。与二分搜索不同,三分搜索每次将搜索区间分为三个部分,并根据目标函数值的情况确定下一步搜索的方向。

步骤

  1. 确定搜索区间的左右边界。
  2. 计算两个中间点,将搜索区间分为三部分。
  3. 比较两个中间点的函数值。
  4. 根据函数值的情况,确定搜索区间缩小的方向。
  5. 重复步骤2-4,直到满足停止条件。

应用场景

三分搜索主要用于寻找单峰函数的极值点,例如求解凸函数的最小值或最大值。

示例代码

python

def ternary_search(func, left, right, epsilon=1e-9):
    while right - left > epsilon:
        mid1 = left + (right - left) / 3
        mid2 = right - (right - left) / 3

        if func(mid1) < func(mid2):
            right = mid2
        else:
            left = mid1

    return (left + right) / 2

Java 实现

public class TernarySearch {

    // 三分搜索算法
    static double ternarySearch(double left, double right, double epsilon) {
        while (right - left > epsilon) {
            double mid1 = left + (right - left) / 3;
            double mid2 = right - (right - left) / 3;

            double f1 = function(mid1);
            double f2 = function(mid2);

            if (f1 < f2) {
                right = mid2;
            } else {
                left = mid1;
            }
        }

        return (left + right) / 2;
    }

    // 示例函数(替换成需要寻找极值的函数)
    static double function(double x) {
        // 这里替换成实际的函数表达式
        return x * x;
    }

    public static void main(String[] args) {
        double result = ternarySearch(-10, 10, 1e-9);

        System.out.println("The minimum/maximum value is: " + result);
    }
}

C++ 实现

#include <iostream>

using namespace std;

// 三分搜索算法
double ternarySearch(double left, double right, double epsilon) {
    while (right - left > epsilon) {
        double mid1 = left + (right - left) / 3;
        double mid2 = right - (right - left) / 3;

        double f1 = function(mid1);
        double f2 = function(mid2);

        if (f1 < f2) {
            right = mid2;
        } else {
            left = mid1;
        }
    }

    return (left + right) / 2;
}

// 示例函数(替换成需要寻找极值的函数)
double function(double x) {
    // 这里替换成实际的函数表达式
    return x * x;
}

int main() {
    double result = ternarySearch(-10, 10, 1e-9);

    cout << "The minimum/maximum value is: " << result << endl;

    return 0;
}

结语

二分搜索和三分搜索算法是解决一些特定问题的有力工具。它们的高效性和简单性使它们在算法和编程中得到了广泛的应用。通过深入理解这两种搜索算法的原理和应用场景,我们可以更好地运用它们来解决实际问题。在编写代码时,要根据具体问题选择合适的搜索算法,以提高算法效率。

目录
相关文章
|
4月前
|
算法
【算法】二分算法——搜索插入位置
【算法】二分算法——搜索插入位置
|
1月前
|
算法 搜索推荐 数据库
二分搜索:高效的查找算法
【10月更文挑战第29天】通过对二分搜索的深入研究和应用,我们可以不断挖掘其潜力,为各种复杂问题提供高效的解决方案。相信在未来的科技发展中,二分搜索将继续发挥着重要的作用,为我们的生活和工作带来更多的便利和创新。
50 1
|
2月前
|
算法 决策智能
基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数
该程序基于禁忌搜索算法求解车辆路径问题(VRP),使用MATLAB2022a版本实现,并带有GUI界面。用户可通过界面设置参数并查看结果。禁忌搜索算法通过迭代改进当前解,并利用记忆机制避免陷入局部最优。程序包含初始化、定义邻域结构、设置禁忌列表等步骤,最终输出最优路径和相关数据图表。
|
3月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
68 2
|
2月前
|
存储 算法 C++
【搜索算法】 跳马问题(C/C++)
【搜索算法】 跳马问题(C/C++)
|
2月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
4月前
|
机器学习/深度学习 算法 文件存储
【博士每天一篇文献-算法】 PNN网络启发的神经网络结构搜索算法Progressive neural architecture search
本文提出了一种名为渐进式神经架构搜索(Progressive Neural Architecture Search, PNAS)的方法,它使用顺序模型优化策略和替代模型来逐步搜索并优化卷积神经网络结构,从而提高了搜索效率并减少了训练成本。
62 9
|
4月前
|
算法
【算法】递归、搜索与回溯——汉诺塔
【算法】递归、搜索与回溯——汉诺塔
|
4月前
|
存储 机器学习/深度学习 算法
【博士每天一篇文献-综述】基于脑启发的连续学习算法有哪些?附思维导图
这篇博客文章总结了连续学习的分类,包括经典方法(重放、正则化和稀疏化方法)和脑启发方法(突触启发、双系统启发、睡眠启发和模块化启发方法),并讨论了它们在解决灾难性遗忘问题上的优势和局限性。
70 2
|
4月前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介
下一篇
DataWorks