2012-05-08 15 views
16

Digamos que tengo una ecuación:¿Cómo puedo resolver ecuaciones en Python?

2x + 6 = 12

Con el álgebra podemos ver que x = 3. ¿Cómo puedo hacer un programa en Python que pueda resolver por x? Soy nuevo en la programación y miré eval() y exec(), pero no puedo entender cómo hacer que hagan lo que quiero. No quiero utilizar bibliotecas externas (por ejemplo, SAGE), quiero hacer esto simplemente con Python.

+7

Quiero un automóvil que tenga de 0 a 60 en 4.5 segundos y obtenga 45 MPG. Tal vez podrías considerar eliminar el requisito de Python simple y usar librerías externas –

+1

. Si quieres resolver cualquier ecuación, tendrás que construir tu propia biblioteca. Además, 4.5 segundos no es lo suficientemente rápido para este ejemplo: D – jamylak

+0

¿Los problemas siempre se verán como 'resolver y = mx + c para x'? –

Respuesta

26

¿Qué tal SymPy? Su solver se parece a lo que necesita. Eche un vistazo a su código fuente si quiere construir la biblioteca usted mismo ...

+2

Divirtiendo ver una respuesta como esta a pocos minutos de todos los comentarios sarcásticos sobre la pregunta: D – naught101

6

Utilice una herramienta diferente. Algo así como Wolfram Alpha, Maple, R, Octave, Matlab o cualquier otro paquete de software de álgebra.

Como principiante, probablemente no deberías intentar resolver un problema tan poco trivial.

+0

Wolfram Alpha es increíble. Lo usé para resolver '3 ** x = 4' y obtuve una respuesta satisfactoria. – Zen

+0

... de hecho, es bastante fácil; log (3 ** x) == x * log (3) == log (4) por lo que x = log (4)/log (3) = 1.261859 ... –

7

Python puede ser bueno, pero no lo es Dios ...

Hay algunas maneras diferentes para resolver ecuaciones. Ya se ha mencionado SymPy, si está buscando soluciones analíticas.

Si está feliz de tener solo una solución numérica, Numpy tiene algunas rutinas que pueden ayudar. Si solo te interesan las soluciones a los polinomios, numpy.roots funcionará. Específicamente para el caso que se menciona:

>>> import numpy 
>>> numpy.roots([2,-6]) 
array([3.0]) 

Para expresiones más complicadas, echar un vistazo a scipy.fsolve.

De cualquier manera, no puede escapar utilizando una biblioteca.

6

Si sólo desea resolver el extremadamente limitado conjunto de ecuaciones mx + c = y para entero positivo m, c, y, entonces esto va a hacer:

import re 
def solve_linear_equation (equ): 
    """ 
    Given an input string of the format "3x+2=6", solves for x. 
    The format must be as shown - no whitespace, no decimal numbers, 
    no negative numbers. 
    """ 
    match = re.match(r"(\d+)x\+(\d+)=(\d+)", equ) 
    m, c, y = match.groups() 
    m, c, y = float(m), float(c), float(y) # Convert from strings to numbers 
    x = (y-c)/m 
    print ("x = %f" % x) 

Algunas pruebas:

>>> solve_linear_equation("2x+4=12") 
x = 4.000000 
>>> solve_linear_equation("123x+456=789") 
x = 2.707317 
>>> 

Si desea reconocer y resolver ecuaciones arbitrarias, como sin(x) + e^(i*pi*x) = 1, entonces tendrá que implementar algún tipo de matemática matemática ne, similar a maxima, Mathematica, MATLAB solve() o caja de herramientas simbólica, etc. Como novato, esto está más allá de su conocimiento.

11

Hay dos formas de abordar este problema: numérica y simbólicamente.

Para resolverlo numéricamente, primero tiene que codificarlo como una función "ejecutable" - insertar un valor, obtener un valor. Por ejemplo,

def my_function(x): 
    return 2*x + 6 

Es muy posible analizar una cadena para crear automáticamente dicha función; digamos que analiza el 2x + 6 en una lista, [6, 2] (donde el índice de la lista corresponde a la potencia de x - entonces 6 * x^0 + 2 * x^1).Entonces:

def makePoly(arr): 
    def fn(x): 
     return sum(c*x**p for p,c in enumerate(arr)) 
    return fn 

my_func = makePoly([6, 2]) 
my_func(3) # returns 12 

este caso es necesario otra función que se conecta repetidamente un valor de x en su función, mira a la diferencia entre el resultado y lo que quiere encontrar, y pellizca su valor x que (esperemos) minimizar la diferencia.

def dx(fn, x, delta=0.001): 
    return (fn(x+delta) - fn(x))/delta 

def solve(fn, value, x=0.5, maxtries=1000, maxerr=0.00001): 
    for tries in xrange(maxtries): 
     err = fn(x) - value 
     if abs(err) < maxerr: 
      return x 
     slope = dx(fn, x) 
     x -= err/slope 
    raise ValueError('no solution found') 

Hay un montón de posibles problemas aquí - la búsqueda de una partida buena valor de x, suponiendo que la función tiene en realidad una solución (es decir, no hay respuestas de valor real a x^2 + 2 = 0), golpear los límites de la precisión de cálculo, etc, pero en este caso, la función de minimización de errores es adecuado y conseguir un buen resultado:

solve(my_func, 16) # returns (x =) 5.000000000000496 

Tenga en cuenta que esta solución no es absolutamente , exactamente correcta. Si necesita que sea perfecto, o si quiere intentar resolver familias de ecuaciones analíticamente, debe recurrir a una bestia más complicada: un solucionador simbólico.

Un solucionador simbólico, como Mathematica o Maple, es un sistema experto con muchas reglas incorporadas ("conocimiento") sobre álgebra, cálculo, etc. "sabe" que la derivada de sin es cos, que la derivada de kx^p es kpx^(p-1), y así sucesivamente. Cuando le das una ecuación, trata de encontrar una ruta, un conjunto de aplicaciones de reglas, desde donde está (la ecuación) hasta donde quieres estar (la forma más simple posible de la ecuación, que es la solución) .

Su ecuación de ejemplo es bastante simple; una solución simbólica podría ser:

=> LHS([6, 2]) RHS([16]) 

# rule: pull all coefficients into LHS 
LHS, RHS = [lh-rh for lh,rh in izip_longest(LHS, RHS, 0)], [0] 

=> LHS([-10,2]) RHS([0]) 

# rule: solve first-degree poly 
if RHS==[0] and len(LHS)==2: 
    LHS, RHS = [0,1], [-LHS[0]/LHS[1]] 

=> LHS([0,1]) RHS([5]) 

y no es la solución: x = 5.

espero que esto le da el sabor de la idea; los detalles de la implementación (encontrar un conjunto bueno y completo de reglas y decidir cuándo se debe aplicar cada regla) pueden consumir fácilmente muchos años-hombre de esfuerzo.

Cuestiones relacionadas