2012-05-08 37 views
16

ı bir denklem var diyelim: cebir ilePython'daki denklemleri nasıl çözebilirim?

2x + 6 = 12

biz x = 3 olduğunu görebilirsiniz. Python'da x için çözebilecek bir program nasıl yapabilirim? Programlamada yeniyim ve eval() ve exec()'a baktım ama onların ne istediğimi yaptıklarını anlayamıyorum. Harici kütüphaneleri kullanmak istemiyorum (örn. SAGE), bunu sadece Python'da yapmak istiyorum.

+7

4.5 saniyede 0 ila 60 yapan bir araba ister ve 45 MPG alır. Belki düz Python gereksinimini kaldırmayı düşünebilir ve harici kütüphaneleri kullanabilirsiniz –

+1

Herhangi bir denklemi çözmek isterseniz kendi kütüphanenizi oluşturmanız gerekecektir. Ayrıca, bu örnek için 4,5 saniye yeterince hızlı değil: D – jamylak

+0

Sorunlar her zaman x = yx için x = y = mx + c gibi görünecek mi? –

cevap

26

SymPy nasıl? Onların solver neye ihtiyacınız olduğuna benziyor. Kütüphaneyi kendiniz oluşturmak istiyorsanız kaynak kodlarına bakın…

+2

Sorunun tüm bu snide yorumlarının dakikalar içinde böyle bir cevabı görmek için eğlenceli: D – naught101

6

Farklı bir araç kullanın. Wolfram Alpha, Maple, R, Octave, Matlab veya başka bir cebir yazılım paketi gibi bir şey. Bir başlangıç ​​olarak, bu gibi önemsiz bir sorunu çözmeye çalışmamalısınız.

+0

Wolfram Alpha şaşırtıcı. Ben 3 ** x = 4' çözmek için kullandı ve tatmin edici bir cevap aldı. – Zen

+0

... aslında, bu oldukça kolay bir tane; log (3 ** x) == x * log (3) == log (4) öyleyse x = log (4)/log (3) = 1.261859 ... –

7

Python iyi olabilir, ama Tanrı değil ...

denklemleri çözmek için birkaç farklı yolu vardır. Analitik çözümler arıyorsanız SymPy'den daha önce bahsedilmiştir.

Numpy'nin sadece sayısal bir çözümü olduğundan memnunsanız, Numpy'nin yardımcı olabilecek birkaç rutini vardır. Sadece polinomlara çözümlerle ilgileniyorsanız, numpy.roots çalışacaktır. Özellikle durum için Bahsettiğiniz:

daha karmaşık ifadeler için
>>> import numpy 
>>> numpy.roots([2,-6]) 
array([3.0]) 

, scipy.fsolve de bakabilirsiniz.

Her iki durumda da bir kütüphane kullanarak kaçamazsınız. Yalnızca pozitif tamsayı m, c, y için denklem mx + c = y ait son derece sınırlı set çözmek istiyorsanız

6

, o zaman bu yapacak:

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) 

Bazı testler:

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

Eğer isterseniz sin(x) + e^(i*pi*x) = 1 gibi keyfi denklemlerini tanımak ve çözmek, daha sonra bir çeşit sembolik matematik uygulamanız gerekir. ne, maxima, Mathematica, MATLAB'ın solve() veya Symbolic Toolbox, vb. gibi bir acemi olarak, bu sizin ken'in ötesindedir.

11

Bu soruna yaklaşımın iki yolu vardır: sayısal ve sembolik.

Sayısal olarak çözmek için, önce bunu bir "runnable" işlevi olarak kodlamanız gerekir - bir değer girme, bir değer elde etme. Örneğin, bir işlevi otomatik olarak oluşturmak için bir dizeyi ayrıştırmak oldukça mümkündür; 2x + 6'u [6, 2] (liste dizininin x - yani 6 * x^0 + 2 * x^1) değerine böldüğünü söyleyin.Ardından:

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 

Ardından arka arkaya İşlevinizden içine bir x-değeri takılan sonucu ve bulmak istiyorsa ne arasındaki fark bakar ve onun x değerini tweaks başka işlev gerekir (umarım) en aza indirmek fark. (X^2 + 2 = 0 olarak hiçbir gerçek değerli cevaplar vardır yani) işlevi aslında bir çözümü var olduğunu varsayarak, iyi bir başlangıç ​​x değerini bulmak -

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

potansiyel Burada birçok sorun vardır hesaplamalı doğruluk vb sınırlarını isabet Ancak bu durumda, hata minimizasyonu fonksiyonu uygundur ve biz iyi bir sonuç almak: Bu çözüm kesinlikle olmadığını

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

not, tam doğru. Mükemmel olmak için ihtiyacınız varsa veya analitik olarak denklemlerin ailelerini çözmeyi denemek istiyorsanız, daha karmaşık bir canavara dönmelisiniz: sembolik bir çözücü.

Mathematica veya Maple gibi sembolik bir çözücü, vb cebir, kalkülüs, ilgili yerleşik kurallar bir çok ("Bilgi") ile bir uzman sistemi anlamına gelir; Günahın türevinin, "kx^p" türevinin kpx^(p-1) ve benzeri olduğunu "bilir". Bir denklem verdiğinizde, bir yol bulmaya çalışır, bir kural-uygulama kümesi, nerede olursanız olun (denklem), nerede olursanız olun (denklemin en basit şekli, ki bu da umarım çözümdür). .

Örnek denkleminiz oldukça basittir; sembolik bir çözüm gibi görünebilir:

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

ve çözüm yoktur: x = 5.

Bu fikrin lezzet verir umut; Uygulamanın detayları (iyi ve eksiksiz bir kurallar kümesinin bulunması ve her bir kuralın ne zaman uygulanması gerektiğine karar verilmesi) birçok insan-yıl çabalarını kolaylıkla tüketebilir.

İlgili konular