2013-03-24 1 views
1

Как получить максимальное значение функции в определенном диапазоне с помощью php. Например, у меня есть функция:Найти максимальное значение функции с помощью php

function f($x){ 
    return pow($x,2); 
} 

и я хочу, чтобы получить максимальное значение этой функции в интервале (-1,1). Как я могу реализовать это в php или с помощью какой-либо другой библиотеки?

+0

Вы не можете обобщить проблему, поэтому попробуйте найти аналитический метод для поиска глобального максимума: http://en.wikipedia.org/wiki/Maxima_and_minima – Athlan

ответ

2

Нет общего способа сделать это; вы должны сами делать математику.

Проблемы с максимизацией/минимизацией решаются путем дифференциации. В этом случае вы получите:

d(x^2)/dx = 2*x 

Метод расчета дифференциала зависит от вашей функции. Это не так сложно для простых функций, подобных этому, и Wolfram Alpha (http://www.wolframalpha.com/) сделает это за вас, если вы попробуете его красиво (http://www.wolframalpha.com/input/?i=d%28x%5E2%29%2Fdx).

Тогда вы установили, что к 0, что говорит вам, когда градиент 0 (и, следовательно, он находится на максимальной, минимальной, или точкой поворота):

2*x = 0 

Это говорит о том, что у вас есть пункт для проверки на x = 0 (см. раздел «решение» здесь: http://www.wolframalpha.com/input/?i=d%28x%5E2%29%2Fdx%3D0). Теперь проверьте значение вашей функции на нижней границе, верхней границе и точке (точках), которая указывает вам проверить и получить максимум/минимум всех этих результатов. Это будет ваш лимит в этом диапазоне.

+0

проблема в том, что я не знаю точной формы функции, он создается в соответствии с пользовательским вводом. –

+0

Вы знаете общую форму? Существуют алгебраические способы решения многих общих функций. Например, 'a * x^b + c * x^d' =>' a * b * x^(b-1) + c * d * x^(d-1) '. Основные правила легко усваиваются и реализуются (конечно, Alpha может идти дальше *, но они строили это на протяжении десятилетий). – Dave

+0

Обычно используемый метод заключается в приближении градиента путем проверки нескольких точек вокруг начальной точки (и вы должны повторять этот метод много раз для разных начальных точек), затем следуйте за градиентом до * локального максимума/минимума *. Это довольно сложно. Например, вы можете найти нули, которые находятся рядом с начальной точкой, применяя метод Ньютона: http://en.wikipedia.org/wiki/Newton's_method#Description – Dave

0
$maximumValue = -999999999; 
for ($i = -1; $i <= 1; $i++) { 
    $maximumValue = max($maximumValue, f($i)); 
} 
var_dump($maximumValue); 

..should отлично работает

Это будет проверять только для чисел -1, 0 и 1. Если вы хотите больше точности, просто измените, например, $i++. $i += 0.1:

$maximumValue = -999999999; 
for ($i = -1; $i <= 1; $i += 0.1) { 
    $maximumValue = max($maximumValue, f($i)); 
} 
var_dump($maximumValue); 

Это даст вам -1, -0.9, -0.8 ..... 0.8, 0.9 и 1.

Его также можно заменить на $i += 0.000000001, если вы хотите потратить много ресурсов, но получите более точный результат.

+0

Это только найдет его, если оно окажется целым. Обычно это не так. – Dave

+0

@Dave Это правда, но я предположил, что OP хочет, чтобы он мог подключаться к любой функции. Конечно, '$ i ++' можно было бы изменить на '$ i + = 0,00001', если бы захотели. – h2ooooooo

+0

@Dave: 'pow' всегда будет возвращать int или float,' max' будет отличать и сравнивать правильноAFAIK –

0

Если вы используете дифференциацию, вам нужно иметь дело с случаем отсутствия локальных оптимумов. Если функция является гладкой, это будет означать, что оптические объекты встречаются на конечных точках. Я не уверен, насколько точно это все должно быть, но, возможно, если функция задана только конечным списком пар, вы можете отсортировать список, содержащий все точки, где определена функция.

+0

Нет, это бесконечно: он определен на сегменте [0,1]. Я знаю только, что это одна переменная и непрерывна на [0,1]. –

+0

Если вы знаете, что его непрерывная ошибка. Затем выберите n так, чтобы 1/n было меньше ошибки. Теперь разделите интервал так: –

+0

Если вы знаете, что его непрерывный выбор ошибки. Затем выберите n так, чтобы 1/n было меньше ошибки. Теперь разделим интервал так [0, 1/2, 2/n, ..., 1]. Теперь определим список L = [f (0), f (1/2), ..., f (1)] и отсортируйте этот список. Заметим, что функция, непрерывная на компактном интервале, равномерно непрерывна, поэтому это разумно. (Однородно непрерывное означает, что для некоторой желаемой ошибки в диапазоне существует одно число delta такое, что если | x-y |