最優化問題的一般形式
這個是數學上的一般形式,當求函數的最大值時候只要加上一個負號就可以
在程序中我們面對的問題一般是離散的即
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
, s->fval, size);
;
}
// printf(%5d , iter);
for (i = 0; i < np; i++)
{
;//printf(%10.3e , gsl_vector_get(s->x, i));
}
optim1<fval<fval, size);
//MessageBox(NULL,(TCHAR*)szbuffer,TEXT(長度優化),MB_OK);
//printf(f() = %12.11f size = %.3f
, s->fval, size);
fcf<paras, 0);//將函數值傳回來
y = gsl_vector_get(s->paras, 1);//
gsl_vector_free(x);
gsl_vector_free(ss);
gsl_multimin_fminimizer_free(s);
}
上文中可能會有一些細節錯誤,倉促之作見諒可以看其官方文檔的。。。。