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.
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 –
Se vuoi risolvere qualsiasi equazione dovrai costruire la tua libreria. Anche 4,5 secondi non sono abbastanza veloci per questo esempio: D – jamylak
I problemi avranno sempre l'aspetto 'solve y = mx + c per x'? –