解决的问题

最优化问题的一般形式


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);
}

上文中可能会有一些细节错误,仓促之作见谅可以看其官方文档的。。。。