Найти местные максимумы и минимумы

14

Определение

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

Вызов

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

На входе будут содержаться все коэффициенты полинома от одной переменной в порядке убывания или увеличения мощности (на ваше усмотрение). Например,

  • [3,-7,1] будет представлять 3x2 - 7x + 1 = 0
  • [4,0,0,-3] будет представлять 4x3-3=0.

Как решить (используя производные)?

Теперь, скажем, наш ввод - [1,-12,45,8]это не что иное, как функция .x3 - 12x2 + 45x + 8

  1. Первая задача - найти производную этой функции. Поскольку это полиномиальная функция, то это действительно простая задача.

    Производная IS . Любые постоянные термины, присутствующие с , просто умножаются. Кроме того, если есть добавленные / вычтенные термины, то их производные также будут добавлены или вычтены соответственно. Помните, что производная от любого постоянного числового значения равна нулю. Вот несколько примеров:xnn*xn-1xn

    • x3 -> 3x2
    • 9x4 -> 9*4*x3 = 36x3
    • -5x2 -> -5*2*x = - 10x
    • 2x3 - 3x2 + 7x -> 6x2 - 6x + 7
    • 4x2 - 3 -> 8x - 0 = 8x
  2. Теперь решите уравнение, приравнивая новый многочлен к нулю и получите только целые значения x.

  3. Поместите эти значения x в исходную функцию и верните результаты. Это должно быть выходной .

пример

Возьмем в качестве примера мы упоминали ранее, то есть [1,-12,45,8].

  • Входные данные: [1,-12,45,8]
  • Функция: x3 - 12x2 + 45x + 8
  • Производная -> 3x2 - 24x + 45 + 0 -> [3,-24,45]
  • Решая уравнение , получаем или .3x2 - 24x + 45 = 0x = 3x = 5
  • Теперь, поместив x = 3и x = 5в функцию, мы получим значения (62,58).
  • Выход -> [62,58]

Предположения

  1. Предположим, что все входные коэффициенты являются целыми числами . Они могут быть в порядке увеличения или уменьшения мощности.

  2. Предположим, что входное значение является по крайней мере 2-градусным полиномом . Если у полинома нет целочисленных решений, вы можете вернуть что угодно.

  3. Предположим, что конечный результат будет только целыми числами.

  4. Вы можете распечатать результаты в любом порядке. Степень входного полинома не должна превышать 5, чтобы ваш код мог с этим справиться.

  5. Ввод будет действительным, так что решения х не являются седловыми точками.

Кроме того, вы не обязаны делать это по производному методу. Вы можете использовать любой метод, который вам нравится.

Пример ввода и вывода

[2,-8,0] -> (-8)
[2,3,-36,10] -> (91,-34)
[1,-8,22,-24,8] -> (-1,0,-1) 
[1,0,0] -> (0)

счет

Это поэтому выигрывает самый короткий код.

Маниш Кунду
источник
1
Если я правильно понимаю: в примере шаг « Решение уравнения » будет частично этой предыдущей задачей с вашей стороны ? Кроме того, шаг « Теперь положить x = 3 и x = 5 в функцию » означает исходную функцию в « Function », а не функцию в « Derivative », верно?
Кевин Круйссен
1
Для примера ввода / вывода 3 я получаю (-1, 0, 1), что я считаю правильным ответом ... хотя не уверен. Если вы не согласны со мной, напишите мне в чате.
HyperNeutrino
1
The input will be valid so that the solutions of x are not saddle pointsСлучай, [1,0,0,3]кажется, дает седловую точку.
JungHwan Мин
1
@JungHwanMin ах, этот пример был добавлен до того, как было сделано правило. Удалено сейчас.
Маниш Кунду
1
x^3 - 12x^2 + 45x + 8 = 0 , хотя лично я предпочитаю, чтобы вы написали это как f(x)=x^3-12x^2+45x+8без, =0потому =0что не имеет смысла, так как мы имеем дело с функцией, а не решением уравнения
Вейцзюнь Чжоу,

Ответы:

4

Желе , 20 байт

ASŒRḅ@Ðḟ
J’U×µṖÇḅ@€³

Попробуйте онлайн!

объяснение

ASŒRḅ@Ðḟ     Helper Function; find all integer solutions to a polynomial
             All integer roots are within the symmetric range of the sum of the absolute values of the coefficients
A            Absolute Value (Of Each)
 S           Sum
  ŒR         Symmetric Range; `n -> [-n, n]`
      Ðḟ     Filter; keep elements where the result is falsy for:
    ḅ@       Base conversion, which acts like the application of the polynomial
J’U×µṖÇḅ@€³  Main Link
J                             Range of length
 ’                    Lowered
  U          Reversed
   ×         Multiplied with the original list (last value is 0)
    µ        Begin new monadic chain
     Ṗ       Pop; all but the last element
      Ç      Apply last link (get all integer solutions of the derivative)
       ḅ@€³  Base conversion of the polynomial into each of the solutions; apply polynomial to each solution of the derivative.

Вспомогательная функция в этой программе была взята из ответа г-на Xcoder здесь, который был основан на ответе Луиса здесь

HyperNeutrino
источник
@JungHwanMin Я укажу это на OP. Это прямое нарушение утверждения о том, что не будет седловых точек, потому что производная полинома at 3равна 0. редактировать о, вы уже сделали nvm, просто проголосовали за комментарий тогда
HyperNeutrino
3

JavaScript (ES7), 129 120 байт

Принимает коэффициенты в порядке возрастания мощности.

a=>(g=x=>x+k?(A=g(x-1),h=e=>a.reduce((s,n,i)=>s+n*(e||i&&i--)*x**i,0))()?A:[h(1),...A]:[])(k=Math.max(...a.map(n=>n*n)))

Контрольные примеры

комментарии

a => (                        // given the input array a[]
  g = x =>                    // g = recursive function checking whether x is a solution
    x + k ? (                 //   if x != -k:
      A = g(x - 1),           //     A[] = result of a recursive call with x - 1
      h = e =>                //     h = function evaluating the polynomial:
        a.reduce((s, n, i) => //       for each coefficient n at position i:
          s +                 //         add to s
          n                   //         the coefficient multiplied by
          * (e || i && i--)   //         either 1 (if e = 1) or i (if e is undefined)
          * x**i,             //         multiplied by x**i or x**(i-1)
          0                   //         initial value of s
        )                     //       end of reduce()
      )() ?                   //     if h() is non-zero:
        A                     //       just return A[]
      :                       //     else:
        [h(1), ...A]          //       prepend h(1) to A[]
    :                         //   else:
      []                      //     stop recursion
  )(k = Math.max(             // initial call to g() with x = k = maximum of
    ...a.map(n => n * n)      // the squared coefficients of the polynomial
  ))                          // (Math.abs would be more efficient, but longer)
Arnauld
источник
1
терпит неудачу для 0,0,1(x ^ 2 = 0)
betseg
@betseg Спасибо за сообщение об этом. Исправлена.
Арнаулд
3

Юлия 0,6Polynomialsпакетом), 57 байт

using Polynomials
x->map(Poly(x),roots(polyder(Poly(x))))

Попробуйте онлайн!

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

Пример выполнения:

julia> using Polynomials

julia> g = x -> map(Poly(x), roots(polyder(Poly(x))))
(::#1) (generic function with 1 method)

julia> g([8,45,-12,1])
2-element Array{Float64,1}:
 58.0
 62.0
Rɪᴋᴇʀ
источник
3

Java 8, 364 239 227 226 218 байт

a->{int l=a.length,A[]=a.clone(),s=0,i,r,f=l,p;for(;f>0;A[--f]*=f);for(int n:A)s+=n<0?-n:n;for(r=~s;r++<s;){for(p=0,i=f=1;i<l;f*=r)p+=A[i++]*f;if(p==0){for(f=i=0;i<l;f+=a[i++]*Math.pow(r,p++));System.out.println(f);}}}

Использует ту же функциональность из этого моего ответа.

-8 байт благодаря @ OlivierGrégoire , приняв массив в обратном порядке.

Объяснение:

Попробуйте онлайн.

a->{                  // Method with integer-varargs parameter and integer return-type
  int l=a.length,     //  The length of the input-array
      A[]=a.clone(),  //  Copy of the input-array
      s=0,            //  Sum-integer, starting at 0
      i,              //  Index-integer
      r,              //  Range-integer
      f=l,            //  Factor-integer, starting at `l`
      p;              //  Polynomial-integer
  for(;f>0;           //  Loop over the copy-array
    A[--f]*=f);       //   And multiply each value with it's index
                      //   (i.e. [8,45,-12,1] becomes [0,45,-24,3])
  for(int n:A)        //  Loop over this copy-array:
    s+=n<0?-n:n;      //   And sum their absolute values
  for(r=~s;r++<s;){   //  Loop `r` from `-s` up to `s` (inclusive) (where `s` is the sum)
    for(p=0,          //   Reset `p` to 0
        i=f=1;        //   and `f` to 1
                      //   (`i` is 1 to skip the first item in the copy-array)
        i<l;          //   Inner loop over the input again, this time with index (`i`)
        f*=r)         //     After every iteration: multiply `f` with the current `r`
      p+=             //    Sum the Polynomial-integer `p` with:
         A[i++]       //     The value of the input at index `i`,
               *f;}   //     multiplied with the current factor `f`
    if(p==0){         //   If `p` is now 0:
      for(f=i=0;      //    Use `f` as sum, and reset it to 0
          i<l;        //    Loop over the input-array
        f+=a[i++]*Math.pow(r,p++));
                      //     Fill in `r` in the parts of the input-function
      System.out.println(f);}}}
                      //    And print the sum
Кевин Круйссен
источник
2
терпит неудачу для 1,0,0(x ^ 2 = 0)
betseg
@betseg Спасибо! Исправлена ​​и игра в гольф.
Кевин Круйссен
1
Вы должны принимать входные данные в обратном порядке (это явно разрешено) , чтобы уменьшить количество , как это: int... ,i, ...; for(;f>0;)A[--f]*=f;. Если я не ошибаюсь, это должно сэкономить как минимум 4 байта. Если вы сделаете это, обязательно инвертируйте все свои обращения к входу.
Оливье Грегуар
@ OlivierGrégoire Спасибо, 8 байтов сохранено!
Кевин Круйссен
2

Haskell , 89 байт

-3 байта благодаря Лайкони.

r#l=foldr1((.(r*)).(+))l
r l|_:d<-zipWith(*)[0..]l,t<-sum$abs<$>d=[i#l|i<-[-t..t],i#d==0]

Попробуйте онлайн!

Принимает коэффициенты в обратном порядке.

totallyhuman
источник
2
d<-tail$можно сократить до _:d<-.
Лайкони
1

Python 3 , 156 байт

def f(p,E=enumerate):a=lambda p,v:sum(e*v**i for i,e in E(p));d=[e*i for i,e in E(p)][1:];r=sum(map(abs,d));return[a(p,x)for x in range(-r,r+1)if a(d,x)==0]

Попробуйте онлайн!

-2 байта благодаря Mr. Xcoder
-22 байта благодаря ovs

HyperNeutrino
источник
1

Python + NumPy, 91

  • 1 байт сохранен благодаря @KevinCruijssen
from numpy import*
p=poly1d(input())
print map(lambda x:int(polyval(p,x)),roots(p.deriv()))

Попробуйте онлайн .

Цифровая травма
источник