解决的问题
最优化问题的一般形式
minf(paras)
s.t.paras∈[paras_lower,paras_upper]
这个是数学上的一般形式,当求函数的最大值时候只要加上一个负号就可以
在程序中我们面对的问题一般是离散的即
f(paras)一般情况下是关于
Xi的一个离散变量的。而此时问题会转化为
valueType errorfunc(valueType* paras,valueType* X)//误差函数输入要求的参数和具体的X的值因为多个以数组的形式传值。
{
sum(f(paras,X_i))//求得函数关于每个X_i的函数和
}
我们通过调节要求得参数paras来使得errorfunc返回的值最小
exp=min_value//收敛的最小值
while(errorfunc( paras, X)>exp)//当误差函数的变化大于最小值时候
{
adjust(paras);//调整参数,继续判断其收敛与否
}
解决的方法
当问题是线性的时候
AX=b
利用SVD分解就可以求得最后的解,这种方法比较简单,网上也有很多的代码,下次有机会在补上。
当问题非线性的时候
如果不采用函数库的方法的话,就只能具体问题具体分析了。
在这里我们采用GNU GSL函数库
[ 下载地址 ]
下面就是我们的函数代码
void my_df (const gsl_vector *params, void *xandcval)//paras是需要传入的数值,可以是X和一些固定参数,也可以用全局变量的方法,para是我们最后需要调整的参数
{
double x, y;
double *Xandcval = (double *)xandcval;//
x = gsl_vector_get(params, 0);//将要求得paras读取出来
y = gsl_vector_get(params, 1);
return errorfunc(...);
}
void optim1()
{
size_t np = 30;//paras的大小
double Xandcval[2] = { 1, 2 };//这里假设只有参数,当有很多X时候需要构造
const gsl_multimin_fminimizer_type *T_min =
gsl_multimin_fminimizer_nmsimplex;
gsl_multimin_fminimizer *s = NULL;
gsl_vector *ss, *x;
gsl_multimin_function minex_func;
size_t iter = 0, i;
int status;
double size;
/* Initial vertex size vector */
ss = gsl_vector_alloc(np);
/* Set all step sizes to 1 */
gsl_vector_set_all(ss, 0.00001);//这里的0.00001指的是exp
/* Starting point */
paras = gsl_vector_alloc(np);
//对需要求得参数赋予初始值12 123
gsl_vector_set(paras , 0,12);//参数表,序号,值
gsl_vector_set(paras , 1, 123);
/* Initialize method and iterate */
minex_func.f = &my_f1;//误差函数的名称
minex_func.n = np;
minex_func.params = (void *)∥
char szbuffer[1000];
s = gsl_multimin_fminimizer_alloc(T_min, np);
gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
do
{
iter++;
status = gsl_multimin_fminimizer_iterate(s);
if (status)
break;
size = gsl_multimin_fminimizer_size(s);
status = gsl_multimin_test_size(size, 1e-12);
if (status == GSL_SUCCESS)//收敛了
{
printf("f() = %12.11f size = %.3f\n", s->fval, size);
;
}
// printf("%5d ", iter);
for (i = 0; i < np; i++)
{
;//printf("%10.3e ", gsl_vector_get(s->x, i));
}
optim1<<"f() = "<<s->fval<<"size="<<size<<"\n";
// sprintf(szbuffer,"f() = %12.11f size = %.3f\n", s->fval, size);
//MessageBox(NULL,(TCHAR*)szbuffer,TEXT("长度优化"),MB_OK);
//printf("f() = %12.11f size = %.3f\n", s->fval, size);
fcf<<"fc[0]="<<fc[0]<<";\t"<<"fc[1]="<<fc[1]<<";\t"<<"cc[0]="<<cc[0]<<";\t"<<"cc[1]="<<cc[1]<<";\n";
} while (status == GSL_CONTINUE && iter < 15622);//此处设置最大迭代次数,此处为15622
///
x = gsl_vector_get(s->paras, 0);//将函数值传回来
y = gsl_vector_get(s->paras, 1);//
gsl_vector_free(x);
gsl_vector_free(ss);
gsl_multimin_fminimizer_free(s);
}
上文中可能会有一些细节错误,仓促之作见谅可以看其官方文档的。。。。