2012-05-08 51 views
16

Diciamo che ho un equazione:Come posso risolvere le equazioni in Python?

2x + 6 = 12

con l'algebra possiamo vedere che x = 3. Come posso creare un programma in Python in grado di risolvere il problema con x? Sono nuovo alla programmazione e ho guardato allo eval() e allo exec() ma non riesco a capire come fargli fare ciò che voglio. Non voglio usare librerie esterne (ad esempio SAGE), voglio farlo semplicemente in Python.

+7

Voglio un'auto che faccia 0 a 60 in 4,5 secondi e ottenga 45 MPG. Forse potresti prendere in considerazione la rimozione del requisito per Python semplice e usare le librerie esterne –

+1

Se vuoi risolvere qualsiasi equazione dovrai costruire la tua libreria. Anche 4,5 secondi non sono abbastanza veloci per questo esempio: D – jamylak

+0

I problemi avranno sempre l'aspetto 'solve y = mx + c per x'? –

risposta

26

Che ne dici di SymPy? Il loro solver sembra quello che ti serve. Dai un'occhiata al loro codice sorgente se vuoi creare tu stesso la libreria ...

+2

Divertente vedere una risposta come questa entro pochi minuti da tutti i commenti sprezzanti sulla domanda: D – naught101

6

Utilizzare uno strumento diverso. Qualcosa come Wolfram Alpha, Maple, R, Octave, Matlab o qualsiasi altro pacchetto software di algebra.

Come principiante non dovresti probabilmente cercare di risolvere un problema non banale.

+0

Wolfram Alpha è sorprendente. L'ho usato per risolvere '3 ** x = 4' e ho ottenuto una risposta soddisfacente. – Zen

+0

... in realtà, è piuttosto facile; log (3 ** x) == x * log (3) == log (4) quindi x = log (4)/log (3) = 1.261859 ... –

7

Python può essere buono, ma non è Dio ...

Ci sono diversi modi per risolvere le equazioni. SymPy è già stato menzionato, se stai cercando soluzioni analitiche.

Se sei felice di avere solo una soluzione numerica, Numpy ha alcune routine che possono aiutarti. Se sei interessato solo a soluzioni ai polinomi, numpy.roots funzionerà. In particolare per il caso in cui si accennato:

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

Per le espressioni più complicate, uno sguardo ai scipy.fsolve.

In entrambi i casi, non è possibile scappare utilizzando una libreria.

6

Se si desidera solo per risolvere il estremamente limitato insieme di equazioni mx + c = y per intero positivo m, c, y, allora questo farà:

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) 

Alcuni test:

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

Se si desidera riconoscere e risolvere le equazioni arbitrarie, come sin(x) + e^(i*pi*x) = 1, quindi sarà necessario implementare una sorta di engi simbolico di matematica ne, simile a maxima, Mathematica, MATLAB's solve() o Symbolic Toolbox, ecc. Come novizio, questo è al di là della tua comprensione.

11

Ci sono due modi per affrontare questo problema: numericamente e simbolicamente.

Per risolverlo numericamente, è necessario prima codificarlo come funzione "eseguibile": inserire un valore, ottenere un valore. Ad esempio,

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

È abbastanza possibile analizzare una stringa per creare automaticamente tale funzione; diciamo che analizzi 2x + 6 in una lista, [6, 2] (dove l'indice della lista corrisponde alla potenza di x - quindi 6 * x^0 + 2 * x^1).Poi:

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 

È quindi necessario un'altra funzione che si collega più volte un valore x nella vostra funzione, guarda la differenza tra il risultato e quello che vuole trovare, e tweaks suo valore x per (si spera) ridurre al minimo la differenza.

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

ci sono un sacco di potenziali problemi qui - a trovare un iniziale buon valore x, partendo dal presupposto che la funzione ha in realtà una soluzione (cioè non ci sono risposte a valori reali di x^2 + 2 = 0), colpire i limiti di precisione di calcolo, ecc Ma in questo caso, la funzione di minimizzazione è adatto e noi ottenere un buon risultato:

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

si noti che questa soluzione non è assolutamente , esattamente corretta. Se hai bisogno che sia perfetto, o se vuoi provare a risolvere analiticamente famiglie di equazioni, devi rivolgerti a una bestia più complicata: un risolutore simbolico.

Un risolutore simbolico, come Mathematica o Maple, è un sistema esperto con molte regole incorporate ("conoscenza") su algebra, calcolo, ecc; "sa" che la derivata del peccato è cos, che la derivata di kx^p è kpx^(p-1), e così via. Quando gli dai un'equazione, prova a trovare un percorso, un insieme di applicazioni di regole, da dove è (l'equazione) a dove vuoi essere (la forma più semplice possibile dell'equazione, che si spera sia la soluzione) .

L'equazione di esempio è piuttosto semplice; una soluzione simbolica potrebbe sembrare:

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

e non v'è la vostra soluzione: x = 5.

Spero che questo dà il sapore di questa idea; i dettagli di implementazione (trovare una buona serie completa di regole e decidere quando applicare ogni regola) possono facilmente consumare molti anni di sforzi.

Problemi correlati