日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言编程用进退法求搜索区间代码,用c对函数进行优化的问题

發布時間:2023/12/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言编程用进退法求搜索区间代码,用c对函数进行优化的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

//多維無約束優化軟件設計#include

#include

#include

double det=1e-5; //計算精度double det1=1e-3; //梯度判斷精度double ak=3e-3; //搜索步長double dx=1e-4; //梯度計算步長

/*目標函數(n維)

入口參數:

x :n維數組,自變量

返回值 :函數值*/

double f(double *x)

{

double y;

y=(x[0]-2)*(x[0]-2)*(x[0]-2)*(x[0]-2)+(x[0]-2*x[1])*(x[0]-2*x[1]);

//y=(x[0]-2)^4+(x[0]-2*x[1])^2; return y;

}

/*計算X(k+1)=X(k)+a*S(k)

入口參數:

x_k : n維數組,自變量

s_k : n維數組,方向向量

a : 方向步長

n : 維數

出口參數:

x_k1 : 轉換后的n維數組*/

void fun(double *x_k1,double *x_k,double *s_k,double a,int n)

{

int i;

for(i=0;i

x_k1[i]=x_k[i]+a*s_k[i];

}

/*進退法求谷區間

入口參數:

n :優化模型維數

x_k :n維數組,初始點坐標

s_k :n維數組,搜索方向向量

出口參數:

a1 :搜索區間步長下限

a3 :搜索區間步長上限*/

void Get_Search_area(int n,double *x_k,double *s_k,double *a1,double *a3)

{

double a=ak,s,f0,a2=0;

double f1=0,f2=0,f3=0;

double *x_k1;

x_k1=(double*)malloc(sizeof(double)*n);

f2=f(x_k);

while(1)

{

*a1=a2+a;

fun(x_k1,x_k,s_k,*a1,n);

f1=f(x_k1);

if(f1>f2)

{

if(a==ak)

{

*a3=*a1;

f3=f1;

a=-a;

continue;

}

else if(*a1>*a3)

{

s=*a1;

*a1=*a3;

*a3=s;

f0=f1;

f1=f3;

f3=f0;

break;

}

else break;

}

else

{

*a3=a2;

a2=*a1;

f3=f2;

f2=f1;

a=2*a;

continue;

}

}

free(x_k1);

}

/*黃金分割法求極小值*/

/*入口參數:

n :優化模型維數

a1 :搜索區間步長下限

a4 :索區間步長上限

s_k :n維數組,搜索方向向量*/

/*出口參數:

x_k :n維數組,極小點坐標*/

void Gold_division(int n,double a1,double a4,double *x_k,double *s_k)

{

double a2,a3,f2,f3,a_star;

double *x_k2,*x_k3; int i;

x_k2=(double*)malloc(sizeof(double)*n);

x_k3=(double*)malloc(sizeof(double)*n);

for(i=0;i

{

x_k2[i]=0;

x_k3[i]=0;

}

a2=a1+0.382*(a4-a1);

fun(x_k2,x_k,s_k,a2,n);

f2=f(x_k2);

a3=a1+0.618*(a4-a1);

fun(x_k3,x_k,s_k,a3,n);

f3=f(x_k3);

do

{

if(f2<=f3)

{

a4=a3;

a3=a2;

f3=f2;

a2=a1+0.382*(a4-a1);

fun(x_k2,x_k,s_k,a2,n);

f2=f(x_k2);

}

else

{

a1=a2;

a2=a3;

f2=f3;

a3=a1+0.618*(a4-a1);

fun(x_k3,x_k,s_k,a3,n);

f3=f(x_k3);

}

} while(fabs(a4-a1)>det);

a_star=(a1+a4)*0.5;

fun(x_k,x_k,s_k,a_star,n);

free(x_k2);

free(x_k3);

}

/*計算函數梯度

入口參數:

n :優化模型維數

dx :梯度步長

x_k :n維數組,初始點坐標

出口參數:

s_k :梯度的負方向向量*/

void tidu(int n,double dx,double x[],double s_k[])

{

int i;

double *x0;

x0=(double*)malloc(sizeof(double)*n);

for(i=0;i

x0[i]=x[i];

for(i=0;i

{

x0[i]=x[i]+dx;

s_k[i]=(f(x0)-f(x))/dx*(-1);

x0[i]=x0[i]-dx;

}

free(x0);

}

/*計算梯度范數

入口參數:

n :優化模型維數

s_k :梯度的負方向向量

返回值:梯度范數*/

double f_fanshu(int n,double s_k[])

{

int i;

double sum=0;

for(i=0;i

sum+=s_k[i]*s_k[i];

return (sqrt(sum));

}

/*梯度法求最優函數值

/*入口參數:

n :優化模型維數

x_k :n維數組,極小點坐標*/

/*出口參數:

f0 :函數極小值*/

void fun_tidu(int n,double *x_k,double *f0)

{

double *s_k;

double a1=0,a3=0;

double *a_1,*a_3;

a_1=&a1;

a_3=&a3;

s_k=(double*)malloc(sizeof(double)*n);

while(1)

{ tidu(n,dx,x_k,s_k);

if(f_fanshu(n,s_k)>det1)

{

Get_Search_area(n,x_k,s_k,a_1,a_3);

Gold_division(n,*a_1,*a_3,x_k,s_k);

}

else

break;

}

*f0=f(x_k);

free(s_k);

}

/*主函數*/

int main()

{

int n,i;

double *x_k,*f;

double f0=0;

f=&f0;

puts("原函數為f=(x[0]-2)*(x[0]-2)*(x[0]-2)*(x[0]-2)+(x[0]-2*x[1])*(x[0]-2*x[1]);\n");

puts("請輸入變量維數n:\n");

scanf("%d",&n);

x_k=(double*)malloc(sizeof(double)*n);

printf("輸入起始坐標x_k:\n");

for(i=0;i

{

scanf("%lf",&x_k[i]);

fun_tidu(n,x_k,f);

}

puts("函數極小點坐標:\n");

for(i=0;i

printf("%lf;",x_k[i]);

printf("\n");

puts("函數最優值:\n");

printf("%lf\n",*f);

free(x_k);

return 0;

}

總結

以上是生活随笔為你收集整理的c语言编程用进退法求搜索区间代码,用c对函数进行优化的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。