【问题标题】:Minimise multiple parameters whilst keeping the same ratios between the parameters最小化多个参数,同时保持参数之间的相同比率
【发布时间】:2019-04-28 14:05:48
【问题描述】:

我有一个特殊的函数可以计算发电厂整个生命周期内的平均电力成本 ($/MWh)。

示例函数如下所示

def calc(a,b,c):
     res = 65*a+74*b+12*c
     return res

其中abc是成本参数,例如运营支出、建设成本和保险。

我可以用无数种方式改变 a bc,但我希望保持比率与我的示例数据点相同,平均电费的结果较低.

例如 当a=1b=2c=3res = 249

但是,我想找出在a bc res=600 时保持相同原始比率的最佳值

我试图找到一种使用 scipy.optimize 的方法,但遇到了一些困难。

我不确定我将如何编程约束的比率。

非常感谢。

【问题讨论】:

  • 谢谢你。但是,我想知道如何定义许多不同参数的比率约束。我的示例中有 7 个参数。谢谢。
  • 您希望哪些比率完全相等?如果您有 3 个数字,则必须满足 3 个比率 - 最后,您只能通过整体乘法因子来更改数字(每个参数都相同)
  • 感谢您的评论@rammelmueller。请参阅我对 Bill M. 的回答的回复。

标签: python scipy


【解决方案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 使用浮点数,而不是使用截断的整数。

【讨论】:

  • 感谢您的回答。对不起,我应该说得更清楚,在这个示例问题中这将是最好的解决方案,但在我的实际项目中我需要使用约束,因为计算 a、b 和 c 的计算相当复杂。
  • 不客气,但很抱歉,我不太了解您在这里需要什么。也许您可以显示scipy.optimize() 在哪里给您错误。
  • 你想要多少个参数真的没关系 - 如果比率相同,你总是会遇到这个问题。在不知道确切的形式和限制条件的情况下,在这里做任何事情都会很有挑战性。
【解决方案2】:

来自this 的答案,您可以像这样指定约束:

cons = [{'type':'eq', 'fun': con1},
        {'type':'eq', 'fun': con2}]

并像这样使用最小化函数:

scipy.optimize.minimize(func, x0, constraints=cons)

【讨论】:

  • 感谢您的回复。这有帮助。
  • 我很高兴它有帮助。祝你的项目好运!如果可以,请将其标记为答案
【解决方案3】:

我设法找到了一个对我的特定用例有帮助的解决方案,尽管有人指出这个特定示例有一个更简单的解决方案。

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

约束保持相同的比率,并将计算的结果设置为等于600。

【讨论】:

    猜你喜欢
    • 2020-09-29
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多