找到具有 N 个变量的函数的最小值

Posted

技术标签:

【中文标题】找到具有 N 个变量的函数的最小值【英文标题】:Finding minimum of a function with N variables 【发布时间】:2019-02-27 04:31:40 【问题描述】:

我正在尝试编写一个算法来定位可能有 N 个变量的 Rosenbrock function 的最小值。当 N = 2 时,我可以很容易地算出来。我用于 N = 2 的代码如下:

double y,z,x, aux1, aux2;
double menor = INT_MAX;
y = INT_MIN;
x = INT_MIN;


while(x < INT_MAX)

    while(y < INT_MAX)
    
        z = (1-x)*(1-x) + 100*(y - (x*x))*(y - (x*x));
        if(menor > z)
        
            menor = z;
            aux1 = x;
            aux2 = y;
           
                
        y = y + 0.1;    
        
    
    y = 0.1;
    x = x + 0.1;


printf("(x,y) : (%.2lf, %.2lf) Minimum value of z: %.2lf\n", aux1, aux2, menor);

这段代码运行良好,我将 y 和 x 相加 0.1 只是因为我已经知道该函数的最小值是多少(它在 (1,1) 上)。运行需要一点时间,但它可以工作。我的问题是 N 变量。当我想到这一点时,我想到的是我需要 N 个重复结构。这是现在的代码。它不起作用,但它可能会让我对我正在尝试做的事情有所了解:

//Calculates the value of the Rosenbrock function given n(the number of variables)
double rosen(double *x, int n)

double y;

for(int i = 0; i < n-1; i++)

    y = y + 100*((x[i+1] - x[i]*x[i])*(x[i+1] - x[i]*x[i])) + (1 - x[i])*(1 - x[i]);
   

return y;


int main(void)
double *x;
//n is the number of variables and it may change
int n = 3;

x = (double*)malloc(n * sizeof(double));
double rosen(double *x, int n);

for(int i = 0; i < n; i++)

    x[i] = INT_MIN;

//That's the part where I can't figure out how to compute all the possibilities, changing the value of the last variable between INT_MIN AND INT_MAX. Then this variable gets the value of INT_MIN again and I will sum 0.1 to the variable antecedent, and then do all the process again to the last variable. And so on for all the N variables.
for(int i = n - 1; i >= 0; i--)

    while(x[i] < INT_MAX)
    
        x[i] = x[i] + 0.1;
           
    x[i] = INT_MIN;

上面的这段代码可能包含一些错误。但是,我唯一需要帮助的是改变 N 个变量的所有值。所以,我想要做的是取最后一个变量并在 INT_MIN 和 INT_MAX 之间改变它的值,总和为 0.1(我知道这真的是一个漫长的旅程)。之后,此变量将再次收到 INT_MIN 值,并且前项变量将变化 +0.1。然后,最后一个变量将再次从 INT_MIN 变为 INT_MAX。这将发生在所有 N 个变量上。

这是我试图解决的一个问题,即暴力破解函数的值以获得最小值。如果你们对我有一些建议或一些图书馆可能会有所帮助,我将非常感激。

【问题讨论】:

Rosenbrock 函数被用作优化算法的压力测试是有原因的:很难定义一种能够快速收敛到该函数的全局最小值或最大值的方法。除非您在问题上引入一些有助于更快收敛到解决方案的约束(或者,甚至更好,允许分析解决方案),否则您肯定需要使用蛮力方法。如果不是这样,Rosenbrock 函数就不会被用作优化算法的压力测试。 旁白:我希望double menor = DBL_MAX;double menor = HUGE_VAL; 而不是double menor = INT_MAX; 彼得,这正是我在最后几行中试图澄清的。我正在尝试使用蛮力找到它的最小值。这就是我遇到问题的地方。 除此之外,我明白了。但这对我来说并不重要。我仅将此 INT_MIN 用作基础。在大多数情况下,我想我只会分析一些小数字之间的函数。我想我的范围是 -5 到 5 【参考方案1】:

你可以有一个像下面这样的递归函数(粗略的 C):

void rosenMin(int maxDims, int currDim, double[] values, double* currMin)

    if (currDims == maxDims) 
        double rosenVal = rosen(values); // You need to implement this
        if (rosenVal < *currMax) 
            *currMin = rosenVal;
        
     else 
        for (double c = INT_MIN; c <= INT_MAX; c += 0.1) 
            values[currDim + 1] = c;
            rosenMin(maxDim, currDim + 1, values, currMin);
        
    


double[] values = new double[N]  0 ; // Check with C syntax how this'll look!
double min = INT_MAX
rosenMin(N, 1, values, &min);

【讨论】:

以上是关于找到具有 N 个变量的函数的最小值的主要内容,如果未能解决你的问题,请参考以下文章

scipy中的最小化,找到N维标量函数的所有局部最小值的算法

用 R 求最小值(1 个变量 X,n 次固定参数 U)

如何在有界的python优化中找到全局最小值?

在 Julia 中最小化具有多个参数的函数

pandas使用nsmallest函数返回特定数据列中前N个最小值(搜寻最小的n个元素)pandas使用nsmallest函数返回特定数据列中前N个最小值所对应的数据行

如何从 DataFrame,Python-3 中找到前 N 个最小值