2017-10-13 137 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