Trouver les maxima et les minima locaux

14

Définition

Les maxima et les minima d'une fonction donnée sont les valeurs les plus grandes et les plus petites de la fonction soit dans une plage donnée, soit dans le domaine entier de la fonction.

Défi

Le défi est de trouver les maxima et minima locaux d'une fonction polynomiale donnée en utilisant n'importe quelle méthode que vous aimez . Ne vous inquiétez pas, je ferai de mon mieux pour expliquer le défi et le garder aussi simple que possible.

L'entrée contiendra tous les coefficients du polynôme variable unique dans l'ordre de puissance décroissant ou croissant (à vous de choisir). Par exemple,

  • [3,-7,1] représentera 3x2 - 7x + 1 = 0
  • [4,0,0,-3] représentera 4x3-3=0.

Comment résoudre (en utilisant des dérivés)?

Maintenant, disons que notre entrée est [1,-12,45,8], qui n'est rien d'autre que la fonction .x3 - 12x2 + 45x + 8

  1. La première tâche consiste à trouver la dérivée de cette fonction. Puisqu'il s'agit d'une fonction polynomiale, c'est en effet une tâche simple à faire.

    La dérivée de est . Tout terme constant présent avec est simplement multiplié. De plus, s'il y a des termes ajoutés / soustraits, leurs dérivés sont également ajoutés ou soustraits respectivement. N'oubliez pas que la dérivée de toute valeur numérique constante est zéro. Voici quelques exemples: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. Maintenant, résolvez l'équation en égalisant le nouveau polynôme à zéro et obtenez seulement les valeurs intégrales de x.

  3. Mettez ces valeurs de x dans la fonction d'origine et retournez les résultats. Cela devrait être la sortie .

Exemple

Prenons l'exemple que nous avons mentionné précédemment, à savoir [1,-12,45,8].

  • Contribution: [1,-12,45,8]
  • Une fonction: x3 - 12x2 + 45x + 8
  • Dérivé -> 3x2 - 24x + 45 + 0 -> [3,-24,45]
  • Résoudre l'équation , nous obtenons ou .3x2 - 24x + 45 = 0x = 3x = 5
  • Maintenant, en mettant x = 3et x = 5dans la fonction, nous obtenons les valeurs (62,58).
  • Sortie -> [62,58]

Hypothèses

  1. Supposons que tous les coefficients d'entrée sont des entiers . Ils peuvent être dans l'ordre croissant ou décroissant de puissance.

  2. Supposons que l' entrée soit au moins un polynôme à 2 degrés . Si le polynôme n'a pas de solutions entières, vous pouvez renvoyer n'importe quoi.

  3. Supposons que le résultat final sera uniquement des entiers.

  4. Vous pouvez imprimer les résultats dans n'importe quel ordre. Le degré du polynôme d'entrée ne serait pas supérieur à 5, afin que votre code puisse le gérer.

  5. L'entrée sera valide pour que les solutions de x ne soient pas des points de selle.

De plus, vous n'êtes pas obligé de le faire par la méthode dérivée. Vous pouvez utiliser n'importe quelle méthode selon vos envies.

Exemple d'entrée et de sortie

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

Notation

C'est le donc le code le plus court l'emporte.

Manish Kundu
la source
1
Si je comprends bien: dans l'exemple, l'étape " Résoudre l'équation " serait en partie ce défi précédent de vous ? De plus, l'étape " Mettre maintenant x = 3 et x = 5 dans la fonction " signifie la fonction d'origine dans " Fonction " et non la fonction dans " Dérivée ", n'est-ce pas?
Kevin Cruijssen
1
Pour l'exemple d'E / S 3, je reçois (-1, 0, 1), ce qui, je crois, est la vraie réponse correcte ... mais je ne suis pas sûr. Si vous n'êtes pas d'accord avec moi, envoyez-moi un message de chat.
HyperNeutrino
1
The input will be valid so that the solutions of x are not saddle points, l'affaire [1,0,0,3]semble donner un point de selle.
JungHwan Min
1
@JungHwanMin ah cet exemple a été ajouté avant l'établissement de la règle. Supprimé maintenant.
Manish Kundu
1
x^3 - 12x^2 + 45x + 8 = 0 , bien que personnellement je préfère que vous l'écriviez comme f(x)=x^3-12x^2+45x+8sans le =0car =0n'a pas de sens puisque nous avons affaire à une fonction, pas à la résolution d'une équation.
Weijun Zhou

Réponses:

4

Gelée , 20 octets

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

Essayez-le en ligne!

Explication

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.

La fonction d'aide dans ce programme a été tirée de la réponse de M. Xcoder ici qui était basée sur la réponse de Luis ici

HyperNeutrino
la source
@JungHwanMin Je le signalerai à OP. C'est une violation directe de l'affirmation selon laquelle il n'y aura pas de points de selle parce que la dérivée du polynôme à 3est 0. modifier oh vous avez déjà fait nvm vient de voter ensuite le commentaire
HyperNeutrino
3

JavaScript (ES7), 129 120 octets

Prend les coefficients par ordre croissant de puissance.

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

Cas de test

Commenté

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
la source
1
échoue pour 0,0,1(x ^ 2 = 0)
betseg
@betseg Merci d'avoir signalé cela. Fixé.
Arnauld
3

Julia 0.6 (avec Polynomialspackage), 57 octets

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

Essayez-le en ligne!

Prend les coefficients dans l'ordre croissant, c'est-à-dire que la première entrée est le terme constant.

Exemple d'exécution:

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ɪᴋᴇʀ
la source
3

Java 8, 364 239 227 226 218 octets

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

Utilise la même fonctionnalité de ma réponse.

-8 octets grâce à @ OlivierGrégoire en prenant le tableau dans l'ordre inverse.

Explication:

Essayez-le en ligne.

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
Kevin Cruijssen
la source
2
échoue pour 1,0,0(x ^ 2 = 0)
betseg
@betseg Merci! Fixe et golfé.
Kevin Cruijssen
1
Vous devez accepter l'entrée dans l' ordre inverse (il est explicitement autorisé) de réduire votre nombre comme ceci: int... ,i, ...; for(;f>0;)A[--f]*=f;. Sauf erreur, cela devrait vous faire économiser au moins 4 octets. Si vous faites cela, assurez-vous d'inverser tous vos accès à l'entrée.
Olivier Grégoire
@ OlivierGrégoire Merci, 8 octets économisés!
Kevin Cruijssen
2

Haskell , 89 octets

-3 octets grâce à Laikoni.

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

Essayez-le en ligne!

Prend les coefficients inversés.

totalement humain
la source
2
d<-tail$peut être raccourci _:d<-.
Laikoni
1

Python 3 , 156 octets

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]

Essayez-le en ligne!

-2 octets grâce à M. Xcoder
-22 octets grâce aux ovs

HyperNeutrino
la source
1

Python + numpy, 91

  • 1 octet enregistré grâce à @KevinCruijssen
from numpy import*
p=poly1d(input())
print map(lambda x:int(polyval(p,x)),roots(p.deriv()))

Essayez-le en ligne .

Traumatisme numérique
la source