基于MATLAB和C#编程实现二元函数梯度下降法求极小值

来源:互联网 发布:安森垚 知乎 编辑:程序博客网 时间:2024/05/20 00:16

Matlab 代码

//////////////////////////////////////////对x的偏导

function dx=fx(x,y)
dx=sin(y)*exp((1-cos(x))^2)*2*(1-cos(x))*sin(x)-sin(x)*exp(((1-sin(y)))^2)+2*(x-y);
end

////////////////////////////////////对y的偏导

function dy=fy(x,y)
dy=cos(y)*exp((1-cos(x))^2)-cos(x)*exp(((1-sin(y)))^2)*2*(1-sin(y))*cos(y)-2*(x-y);
end

/////////////////////////////////////二元函数

function p=fun(x,y)
p=sin(y)*exp((1-cos(x))^2)+cos(x)*exp(((1-sin(y)))^2)+(x-y)^2;
end

///////////////////////梯度下降法

clc
clear
%%%%%%%%%%%%%%%梯度下降法
%设置步长,x,y初始值
h=0.001;x(1)=-4;y(1)=-2;%初始值
fb=0;
f(1)=fun(x(1),y(1));
n=1;
minf=0;
minx=x(1);
miny=y(1);


while abs(f(n)-fb)>0.0001
dx=fx(x(n),y(n));
dy=fy(x(n),y(n));
deltax=h*dx;
deltay=h*dy;
x(n+1)=x(n)-deltax;
y(n+1)=y(n)-deltay;
f(n+1)=fun(x(n+1),y(n+1));
fb=f(n);
if f(n+1)<minf
    minf=f(n+1);
    minx=x(n+1);
    miny=y(n+1);
end
 n=n+1;
if(x(n)>0)||(x(n)<-5)
    break;
end
if(y(n)>0)||(y(n)<-5)
    break;
end
if n>1000
    break
end
end
minf
minx
miny

plot(1:n,f);
title('极小值求解');
xlabel('迭代次数n');
ylabel('函数值');
grid on;




C#代码

#include<stdio.h>
#include<math.h>
/////全局变量定义


double h=0.001;//步长
double error=0.0001;//误差
/////函数声明
double dx(double x,double y);//x偏导
double dy(double x,double y);//y偏导
double fun(double x,double y);//二元函数
void tidu(double *result,double x1,double y1);//梯度下降法函数求解
int main()
{
double jieguo[3];
tidu(jieguo,-2,-4);
printf("minf=%lf\nminx=%lf\nminy=%lf\n",jieguo[0],jieguo[1],jieguo[2]);
return 0;
}
double dx(double x,double y)

double a;
a=sin(y)*exp(pow((1-cos(x)),2))*2*(1-cos(x))*sin(x)-sin(x)*exp(pow(((1-sin(y))),2))+2*(x-y);
return a;
}
double dy(double x,double y)
{
double b;
b=cos(y)*exp(pow((1-cos(x)),2))-cos(x)*exp(pow(((1-sin(y))),2))*2*(1-sin(y))*cos(y)-2*(x-y);
return b;
}
double fun(double x,double y)
{
double c;
c=sin(y)*exp(pow((1-cos(x)),2))+cos(x)*exp(pow(((1-sin(y))),2))+pow((x-y),2);
return c;
}
void tidu(double *result,double x1,double y1)
{
double fb=0;
double f1;
f1=fun(x1,y1);
int n=1;
double minf=0;
double minx=x1;
double miny=y1;
while(fabs(f1-fb)>error)
{
double deltax,deltay;
double x;
double y;
double f;
deltax=dx(x1,y1);
deltay=dy(x1,y1);
x=x1-h*deltax;
y=y1-h*deltay;
x1=x;
y1=y;
f=fun(x,y);
fb=f;
if (f<minf)
{
     minf=f;
minx=x1;
miny=y1;
}
n=n+1;
if(x1>0||x1<-5)
{
printf("超界\n");
break;
}
if(y1>0||y1<-5)
{
printf("超界\n");
break;
}
if(n>1000)
{
break;
}
}
*(result)=minf;
        *(result+1)=minx;
*(result+2)=miny;
return;


}



原创粉丝点击