2016-05-30 7 views
3

У меня есть возрастающая математическая функция, например y = x + 5*x^3 + x^7 + 11*ln x и я хочу найти первую (положительную) x такую, что y(x) >= 1478. Могу ли я использовать алгоритм бинарного поиска из stl для решения этой проблемы?Бинарный поиск математической функции

+0

Да, вы можете. Попробуй. – dasblinkenlight

+0

Почему бы не использовать цикл 'for'? – Boiethios

+0

@dasblinkenlight, как я могу его использовать? Я могу написать это сам, но вопрос о stl алгоритмах – Pavel

ответ

2

Проблема в том, что алгоритмы STL (std::lower_bound, вероятно, ваш кандидат на выбор) работают над коллекциями. Или более конкретно: на итераторах коллекций. Один из способов использования их для вашей проблемы - это адаптер: вы пишете «итератор», который просто возвращает значение функции при разыменовании.

Код для этого может быть довольно большим, так как вам необходимо удовлетворить все требования RandomAccessIterator. Однако вы можете запланировать его на своей функции. Пример:

template<class F> 
FuncIterator{ 
    typedef int ParamType; 
    typedef float ResultType; // Or better: result_of F 

    ParamType param_; 
    FuncIterator(ParamType param): param_(param){} 
    ResultType operator*(){ return F(param_); } 
    FuncIterator& operator+=(int diff){ param_ += diff; return *this; } 
    //... Other functions required for RandomAccessIterator 
} 

auto result = std::lower_bound(FuncIterator<MyFunc>(0), FuncIterator<MyFunc>(1000)); 
std::cout << "First x value is:" result.param_ << std::endl; 

Опять же: этот итератор более сложный, чем здесь, но вы должны получить отсюда. Вам нужны некоторые определения и возможные черты. Но вам нужно определить его только один раз и использовать его для любой функции. Он становится более общим, если вы используете std-признаки, чтобы вывести тип параметра и результат F.

Заключительное примечание: двоичный поиск выполняет поиск только в диапазоне! Поэтому вы должны решить этот диапазон при вызове std::lower_bound. Он не может найти «первое значение x с F(x)>=y» для любое x, но только для любого x в заданном диапазоне.

+0

Спасибо за подробный ответ. Таким образом, это не простой способ использовать двоичный поиск из stI, и ручная запись двоичного поиска будет действительно проще, чем создание адаптера, правильно? – Pavel

+1

Да. Бинарный поиск предназначен для заказанных контейнеров. Почему вы хотите сделать, скорее всего, лучше подходит для алгоритма Newtons или аналогичного: Поиск корня функции. В вашем случае: 'y '(x) = y (x) - 1478', а теперь найдите' x' для 'y' (x) = 0' – Flamefire

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