找到具有 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维标量函数的所有局部最小值的算法
pandas使用nsmallest函数返回特定数据列中前N个最小值(搜寻最小的n个元素)pandas使用nsmallest函数返回特定数据列中前N个最小值所对应的数据行