我正在尝试对一种算法进行编码,以查找可能具有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个变量都会发生这种情况。
这是我要解决的问题,以蛮力地使函数的值最小。如果你们对我有一些提示或可能有用的图书馆,我将非常感激。
答案 0 :(得分:0)
您可以具有如下所示的递归函数(粗略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);