机械优化设计鲍威尔法编程.docx
《机械优化设计鲍威尔法编程.docx》由会员分享,可在线阅读,更多相关《机械优化设计鲍威尔法编程.docx(16页珍藏版)》请在冰豆网上搜索。
机械优化设计鲍威尔法编程
鲍威尔法求解二维函数极小值的程序说明
一题目
利用鲍威尔法求函数
的极小值点。
二鲍威尔法基本思想:
1)给定初始点
,选取初始方向组,它由n各线性无关的向量
所组成。
2)从
出发,顺次沿
作一维搜索得
。
接着以
为起点,沿方向
移动一个
的距离,得到
分别称为一轮迭代的始点,终点和反射点。
始点,终点,反射点所对应的函数值分别表示为
同时计算各中间点处的函数值,并记为
因此有
计算n个函数值之差,记作
其中最大者记作
3)根据是否满足判别条件
和
来确定是否要对原方向组进行替换。
若不满足判别条件,则下轮迭代应对原方向组进行替换,将
补充到原方向组的最后位置,而除掉
。
即新方向组为
,
,…,
,
,…,
,
作为下轮迭代的搜索方向。
下轮迭代的始点取
方向进行一维搜索得极小点
。
4)判断是否满足收敛准则。
若满足则取
为极小点,否则应置
,返回2,继续进行下一轮迭代。
改进后的鲍威尔法程序框图如下:
三用鲍威尔法求函数
程序如下:
//鲍威尔法Dlg.cpp:
implementationfile
//
#include"stdafx.h"
#include"鲍威尔法.h"
#include"鲍威尔法Dlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
:
IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
voidCAboutDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CMyDlgdialog
CMyDlg:
:
CMyDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CMyDlg:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(CMyDlg)
m_x01=0.0f;
m_x02=0.0f;
m_x1=0.0f;
m_x2=0.0f;
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCMyDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDlg)
DDX_Text(pDX,IDC_x01,m_x01);
DDX_Text(pDX,IDC_x02,m_x02);
DDX_Text(pDX,IDC_x1,m_x1);
DDX_Text(pDX,IDC_x2,m_x2);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMyDlg,CDialog)
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CMyDlgmessagehandlers
BOOLCMyDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
//Add"About..."menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
//TODO:
Addextrainitializationhere
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCMyDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
voidCMyDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog:
:
OnPaint();
}
}
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORCMyDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidCMyDlg:
:
OnOK()
{
//TODO:
Addextravalidationhere
//CDialog:
:
OnOK();
UpdateData(true);
inti,n;
doubleh1,h2,h3,m,flag,X00[2][1],d01[2][1],d02[2][1],d03[2][1];//确定键的执行程序
doubleX01[2][1],X02[2][1],X03[2][1];
doubleF0,F1,F2,F3,e1,e2,em;
doubleX[2][1];
doublef0,f1,f2,f3;
X00[0][0]=m_x01;//对初始搜索点进行赋值
X00[1][0]=m_x02;
d01[0][0]=1,d01[1][0]=0;//初始索索方向的确定
d02[0][0]=0,d02[1][0]=1;
i=1;
do
{
F0=(X00[0][0]*X00[0][0]+2*X00[1][0]*X00[1][0]-4*X00[0][0]-2*X00[0][0]*X00[1][0]),f0=F0;//初始点函数值
h1=(4*d01[0][0]+2*d01[0][0]*X00[1][0]+2*d01[1][0]*X00[0][0])/(2*d01[0][0]*d01[0][0]+//确定搜索方向
4*d01[1][0]*d01[1][0]-4*d01[1][0]*d01[0][0]);
X01[0][0]=X00[0][0]+h1*d01[0][0],X01[1][0]=X00[1][0]+h1*d01[1][0];
F1=(X01[0][0]*X01[0][0]+2*X01[1][0]*X01[1][0]-4*X01[0][0]-2*X01[0][0]*X01[1][0]),f1=F1;//确定F的函数值
h2=(4*d02[0][0]+2*d02[0][0]*X01[1][0]+2*d02[1][0]*X01[0][0])/(2*d02[0][0]*d02[0][0]+//确定搜索步长
4*d02[1][0]*d02[1][0]-4*d02[1][0]*d02[0][0]);
X02[0][0]=X01[0][0]+h2*d02[0][0];X02[1][0]=X01[1][0]+h2*d02[1][0];
F2=(X02[0][0]*X02[0][0]+2*X02[1][0]*X02[1][0]-4*X02[0][0]-2*X02[0][0]*X02[1][0]),f2=F2;
//确定F2的函数值
e1=f0-f1;//进行判定
e2=f1-f2;
if(e1>e2)em=e1,m=1;
elseem=e2,m=2;
//////////////////////////////////////////////////////////////////////////////
d03[0][0]=X02[0][0]-X00[0][0];
d03[1][0]=X02[1][0]-X00[1][0];
X03[0][0]=2*X02[0][0]-X00[0][0];
X03[1][0]=2*X02[1][0]-X00[1][0];
F3=(X03[0][0]*X03[0][0]+2*X03[1][0]*X03[1][0]-4*X03[0][0]-2*X03[0][0]*X03[1][0]),f3=F3;//确定F3的函数值
while(F3>=F0&&(F0-2*F2+F3)*(F0-F2-em)*(F0-F2-em)>=0.5*(F0-F3)*(F0-F3))//不满足判别条件
{
i++;
if(F2{
X00[0][0]=X02[0][0],X00[1][0]=X02[1][0];
//以函数最小者作为下轮迭代的始点
F0=(X00[0][0]*X00[0][0]+2*X00[1][0]*X00[1][0]-4*X00[0][0]-2*X00[0][0]*X00[1][0]),f0=F0;
//进行第二轮搜索
h1=(4*d01[0][0]+2*d01[0][0]*X00[1][0]+2*d01[1][0]*X00[0][0])/(2*d01[0][0]*d01[0][0]+//确定步长
4*d01[1][0]*d01[1][0]-4*d01[1][0]*d01[0][0]);
X01[0][0]=X00[0][0]+h1*d01[0][0],X01[1][0]=X00[1][0]+h1*d01[1][0];
F1=(X01[0][0]*X01[0][0]+2*X01[1][0]*X01[1][0]-4*X01[0][0]-2*X01[0][0]*X01[1][0]),f1=F1;
//确定函数值
h2=(4*d02[0][0]+2*d02[0][0]*X01[1][0]+2*d02[1][0]*X01[0][0])/(2*d02[0][0]*d02[0][0]+
//确定步长
4*d02[1][0]*d02[1][0]-4*d02[1][0]*d02[0][0]);
X02[0][0]=X01[0][0]+h2*d02[0][0];X02[1][0]=X01[1][0]+h2*d02[1][0];
F2=(X02[0][0]*X02[0][0]+2*X02[1][0]*X02[1][0]-4*X02[0][0]-2*X02[0][0]*X02[1][0]),f2=F2;
//确定函数值
e1=f0-f1;
e2=f1-f2;
if(e1>e2)em=e1,m=1;//进行判断
elseem=e2,m=2;
d03[0][0]=X02[0][0]-X00[0][0];//确定新的搜索方向
d03[1][0]=X02[1][0]-X00[1][0];
X03[0][0]=2*X02[0][0]-X00[0][0];
X03[1][0]=2*X02[1][0]-X00[1][0];
F3=(X03[0][0]*X03[0][0]+2*X03[1][0]*X03[1][0]-4*X03[0][0]-2*X03[0][0]*X03[1][0]),f3=F3;
//确定函数值
}
else
{
X00[0][0]=X03[0][0],X00[1][0]=X03[1][0];
F0=(X00[0][0]*X00[0][0]+2*X00[1][0]*X00[1][0]-4*X00[0][0]-2*X00[0][0]*X00[1][0]),f0=F0;
h1=(4*d01[0][0]+2*d01[0][0]*X00[1][0]+2*d01[1][0]*X00[0][0])/(2*d01[0][0]*d01[0][0]+
4*d01[1][0]*d01[1][0]-4*d01[1][0]*d01[0][0]);
X01[0][0]=X00[0][0]+h1*d01[0][0],X01[1][0]=X00[1][0]+h1*d01[1][0];
F1=(X01[0][0]*X01[0][0]+2*X01[1][0]*X01[1][0]-4*X01[0][0]-2*X01[0][0]*X01[1][0]),f1=F1;
h2=(4*d02[0][0]+2*d02[0][0]*X01[1][0]+2*d02[1][0]*X01[0][0])/(2*d02[0][0]*d02[0][0]+
4*d02[1][0]*d02[1][0]-4*d02[1][0]*d02[0][0]);
X02[0][0]=X01[0][0]+h2*d02[0][0];X02[1][0]=X01[1][0]+h2*d02[1][0];
F2=(X02[0][0]*X02[0][0]+2*X02[1][0]*X02[1][0]-4*X02[0][0]-2*X02[0][0]*X02[1][0]),f2=F2;
e1=f0-f1;
e2=f1-f2;
if(e1>e2)em=e1,m=1;
elseem=e2,m=2;
d03[0][0]=X02[0][0]-X00[0][0];
d03[1][0]=X02[1][0]-X00[1][0];
X03[0][0]=2*X02[0][0]-X00[0][0];
X03[1][0]=2*X02[1][0]-X00[1][0];
F3=(X03[0][0]*X03[0][0]+2*X03[1][0]*X03[1][0]-4*X03[0][0]-2*X03[0][0]*X03[1][0]),f3=F3;
}
}
if(m=1)d01[0][0]=d03[0][0],d01[1][0]=d03[1][0];
else
{
if(m=2)
d02[0][0]=d03[0][0],d02[1][0]=d03[1][0];
}
h3=(4*d03[0][0]+2*d03[0][0]*X02[1][0]+2*d03[1][0]*X02[0][0])/(2*d03[0][0]*d03[0][0]+
4*d03[1][0]*d03[1][0]-4*d03[1][0]*d03[0][0]);
X00[0][0]=X02[0][0]+h3*d03[0][0];
X00[1][0]=X02[1][0]+h3*d03[1][0];
if(i=2)break;
}while(abs(X02[0][0]-X00[0][0])>0.001&&abs(X02[1][0]-X00[1][0])>0.001);
//输出极小值点
X[0][0]=X00[0][0],X[1][0]=X00[1][0];
m_x1=X[0][0];
m_x2=X[1][0];
UpdateData(false);
}
程序运行结果:
四结论
由该程序的运行结果可知,要求函数的极小值的在(10,5)处。
该程序利用VC++6.0下的MFC插件,创建对话框,将运算结果很形象的表现出来。
经验证,运算结果完全正确。
验证了该程序的可行性。