2010-11-26 2 views
2

Я узнал о тройном поиске из Википедии. Я не уверен, что они подразумевают под абсолютной точностью параметра. Они не уточнили. Но вот псевдокод:Коррекция тернарных поисков неверна

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); 
} 

Заранее спасибо.

ответ

2

Абсолютная точность означает максимальную ошибку между возвращенным результатом и истинным результатом, то есть max | returned_result - true_result |. В этом контексте f является непрерывной функцией.

Поскольку вы смотрите на дискретную функцию, вы не можете сделать намного лучше, чем добраться до точки, где right - left <= 1. Затем просто сравните два результирующих значения и верните значение, соответствующее большему (поскольку вы ищете max).

EDIT

Первая точка раздела, будучи математически 2/3*left + right/3, следует дискрети- в ceil(2/3*left + right/3) (так что отношения left < first_third <= last_third < right

Так first_third = (left*2+right)/3 должен быть изменен на first_third = (left*2 + right + 2)/3.

+0

> Поскольку вы смотрите на дискретную функцию, вы не можете сделать намного лучше, чем добраться до пункта>, где right-left <= 1. Затем просто сравните два результирующих значения и верните значение>, соответствующее более крупный (поскольку вы ищете максимум). Благодарим вас, я отредактировал код записи if (right-left <= precval) // Я упустил «precval» глобальную переменную, имеющую значение 1 return (arr [right]> arr [left])? Arr [right ]: обр [влево]; , но он также не дает никакого выхода. – nerd

+0

Вы можете изменить свой вопрос, чтобы включить изменения? когда я трачусь вручную, он работает (последний рекурсивный вызов имеет '(left, right) = (4, 5)'. – lijie

+1

Вот что произошло: в тройном поиске, когда осталось <= 3, вам придется обрабатывать его в базовом случае, в противном случае это может привести к переполнению стека, потому что функция с тем же параметром вызывается снова и снова. [Помните, что в двоичной базе поиска используется значение <= 2) Пример: N = 3 значения равны 0 2 1 first call-> ternary_search (arr, 0, 2) first_third = 0 // Наблюдение left и first_third стало таким же, поэтому вам придется обрабатывать это как базовый регистр, то есть правый-левый <= 2 является базовым. second_third = 1 обр [first_third] <обр [second_third] Таким образом, вы снова звоните ternary_search (обр, 0, 2) – nerd

0

Попробуйте Golden Поиск разделов (или поиск по Фибоначчи для дискретных функций). Он имеет меньшее количество рекурсий и 50% -ное снижение оценки по сравнению с предыдущим тройным поиском.

Смежные вопросы