【发布时间】: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