【问题标题】:Finding minimum of a function with N variables找到具有 N 个变量的函数的最小值
【发布时间】:2023-04-02 11:10:01
【问题描述】:

我正在尝试编写一个算法来定位可能有 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

标签: c c99 minimum repeat


【解决方案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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2015-10-25
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    相关资源
    最近更新 更多