我有一个特殊的功能,可以计算发电厂整个生命周期的平均电费($ / MWh)。
一个示例函数如下所示
def calc(a,b,c):
res = 65*a+74*b+12*c
return res
a
b
和c
是成本参数,例如运营支出,建筑成本和保险。
我可以以无数种方式来改变a
b
和c
,但是我想保持比率与示例数据点相同,但要降低平均电费的结果。
例如
当a=1
,b=2
和c=3
,res = 249
时。
但是,我想找出a
时b
c
和res=600
的最优值,该最优值保持相同的原始比率
我试图找出一种使用scipy.optimize进行此操作的方法,但是有些困难。
我不确定如何按照约束比例进行编程。
非常感谢。
答案 0 :(得分:1)
假设您有两组值,(a_old,b_old,c_old)和(a_new,b_new,c_new)。如果您希望它们各自的比率相同(例如,a_old:c_old与a_new:c_new相同,而c_old:b_old与c_new:b_new相同,依此类推),那么这就像说存在一些常数k,例如a_new = k * a_old,b_new = k * b_old和c_new = k * c_old。
在您的示例中,65 * a_old + 74 * b_old + 12 * c_old =249。如果将该方程式的两边乘以k,则得到 65(k * a_old)+ 74(k * b_old)+ 12(k * c_old)= 249 * k。这与'65(a_new)+ 74(b_new)+ 12(c_new)= 249k'相同。
您希望249 * k等于600。因此,k = 600/249 =约2.4096。然后,您可以将此k值与a_old,b_old,c_old一起使用,以找到a_new,b_new,c_new的值。请记住,新值只是旧值的k倍。
这是一个返回缩放参数值集合的函数:
def optimize(a,b,c, opt_res):
res = 65 * a + 74 * b + 12 * c
k = opt_res/res
new_vals = [parameter * k for parameter in [a,b,c]]
return new_vals
print(optimize(1,2,3,600.0))
## output: [2.4096385542168677, 4.819277108433735, 7.2289156626506035]
请注意,我使用的是“ 600.0”,而不是“ 600”。这迫使Python使用浮点数,而不是使用截断的整数来完成所有操作。
答案 1 :(得分:1)
从this的答案中,您可以这样指定约束条件:
cons = [{'type':'eq', 'fun': con1},
{'type':'eq', 'fun': con2}]
并使用如下的最小化功能:
scipy.optimize.minimize(func, x0, constraints=cons)
答案 2 :(得分:0)
尽管有人指出针对此特定示例有一个更简单的解决方案,但我还是设法找到了对我的特定用例有用的解决方案。
from scipy.optimize import minimize
import numpy as np
a = 1
b = 2
c = 3
def calc(x):
res = 65*x[0]+74*x[1]+12*x[2]
return res
cons = [{'type': 'eq', 'fun': lambda x: x[0]/x[1]-a/b},
{'type': 'eq', 'fun': lambda x: x[1]/x[2]-b/c},
{'type': 'eq', 'fun': lambda x: calc(x)-600}]
start_pos = np.ones(3)*(1/6.)
print(minimize(calc, x0=start_pos, constraints=cons))
约束保持相同的比率,并将calc的结果设置为等于600。