Có hai cách để tiếp cận vấn đề này: số lượng và biểu tượng.
Để giải quyết nó bằng số, trước tiên bạn phải mã hóa nó dưới dạng hàm "runnable" - hãy gắn giá trị vào, lấy giá trị. Ví dụ:
def my_function(x):
return 2*x + 6
Có thể phân tích chuỗi để tự động tạo chức năng như vậy; giả sử bạn phân tích cú pháp 2x + 6
thành danh sách, [6, 2]
(trong đó chỉ mục danh sách tương ứng với sức mạnh của x - vì vậy 6 * x^0 + 2 * x^1).Sau đó:
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
Sau đó bạn cần một chức năng mà nhiều lần cắm một x-giá trị vào chức năng của bạn, nhìn vào sự khác biệt giữa kết quả và những gì nó muốn tìm, và tweaks x-giá trị của nó (hy vọng) giảm thiểu Sự khác biệt.
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')
Có rất nhiều vấn đề tiềm ẩn ở đây - tìm kiếm một khởi đầu x-giá trị tốt, giả định rằng chức năng thực sự có một giải pháp (tức là không có câu trả lời thực có giá trị đến x^2 + 2 = 0), đánh các giới hạn của độ chính xác tính toán, vv Tuy nhiên, trong trường hợp này, hàm lỗi giảm thiểu phù hợp và chúng tôi có được một kết quả tốt:
solve(my_func, 16) # returns (x =) 5.000000000000496
Lưu ý rằng giải pháp này không phải là hoàn toàn, chính xác đúng. Nếu bạn cần nó để được hoàn hảo, hoặc nếu bạn muốn thử giải quyết các gia đình của phương trình phân tích, bạn phải chuyển sang một con thú phức tạp hơn: một người giải quyết tượng trưng.
Bộ giải mã tượng trưng, như Mathematica hoặc Maple, là một hệ thống chuyên gia có rất nhiều quy tắc (kiến thức) tích hợp sẵn về đại số, phép tính, v.v. nó "biết" rằng đạo hàm của sin là cos, rằng đạo hàm của kx^p là kpx^(p-1), và vân vân. Khi bạn cho nó một phương trình, nó cố gắng tìm một đường dẫn, một tập hợp các ứng dụng quy tắc, từ đó nó (phương trình) đến nơi bạn muốn trở thành (dạng đơn giản nhất có thể của phương trình, hy vọng là giải pháp) .
Phương trình ví dụ của bạn khá đơn giản; một giải pháp mang tính biểu tượng có thể trông giống như:
=> 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])
và có giải pháp của bạn: x = 5.
Tôi hy vọng điều này sẽ cho hương vị của các ý tưởng; các chi tiết thực hiện (tìm một bộ quy tắc tốt, đầy đủ và quyết định khi nào mỗi quy tắc nên được áp dụng) có thể dễ dàng tiêu thụ nhiều nỗ lực của con người.
Tôi muốn một chiếc xe hơi 0 đến 60 trong 4,5 giây và nhận được 45 MPG. Có lẽ bạn có thể xem xét loại bỏ yêu cầu cho Python đơn giản và sử dụng thư viện bên ngoài –
Nếu bạn muốn giải quyết bất kỳ phương trình nào, bạn sẽ phải xây dựng thư viện của riêng mình. Ngoài ra 4,5 giây không đủ nhanh cho ví dụ này: D – jamylak
Các vấn đề có luôn luôn giống như 'giải quyết y = mx + c đối với x' không? –