【问题标题】:Ternary search recursion isn't correct三元搜索递归不正确
【发布时间】:2010-11-26 02:01:45
【问题描述】:

我从 Wikipedia 了解了三元搜索。我不确定参数绝对精度是什么意思。他们没有详细说明。但这里是伪代码:

def ternarySearch(f, left, right, absolutePrecision):
    #left and right are the current bounds; the maximum is between them
    if (right - left) < absolutePrecision:
        return (left + right)/2

    leftThird = (2*left + right)/3
    rightThird = (left + 2*right)/3

    if f(leftThird) < f(rightThird):
        return ternarySearch(f, leftThird, right, absolutePrecision)

    return ternarySearch(f, left, rightThird, absolutePrecision)

我想从单峰函数中找到最大值。这意味着我想打印递增和递减序列的边界点。如果序列是

1 2 3 4 5 -1 -2 -3 -4

然后我想打印 5 作为输出。

这是我的尝试。它没有输出。能否请您帮忙或给我链接,其中包含关于自学的三元搜索的好教程?

#include<iostream>

using namespace std;
int ternary_search(int[], int, int, int);
int precval = 1;

int main()
{
    int n, arr[100], target;
    cout << "\t\t\tTernary Search\n\n" << endl;
    //cout << "This program will find max element in an unidomal array." << endl;
    cout << "How many integers: "; 
    cin >> n;
    for (int i=0; i<n; i++)
        cin >> arr[i];
    cout << endl << "The max number in the array is: ";
    int res = ternary_search(arr,0,n-1,precval)+0;
    cout << res << endl;
    return 0;
}

int ternary_search(int arr[], int left, int right, int precval)
{
    if (right-left <= precval)
        return (arr[right] > arr[left]) ? arr[right] : arr[left];
    int first_third = (left * 2 + right) / 3;
    int last_third = (left + right * 2) / 3;
    if(arr[first_third] < arr[last_third])
        return ternary_search(arr, first_third, right, precval);
    else
        return ternary_search(arr, left, last_third, precval);
}

提前谢谢你。

【问题讨论】:

    标签: algorithm search


    【解决方案1】:

    绝对精度是指返回结果与真实结果之间的最大误差,即max | returned_result - true_result |。在这种情况下,f 是一个连续函数。

    由于您正在查看一个离散函数,因此您没有比达到right - left &lt;= 1 更好的方法了。然后,只需比较两个结果值并返回对应于较大值的值(因为您正在寻找max)。

    编辑

    第一个分区点,数学上为2/3*left + right/3,应离散化为ceil(2/3*left + right/3)(因此关系为left &lt; first_third &lt;= last_third &lt; right

    所以first_third = (left*2+right)/3应该改为first_third = (left*2 + right + 2)/3

    【讨论】:

    • >因为您正在查看一个离散函数,所以最好的方法就是到达右 - 左 点。然后,只需比较两个结果值并返回>value 对应于较大的值(因为您正在寻找最大值)。谢谢,我编辑了代码编写 if(right-leftarr[left])?arr[right]:arr[剩下];但它也没有给出任何输出。
    • 您可以编辑您的问题以包含更改吗?当我手动跟踪时,它可以工作(最后一个递归调用有(left, right) = (4, 5)
    • 发生了什么事:在三元搜索中,当剩下 ternary_search(arr , 0, 2) first_third = 0 // 观察 left 和 first_third 已经变得相同,所以你必须将其作为基本情况处理,即 right-left
    • 我明白了。是的,您评论后半部分的推理是正确的。
    • 哦,你是对的。嗯。实际上解决它的另一种方法是以另一种方式计算三分之一......我将编辑我的解决方案。
    【解决方案2】:

    尝试黄金分割搜索(或离散函数的斐波那契搜索)。 与上述三元搜索相比,它的递归次数更少,对 f 的评估减少了 50%。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-10
      • 2019-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 2013-06-26
      相关资源
      最近更新 更多