MattF
(usa Slackware)
Enviado em 05/12/2015 - 19:50h
unnslacker escreveu:
Isso envolve mais matemática do que programação em si (já que esta parte é fácil);
Sabendo efetuar divisões e testes com restos (pra ver se um número é ou não divisível por outro) no C você resolve este problema;
O que você tem que fazer é usar o Teorema das raízes racionais;
Vou dar uma resumida: todo polinômio (TODO, desde que não seja nulo) tem a "cara" ax^n + bx^n-1 + cx^n-2 + ... + dx + e, onde a é o coeficiente dominante (com o x de maior grau - logo, o grau do polinômio) e e o coeficiente constante (sem o x);
O que o teorema diz é que as raízes de um polinômio de grau N é(são) aqueles na forma p/q, onde p é divisível por e (o coeficiente constante) e q é divisível por a (o coeficiente dominante), de modo que todos os valores possíveis entre p e q formem "pares" entre si e que o MDC entre eles seja igual a 1;
Depois de determinar as raízes (são várias), é só jogar no X do polinômio e resolver; se a resposta for 0 é que o valor é, de fato, a raiz do polinômio, se não der 0, não é raiz. Nota: o número de raízes de um polinômio é sempre igual ao valor do seu grau (mas pode existir raiz dupla, tripla e por aí vai)
Não sei se você sabe disso ou não, mas falei porque é assim que eu faria este programa; não sei também se o header <math.h> inclui funções próprias para trabalhar com polinômios, mas se tiver, simplificaria muito. Por fim, qualquer dúvida é só postar (inclusive não sei se o que eu respondi é o que você realmente precisa)
---
~$ seq -f '4/%g' 1 2 99999 | paste -sd-+ | bc -l
Gostaria de fazer uma pequena correção. O teorema correto seria: dado um polinômio da forma ax^n + bx^(n-1) + .....cx+q=0;
caso existam raízes inteiras ou fracionárias(racionais) elas serão da forma Dq/Dn onde Dq são divisores de q e Dn são divisores de n. Ou seja, não há obrigatoriedade das raízes serem dessa forma, e se alguma for, as outras raízes não precisam ser porque elas podem ser irracionais, mesmo que a, b, c, ....q sejam inteiros(a exigência é que eles sejam reais). Desta forma seu programa estaria incompletíssimo se usasse somente esse teorema, mas nada te impede de implementá-lo com isso.
Já fiz exatamente isso que você quer usando python, mas não usei nenhuma biblioteca ou coisa do tipo, tentei construir minha lógica. A melhor solução que achei foi mais ou menos assim:
Limite o usuário para encontrar as soluções em um intervalo e com uma determinada precisão. Use a precisão como um intervalo de saltos dx pelo qual você vai percorrendo e computando valores de y correspondente. Se, durante esse loop, y=0 eis uma solução(não se esqueça de fazer tudo float). Se y muda de sinal use a média aritmética dos valores antes e depois da mudança de sinal como sendo a raiz, ou você pode usar outro critério. Vá armazenando as raízes nos arrays.
Claro que o programa ainda tem duas limitações: 1º não encontra os valores exatos da raiz 2º necessita de um intervalo de varredura(está limitado).
Para o primeiro problema se o resultado for irracional não existe melhor solução do que aproximar mesmo, mas e se for uma fração ou um inteiro aproximado? Ai sim você usa aquele teorema. Uma dica é criar um vetor com todos as combinações possíveis de divisores e depois comparar com os valores das aproximações.
Para o segundo problema é mais complicado. Você teria que analisar se a função é crescente ou decrescente, por exemplo, se o polinômio é de terceiro grau e você encontrou 3 raízes diferentes então resolvido. Agora, se você encontrou 2, então o polinômio pode ser sido ou não resolvido, pode ser que haja uma raíz dupla. Como verificar isso? Veja se no intervalo após a maior das raízes o polinômio representa uma função crescente e antes da menor é decrescente ou vice versa, já que se trata de uma função "ímpar". As aspas são porque ela não é ímpar, mas se comporta como uma, ao contrário do que seriam polinômios de grau dez. A coisa complicaria se você encontrasse uma solução.
Há no que se pensar. A vantagem de usar isso é que resolveria raízes não só de polinômios, mas também de funções em geral, teoricamente. A grande desvantagem é o quão pesada é essa varredura, mas por sorte estamos falando de C.
Se você pudesse aproveitar uma biblioteca que permitisse manipulação de variáveis e cálculo diferencial poderia utilizar o recurso do método de newton-raphson, se tiver alguma prática com cálculo. Bem, você também pode simplesmente identificar de qual grau é a função e aplicar o algoritmo de raphson-newton já pronto e depois de algumas permutações teria um resultado aproximado:
https://pt.wikipedia.org/wiki/M%C3%A9todo_de_Newton-Rhapson
Para fazer isso você precisaria de ter uma função para cada caso que tem como argumentos cada coeficiente e computassem a fórmula para cada caso. A fórmula para décimo grau fica difícil ein!
Espero que consiga fazer um bom programa com isso. Esse é realmente um problema mais matemático que de programação, mas acho que aí é que esteja o erro. Programação é puramente matemática, com uma pitada de sintaxe. Se tiver mais alguma dúvida quanto ao problema não hesite em perguntar.