def my_function(param1 , param2 , param3 , param4) : return param1 + 3*param2 + 5*param3 + np.power(5 , 3) + np.sqrt(param4) print(my_function(1,2,3,4))

This prints 134.0

如何在my_function参数的下列条件下返回100而不是134.0或尽可能接近6的值:param1必须在10-20范围内,param2必须在20-30范围内,param3必须在30-40范围内,param4必须在40-50范围内。

我不要求对这个问题的具体解决方案,但它属于哪个领域?阅读 https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html & Python中的参数优化 建议这可以用开箱即用的解决方案(在低维度)。遗传编程可以应用于这个问题吗?

5 个评论
这是一个非线性优化问题。 en.wikipedia.org/wiki/Nonlinear_programming 这里有一个算法的工具箱,而GAs并不是你的首选。
param3 is never used.
jman
如果你问的是如何解决value = my_function ,那可以看成是一种寻根算法(与优化非常相关)。 你可以看一下scipy docs.scipy.org/doc/scipy-0.18.1/reference/optimize.html
@BadZen 感谢类似的东西。 stackoverflow.com/questions/21765794/... 我也很好奇,为什么不推荐GA?使用GA可以将权重初始化为范围内的一组随机值,并且GA应该找到使函数最小化的最佳权重集?
1) 这是在它的天真无邪的形式下 无约束的 优化(有边界)。比有约束的优化容易得多。2) GA只是(个人观点:愚蠢的)不完整的启发式方法,没有正式的保证,只在有限的先验分析领域工作,同时高度调整。3) 由于这看起来是非凸的,你需要决定局部选择的解决方案是否可以(容易)或需要全局选择(不那么容易)。
python
optimization
mathematical-optimization
genetic-algorithm
genetic-programming
blue-sky
blue-sky
发布于 2018-02-22
3 个回答
Emmet B
Emmet B
发布于 2018-02-22
已采纳
0 人赞同

基本上,你想使估计值和真实函数之间的误差最小。

EDIT : 这里的明显选择是在4个参数上使用梯度下降。如果你不想这样做,而要求更多的像一个务实的解决方案,这里就是。

这里的主要问题是有4个参数。为了解决这个问题,你可以这样做。

  • Fix any 3 parameters , leave the last one alone. We will try to find this value.
  • Find the inverse function, and solve for it either explicitly or using a solver (which may be a numerical method like Newton-Raphson or Brent method)
  • 我将描述一个过程来证明这个想法。我们将使用scipy的scalar_minimizer,它采用了Brent方法。

    为了便于讨论,让我们保持你的函数由2个参数组成,让我们假设你的函数是。

    def f(p1, p2):
        return p1 + np.sqrt(p2)
    

    你基本上是在问如何找到和p1, p2的值,使f(p1, p2) = 100。 假设范围如下。

  • ranges for p1: 10-20
  • ranges for p2: 20-30
  • 让我们把p1固定为10(你可以自由地固定为这个范围内的任何东西)。现在这个函数变成了

    def g(p2):
        return 10 + np.sqrt(p2)
    

    我们希望它尽可能地接近100,所以让我们创建一个误差函数来衡量我们的估计值离100有多远。

    def error(p2):
        return 100 - (10 + np.sqrt(p2)) # we want to minimize this
    

    你可以找到值来最小化这个误差,这样你就可以尽可能地接近100,通过

    from scipy import optimize
    optimize.minimize_scalar(error, bounds = (10,20), method = "bounded")   
    

    它给出了一个x=19.9的值,作为使误差最小的值。

    那么,这对他的例子将如何发挥作用?它将提供什么?
    他问的那个接近100的P1值,还能是什么呢?
    为此,你不需要代码,你的方法也没有带来任何有价值的东西(至少它在以下方面是不完整的 如何转移 )(这只是我的看法)。多变量GD的方法是局部的,但在这里这就足够了吗?
    我只是很高兴,至少你最终意识到这是你的观点。
    alexprice
    alexprice
    发布于 2018-02-22
    0 人赞同

    创建新的函数,通过增加对违反约束的惩罚来优化。

    param1必须在10-20的范围内,因此要满足param1的约束条件,唯一需要优化的新函数是

    f(p1,p2,p3,p4)=my_function(p1,p2,p3,p4)+1000*(p1-30)*2
    param1=20+p1
    

    改变变量进行优化 p1=param1-20 你可以在约束条件前玩弄系数的大小,这将取决于所使用的优化方法。

    需要有一个正方形,以便梯度存在于所有的p1

    根据需要向新的优化函数添加其他惩罚措施

    sascha
    sascha
    发布于 2018-02-22
    0 人赞同

    只是为了好玩,一个小的演示在 朱莉娅 (正如有人所说。 no concrete solution 可用)。

    这个a 全球开放源码的解算器 这将对这样的小规模问题起作用(并转移到更复杂的问题上)。请记住,你的例子有点微不足道(两个目标都会导致所有变量的下限,不需要优化就能看到;代码会按照预期输出这些结果),而我使用的是其他一些值,实际上有一些东西需要优化

    当模型变得更加复杂时,全局优化将是不可行的(理论上很难,有时不可能)。你可以将求解器切换到Ipopt来获得局部最优。

    这也可以在python中使用 pyomo ,但它没有那么好。模型和求解器都可以使用。只有代码会改变。

    using JuMP, AmplNLWriter
    TARGET = 387
    m = Model(solver=AmplNLSolver(CoinOptServices.couenne))
    @variable(m, 10 <= param1 <= 20, start=10)
    @variable(m, 20 <= param2 <= 30, start=20)
    @variable(m, 30 <= param3 <= 40, start=30)
    @variable(m, 40 <= param4 <= 50, start=40)
    @variable(m, aux)
    @NLconstraint(m, aux == TARGET - (param1 + 3*param2 + 5*param3 + 5^3 + sqrt(param4)))
    @NLobjective(m, Min, aux^2)
    solve(m)
    println("objective: ", getobjectivevalue(m))
    println("param1 = ", getvalue(param1))
    println("param2 = ", getvalue(param2))
    println("param3 = ", getvalue(param3))
    println("param4 = ", getvalue(param4))
    
    Mailing list: couenne@list.coin-or.org
    Instructions: http://www.coin-or.org/Couenne
    couenne:
    ANALYSIS TEST: Couenne: new cutoff value 0.0000000000e+000 (0.016 seconds)
    NLP0012I
                  Num      Status      Obj             It       time                 Location
    NLP0014I             1         OPT 0        7 0.003
    Loaded instance "C:\Users\Sascha\.julia\v0.5\AmplNLWriter\.solverdata\jl_21AE.tmp.nl"
    Constraints:            1
    Variables:              5 (0 integer)
    Auxiliaries:            2 (0 integer)
    Coin0506I Presolve 11 (0) rows, 4 (-3) columns and 22 (-3) elements
    Clp0006I 0  Obj 0 Primal inf 0.0023740886 (2)
    Clp0006I 1  Obj -4.0767235e-022
    Clp0000I Optimal - objective value 0
    Clp0032I Optimal objective 0 - 1 iterations time 0.012, Presolve 0.00
    Clp0000I Optimal - objective value 0
    NLP Heuristic: NLP0014I             2         OPT 0        3 0.001
    no solution.
    Cbc0010I After 0 nodes, 0 on tree, 1e+050 best solution, best possible 0 (0.01 seconds)
    Clp0000I Optimal - objective value 3.90625e-007
    Clp0006I 0  Obj 0 Primal inf 0.00098181331 (1)
    Clp0006I 1  Obj -3.2730444e-022
    Clp0000I Optimal - objective value 0
    Optimality Based BT: 0 improved bounds
    Cbc0004I Integer solution of 0 found after 2 iterations and 2 nodes (0.03 seconds)
    Cbc0001I Search completed - best objective 0, took 2 iterations and 2 nodes (0.04 seconds)
    Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
            "Finished"
    Linearization cuts added at root node:         11
    Linearization cuts added in total:             11  (separation time: 0s)
    Total solve time:                           0.065s (0.065s in branch-and-bound)
    Lower bound:                                    0
    Upper bound:                                    0  (gap: 0.00%)
    Branch-and-bound nodes:                         2
    WARNING: Nonlinear solver does not provide dual solutions
    objective: 0.0