外推法c语言,共轭梯度法,黄金分割,外推法C语言代码

共轭梯度法求函数极小值的方法,利用到了黄金分割和外推法求方向上的极小值。

#include

#include

#define lamda 0.618

//************************

float a,b,c,d,e,g;//目标函数的系数

float x1,x2,arf;//目标函数的变量

float a0[2],b0[2],c0[2];//一维搜索区间的变量定义

float xi1,xi2,xi3,xi4;

float min_gold_x[2];

float directon[2];//搜索方向

float powell_minx[2],xg_min[2];

float _g[2];

//***********************************

void get_num()

{

printf("输入目标函数系数\n");

scanf("%f %f %f %f %f %f",&a,&b,&c,&d,&g,&e);

printf("a=%f b=%f c=%f d=%f e=%f g=%f\n",a,b,c,d,e,g);

printf("\n目标函数为:\n");

printf("y=%f*x1*x1+%f*x2*x2+%f*x1+%f*x2+%f*x1*x2+%f\n",a,b,c,d,g,e);

}

//功能函数***************************

float fun(float x1,float x2)

{

float y;

y=a*x1*x1+b*x2*x2+c*x1+d*x2+g*x1*x2+e;

return y;

}

//*********计算步长***

float change(float h0,float d[2])

{

float m,n;

n=(d[0]*d[0]+d[1]*d[1])/(h0*h0);

m=sqrt(n);

return m;

}

//***区间搜索********************

void search(float x01,float x02,float h0,float d[2])

{

float y0,y1,y2,n,di[2],x1[2],x2[2],x0[2];

int j,k=0;

for(j=0;j<2;j++)//读取搜索方向

{

di[j]=d[j];

}

x0[0]=x01,x0[1]=x02;

n=change(h0,di);

di[0]=di[0]/n;

di[1]=di[1]/n;

x1[0]=x0[0]+di[0];

x1[1]=x0[1]+di[1];

y0=fun(x0[0],x0[1]);

y1=fun(x1[0],x1[1]);

if(y1<=y0)

{

for(j=0;j<2;j++)

{

di[j]=2*di[j];

x2[j]=x1[j]+di[j];

}

}

if(y1>y0)

{

for(j=0;j<2;j++)

{

di[j]=(-2)*di[j];

x2[j]=x1[j]+di[j];

}

}

while(1)

{

y2=fun(x2[0],x2[1]);

if(y2<=y1)

{

y0=y1;y1=y2;

for(j=0;j<2;j++)

{

x0[j]=x1[j];

x1[j]=x2[j];

}

for(j=0;j<2;j++)

{

di[j]=2*di[j];

x2[j]=x1[j]+di[j];

}

}

if(y2>y1)

{

for(j=0;j<2;j++)

{

a0[j]=x0[j];

b0[j]=x1[j];

c0[j]=x2[j];

}

break;

}

}

}

//*********************黄金分割********************

void gold_d(float a[2],float b[2],float dlt)

{

float alf1[2],alf2[2],y1,y2;

float at[2],bt[2],temp1[2],temp2[2];

float m,n,i,k;

int j;

/*dlt=dlt*dlt;*/

for(j=0;j<2;j++)

{

at[j]=a[j];

bt[j]=b[j];

}

for(j=0;j<2;j++)

{

alf1[j]=bt[j]-lamda*(bt[j]-at[j]);

alf2[j]=at[j]+lamda*(bt[j]-at[j]);

}

y1=fun(alf1[0],alf1[1]);

y2=fun(alf2[0],alf2[1]);

while(1)

{

if(y1>=y2)

{

for(j=0;j<2;j++)

{

at[j]=alf1[j];

alf1[j]=alf2[j];

}

y1=y2;

for(j=0;j<2;j++)

{

alf2[j]=at[j]+lamda*(bt[j]-at[j]);

}

y2=fun(alf2[0],alf2[1]);

}

else

{

for(j=0;j<2;j++)

{

bt[j]=alf2[j];

alf2[j]=alf1[j];

}

y2=y1;

for(j=0;j<2;j++)

{

alf1[j]=bt[j]-lamda*(bt[j]-at[j]);

}

y1=fun(alf1[0],alf1[1]);

}

for(j=0;j<2;j++)

{

temp1[j]=bt[j]-at[j];

}

n=(y2-y1)/y2;n=fabs(n);

m=temp1[0]*temp1[0]+temp1[1]*temp1[1];

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
共轭梯度法是一种用于求解线性方程组的迭代方法,以下是一个使用C语言实现的共轭梯度法程序: ```c #include<stdio.h> void conjugate_gradient(double A[], double b[], double x[], int n, int max_iter) { double r[n], p[n], Ap[n]; double alpha, beta, residual; // 初始化向量 for (int i = 0; i < n; i++) { r[i] = b[i]; p[i] = r[i]; } for (int k = 0; k < max_iter; k++) { // 计算Ap for (int i = 0; i < n; i++) { Ap[i] = 0; for (int j = 0; j < n; j++) { Ap[i] += A[i*n+j] * p[j]; } } // 计算alpha和更新x double pAp = 0, rr = 0; for (int i = 0; i < n; i++) { pAp += p[i] * Ap[i]; rr += r[i] * r[i]; } alpha = rr / pAp; for (int i = 0; i < n; i++) { x[i] += alpha * p[i]; r[i] -= alpha * Ap[i]; } // 计算残差,检查是否收敛 residual = 0; for (int i = 0; i < n; i++) { residual += r[i] * r[i]; } if (residual < 1e-6) { break; } // 计算beta和更新p double old_rr = rr; rr = 0; for (int i = 0; i < n; i++) { rr += r[i] * r[i]; } beta = rr / old_rr; for (int i = 0; i < n; i++) { p[i] = r[i] + beta * p[i]; } } } int main() { double A[4] = {4, -1, -1, 3}; // 线性方程组的系数矩阵 double b[2] = {2, 3}; // 线性方程组的常数向量 double x[2] = {0, 0}; // 初始解向量 int n = 2; // 线性方程组的未知数个数 int max_iter = 10000; // 最大迭代次数 conjugate_gradient(A, b, x, n, max_iter); printf("Solution: x = [%.2f %.2f]\n", x[0], x[1]); return 0; } ``` 以上程序使用共轭梯度法求解了一个含有2个未知数的线性方程组,其中系数矩阵A为4 -1 -1 3,常数向量b为2 3,初始解向量x为0 0,最大迭代次数max_iter为10000。程序运行后将输出解向量x的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值