scipy-optimize-minimize 最小化缺乏收敛性

Posted

技术标签:

【中文标题】scipy-optimize-minimize 最小化缺乏收敛性【英文标题】:Lack of convergence in scipy-optimize-minimize minimization 【发布时间】:2019-09-01 08:01:28 【问题描述】:

总的来说,我试图“缩放”一个数组,使数组的积分为 1,即数组元素的总和除以元素的数量为 1。但是,这种缩放必须通过更改参数 alpha 而不是简单地将数组乘以缩放因子。为此,我正在使用 scipy-optimize-minimize。问题是代码运行,输出“优化终止成功”,但显示的当前函数值不是0,所以显然优化并没有真正成功。

This is a screenshot from the paper that defines the equation.

import numpy as np
from scipy.optimize import minimize

# just defining some parameters
N = 100
g = np.ones(N)
eta = np.array([i/100 for i in range(N)])
g_at_one = 0.01   

def my_minimization_func(alpha):
    g[:] = alpha*(1+(1-g_at_one/alpha)*np.exp((eta[:]-eta[N-1])/2)*(1/np.sqrt(3)*np.sin(np.sqrt(3)/2*(eta[:] - eta[N-1])) - np.cos(np.sqrt(3)/2*(eta[:] - eta[N-1])))) 
    to_be_minimized = np.sum(g[:])/N - 1
    return to_be_minimized

result_of_minimization = minimize(my_minimization_func, 0.1, options='gtol': 1e-8, 'disp': True)
alpha_at_min = result_of_minimization.x
print(alpha_at_min)

【问题讨论】:

【参考方案1】:

嗯,我不清楚,你为什么要对这样的问题使用最小化?您可以简单地对矩阵进行归一化,然后使用归一化矩阵和旧矩阵计算alpha。对于矩阵归一化看here。

在您的代码中,您的目标函数包括除以零 (1-g_at_one/alpha),因此该函数未在 0 中定义,这就是为什么我假设 scipy 正在跳过它。

编辑: 所以我只是重新阐述了你的问题并使用了一个约束,添加了一些打印以获得更好的可视化。我希望这会有所帮助:

import numpy as np
from scipy.optimize import minimize

# just defining some parameters
N   = 100
g   = np.ones(N)
eta = np.array([i/100 for i in range(N)])
g_at_one = 0.01   

def f(alpha):
    g = alpha*(1+(1-g_at_one/alpha)*np.exp((eta[:]-eta[N-1])/2)*(1/np.sqrt(3)*np.sin(np.sqrt(3)/2*(eta[:] - eta[N-1])) - np.cos(np.sqrt(3)/2*(eta[:] - eta[N-1])))) 
    to_be_minimized = np.sum(g[:])/N
    print("+ For alpha: %7s => f(alpha): %7s" % ( round(alpha[0],3),
                                                  round(to_be_minimized,3) ))
    return to_be_minimized

cons = 'type': 'ineq', 'fun': lambda alpha:  f(alpha) - 1
result_of_minimization = minimize(f, 
                                  x0 = 0.1,
                                  constraints = cons,
                                  tol = 1e-8,
                                  options = 'disp': True)

alpha_at_min = result_of_minimization.x

# verify 
print("\nAlpha at min: ", alpha_at_min[0])
alpha = alpha_at_min
g = alpha*(1+(1-g_at_one/alpha)*np.exp((eta[:]-eta[N-1])/2)*(1/np.sqrt(3)*np.sin(np.sqrt(3)/2*(eta[:] - eta[N-1])) - np.cos(np.sqrt(3)/2*(eta[:] - eta[N-1])))) 
print("Verification: ", round(np.sum(g[:])/N - 1) == 0)

输出:

+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:     0.1 => f(alpha):   0.021
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
+ For alpha:   7.962 => f(alpha):     1.0
Optimization terminated successfully.    (Exit mode 0)
            Current function value: 1.0000000000000004
            Iterations: 3
            Function evaluations: 9
            Gradient evaluations: 3

Alpha at min:  7.9620687892224264
Verification:  True

【讨论】:

我同意我可以使用例如 normalized_g = g[:] / (np.sum(g[:]/N)) 对矩阵进行归一化,但我不确定这有什么帮助,因为考虑到 alpha 在复杂的表达式中,从归一化和原始矩阵计算 alpha 仍然很重要 如果您在[0,1] 中寻找标准化值,您的方法会返回大于1 的值。我认为您将标准化与矩阵缩放混淆了。在缩放中alpha 是一个因素,您可以写normalized_g = alpha*g,但在规范化中并非如此。请对您的目标和您需要的标准化类型提供更好的解释? 一种简单的方法,但我不确定将矩阵除以其范数或最大值是否正确。在这种情况下,您将拥有 [0,1]alpha=1/norm(g)alpha=1/max(g) 中的值,具体取决于您使用的类型。 嗨,我编辑了问题陈述以使缩放更清晰。我不是在寻找传统的标准化或缩放,而是使用参数 alpha 的特定缩放,例如 np.sum(g[:])/N = 1 好的,我明白了,但是你能解释一下你在这里做什么:` g[:] = alpha*(1+(1-g_at_one/alpha)*np.exp((eta[ :]-eta[N-1])/2)*(1/np.sqrt(3)*np.sin(np.sqrt(3)/2*(eta[:] - eta[N-1]) ) - np.cos(np.sqrt(3)/2*(eta[:] - eta[N-1]))))` 或者为此提供数学方程式/推理。

以上是关于scipy-optimize-minimize 最小化缺乏收敛性的主要内容,如果未能解决你的问题,请参考以下文章

图 - 最短路径 (二)

数据结构—— 图:最短路径问题

如何用WPF实现一个最简单的Mvvm示例

算法导论——单元最短路径

最短路径 深入浅出Dijkstra算法(一)

Git使用教程:最详细最傻瓜最浅显真正手把手教!