2017-10-13 130 views
0

我想寫一個函數來解決從Python中的另一個函數的變量,有點像Excel解算器所做的。返回解決變量使用python

爲了簡化我的例子,我有一個函數需要幾個變量,然後計算一個價格。我將傳遞實際值(a,b,c,d,x)到該函數中,以便返回數值。

def calc_price(a,b,c,d,x): 
    value = a+b*c-d + x 
    return value 

現在我給出了一個目標價格,a,b,c,d。只有未知的是變量x,所以我想回去求解變量x。我想將其構建到一個函數中,該函數採用與calc_price相同的變量,並使用額外的變量target_price。

def solve(target_price, a,b,c,d): 
    #this function takes in values for target_price, a,b,c,d 
    #and should do something like this: 
    target_price = calc_price(a,b,c,d,x) 
    solve for x <---------this is the part I'm not sure how to do 
    return x 

我創造了這樣的下方備份解決由一個循環中值x的函數,但它在計算大型數據集低效的,所以我在尋找一種更有效的解決方案。

def solve(target_price,a,b,c,d): 
    x = 0.01 
    while x < 1: 
     if abs(target_price - calc_price(a,b,c,d,x)) < 0.001: 
      return x 
     x += 0.001 

謝謝!

+1

[scipy.optimize.minimize_scalar](https://docs.scipy.org/doc/scipy-0.19.1/reference/generated /scipy.optimize.minimize_scalar.html)。這將是黃金標準(在數值方法中,爲其他世界查找計算機代數系統,不一定推薦)。如果這是一個太重的代碼/庫依賴:查找根發現和合作。 – sascha

+1

@sascha,你是不是指'金'標準:-) https://docs.scipy.org/doc/scipy-0.19.1/reference/optimize.minimize_scalar-golden.html –

+0

相當不錯的斯圖爾特。但我會使用布倫特(至少當有人已經爲我實現了它):-) – sascha

回答

0

請考慮這個演示(因爲您的任務仍然有點不清楚),並確保閱讀scipy's docs瞭解這些方法提供的基本保證。

有人可能會爭辯說,基於root-finding的方法更合適(我們正在最小化一個函數;因此abs函數在殘差函數中),但是這種方法並不需要你給出一些包圍 - 間隔。

代碼:

import numpy as np 
from scipy.optimize import minimize_scalar 
np.random.seed(0) 

""" Utils """ 
def calc_price(x, a, b, c, d): 
    value = a+b*c-d + x 
    return value 

def calc_price_res(x, target, a, b, c, d): 
    value = a+b*c-d + x 
    return abs(value - target) # we are looking for f(x) == 0 

""" Create fake-data (typically the job of OP!) """ 
a, b, c, d, x = np.random.random(size=5) 
fake_target = calc_price(x, a, b, c, d) 

print('a, b, c, d: ', a, b, c, d) 
print('real x: ', x) 
print('target: ', fake_target) 
print('noisy obj (just to be sure): ', calc_price_res(x, fake_target, a, b, c, d)) 

""" Solve """ 
res = minimize_scalar(calc_price_res, args=(fake_target, a, b, c, d)) 

print('optimized x: ', res.x) 
print('optimized fun: ', res.fun) 

輸出:

a, b, c, d: 0.548813503927 0.715189366372 0.602763376072 0.544883182997 
real x: 0.423654799339 
target: 0.858675077275 
noisy obj (just to be sure): 0.0 
optimized x: 0.423654796297 
optimized fun: 3.04165614917e-09 
+1

謝謝你,這正是我正在尋找的。我不確定如何通過其他變量,但您在示例中已經很清楚了!這個minim_scalar函數也比我原來的函數快很多。 – jingz