最速下降法 c 语言程序,工程優化方法中的“最速下降法”和“DFP擬牛頓法”的 C 語言實現...

這個小程序是研一上學期的“工程優化”課程的大作業。其實這題本可以用 MATLAB 實現,但是我為了鍛煉自己薄弱的編碼能力,改為用 C 語言實現。這樣,就得自己實現矩陣的運算(加減乘除、求逆、拷貝);難點是求偏導,通過查資料,發現可以通過導數定義,即取極限的方法,來逐步逼近求得梯度;另外,沒法做到輸入任意公式,只能將公式硬編碼為函數,而求導函數需要傳入公式,就直接傳入函數指針了。思考、編碼、調試、測試共耗費兩周左右時間,完成於 2013/01/10。雖然為了認真做這個大作業而耽誤了期末考試的復習,但我不后悔做出的選擇,因為我學到了我覺得真正有用的東西。

源碼托管在 Github 上:點此打開鏈接

以下為完整的作業報告:

一、題目

用最速下降法和DFP擬牛頓法求解以下函數的最小值點以及最小值:

1.1 d6cfb8679c2c128969ef327b3a98e282.gif,其中,a877acbb0800e0dd7154af677e286b48.gif5fb646607a917726b8e12e6c9b0c4fde.giffcd7b73949279149dd6ff5c95508d4f4.gif

1.2 315cdd5710ebc459f4390931fb6afedd.gif,其中,6c8d0190f022ad70b40b073400830e91.gif525833429f9f23a9c0923f8f5de2bc65.gif179480055121fc661a26606047a4a57d.gif

二、算法

2.1最速下降法(steepest descent method)

算法步驟:

(1)取初始點2e2841abcf204890016014281459ada9.gif4b3816c75fdec0ed0fd836f7d48bc403.gif,精度ff964b498bb98a964a0f8111aae39315.gif,令6d401cd06e473570462ed79ed856dac4.gif

(2)計算36c30d09456d025a3191a3a2d80209a3.gif,若4007dee53791cbd0eaffc7593f2c44ef.gif,則停,21e6100920d55cac476f74b269bcd4f1.gif;否則轉(3);

(3)一維搜索:fe8659e56dbe5e2c7a37e7feccc4fdbd.gif

7bdd019221bcfa56933f05435428d25b.gif,轉(2)。

2.2擬牛頓法(DFP)

算法步驟:

(1)取初始點8ad5bd8182db225d78b536f71ac75b08.gif,允許誤差623b6c30b3be8cdb8de167ebe6b1549d.gif

(2)求2a876d659415be30bba281ff78e8c7d9.gif,若0eebde72026d66ff45d9bc73fd56906d.gif,令e2d6ad9beaf499f189ee4ccee28a5f0d.gif,算法停止;否則轉(3);

(3)令c9b6c9cb03382eb62bb89074268e9e39.gif

(4)令fd91d5ee417e680ce8c60abf6089c35b.gif

(5)求8d13ecf5eb0cca57bdd2ddef8f0934b9.gif6b8970f2d15ea6f7c4b5f872504b6051.gif,令c1b2c55a92a31188a38a99ce23bb3f3b.gif

(6)求d6fe22295cb478992c6febce6400cdad.gif,若a6bde34b92dba4d134a75e882201268e.gif,令24dc3447b2c0da3a1ddee9dd37862009.gif,算法停止;否則轉(6);

(7)若749207ead48a4726ec5c69fc2e5053a0.gif,則令31259346267ed43c51637faf4bbf81fe.gifc0589d25f02f52c4f6393f6b52e9cd20.gif,轉(3);

否則令d49d41a7aa9ee09fbc325bebd43884ba.gifd9ac44ea6eb0b90bc85db610f54e9aee.gif

計算014113147c67f6bd3ac9db4df502ebdc.gif

5d750cd844b2a0d39e19e581077e0787.gif,轉(4)。

2.3成功—失敗法(用於一維搜索)

算法步驟:

(1)取初始點57e6a7c830ca1bb4b3a745ef34cd1406.gif26875548c9df2b830b6ea1dd935a536a.gif,初始步長410d0d06893779f1d2d378f3a968ee42.gif和精度e6c68f67e9206bb2706d904778e1ff8f.gif,計算1e826a929a211d60a4635b14685da194.gif

(2)計算3bed8b36cc34b5ddefc5d7946b81fcfa.gif

(3)若38743c51f21434acd6d5787ecf0a8f14.gif(搜索成功),令8bd6988cf52d974bc4095e956a96e2fd.gif

a26f9ef33aac85050d4b0f478209784e.gif(搜索失敗),若c5a085ba9a9a18094d230596648aaa44.gif,令bab05de4afc43ba4684b5ab8d1afbef4.gif,停止迭代;

否者,令b46d131ff531cea022ce9502b5abefa5.gif,轉(2);

三、語言及算法實現說明

3.1算法實現語言及平台:

C語言+VC6.0(Debug模式)。

3.2幾個部分的思考:

(1)由於實現實時輸入函數多項式比較困難,本程序將函數多項式寫成模塊,存入程序文件中,由於程序使用函數指針,故可以陸續添加函數多項式而不必修改核心算法的代碼;

(2)由於函數不同,取值范圍不同,則算法需要不同的精度和步長,才能求得精確的結果,故本程序提供接口讓用戶指定;

(3)為了實現實時輸入變量維度,本程序使用動態內存分配,建立多維數組,模擬矩陣,用於存儲多維變量;

3.3算法實現的重難點分析:

(1)偏導數的求解:本程序使用偏導數的定義,即極限方法,求解指定點的函數值;

(2)DFP算法中d741454f93eb9f46bc03e76d7d2f3f08.gif的計算:本程序用多維數組來模擬矩陣進行運算。

四、程序中的主要模塊說明(完整程序及注釋見附錄)

4.1待求解的兩個函數:

其中vars為多維變量,n代表維度,這兩個模塊返回函數在指定點的值。

/* 求函數1在指定點的值 */

double fun1(double **vars, int n);

/* 求函數2在指定點的值 */

double fun2(double **vars, int n);

4.2利用偏導的定義求某個點的偏導數:

其中f為指定函數,vars為多維變量,grads為梯度,n為維度,prec為用戶指定的精度;該模塊求出函數的偏導存入矩陣grads中。

/* 用極限方法求指定點的偏導/梯度 */

void differ(double (*f)(double **vars, int n), double **vars, double **grads, int n, double prec);

4.3成功—失敗法,用於一維搜索:

其中f代表指定函數,vars為多維變量,d為二維搜索的方向,n為維度,prec為用戶指定的進度,h為用戶指定的步長;

該模塊將搜索到的84b2ea1dfbd61f013ba7b4a4d6c7d5a6.gif所對應的多維變量存入矩陣vars。

/* 成功失敗法,用於一維搜索 */

void suc_fail(double (*f)(double **vars, int n), double **vars, double **d, int n, double prec, double h);

4.4兩個核心算法:

其中fun為待解函數的標號,n為維度,prec為用戶指定的精度,h為用戶指定的用於一維搜索的步長;

這里這兩個模塊求出指定函數的最小值點和最小值並輸出。

/* 最速下降法(Speedest Descent Method)*/

void SD(int fun, int n, double prec, double h);

/* DFP擬牛頓法 */

void DFP(int fun, int n, double prec, double h);

五、程序使用說明

本程序將最速下降法和DFP法整合在一起,精度、步長、維度可由用戶指定:

(1)選擇方法(只輸入序號,‘0’退出);

(2)選擇函數(只輸入序號);

(3)輸入精度值(b68ae98bf9109a2ae7ad93dca93e45a2.gif);

(4)輸入一維搜索的步長;

(5)輸入變量維度;

(6)輸入變量的每個分量;

回車后程序開始使用指定方法對指定函數進行計算,計算過程中輸出迭代次數;

最后輸出結果:最小值點和最小值。

如下圖所示(下一頁):

b84d78e5a7ed8164704fec63b5c3ac12.png7a67788d1ac0e80bfb74eeccaa84efa7.png

6f286cbb975c308e6930980c1f63c619.png

六、運行結果及分析

6.1精度選擇:

(1)如下用最速下降法求函數1,精度取307c3b587b4512ec76518d3477c0488a.gif,步長取1,初值取(5,5,5),求解時陷入了無限迭代:

310a4832a481bd2d0a199cd08ddf9bdc.png96f79e34600a8715a6eacbff972eeed8.png……

(2)對於(1)的輸入,僅修改精度為0eaf88918868dccbbc629e157461c997.gif,僅迭代3次就求出了結果,且達到很高的精度,變量的三個分量和最優值都約等於0:

70930683fec3a1fb461734a8bc98ec24.pngad4787eed1bc370a6a29bc98495993ae.png

6.1.1小結

當精度值選擇太小,雖然可能得到更精確的結果,但會陷入死循環。當精度要求放松了一點,反而快速求出了精確結果,可見精度要選着適當,不可太大,也不可太小。以下試驗就選擇a0ee35e00e8801c0bbf03ae4ed129ccd.gif為精度值。

6.2一維搜索的步長選擇:

(1)如下用最速下降法求函數1,精度取90d4f81721aea64cf31dd4a91c3665b1.gif,步長取0.1,初值取(3,3,3),迭代3次求出結果,但是誤差很大:

daf4de714c95b6e58a0876f7345a135a.png444e1453df94d03f1632c2faad285bba.png

(2)針對(1),僅將步長改為0.5,迭代4次求出結果,精度很高:

3e09da52e5737e512ab906e4e00f758d.png408bd376680b3a50143f7149f6489428.png

(4)如下用最速下降法求函數2,精度取286cf9480fb302ec6d74d6b22c815a85.gif,步長取0.5,

初值取(300,300,300),迭代9次求出結果,但是誤差很大:

45baf0dc881cf54ef70351648c346018.pngfc8e4440f8a903a63a1a69aa346c38c7.png

(5)針對(4),僅將步長改為30,迭代17次求出結果,雖然結果與理想值0還是有一些誤差,但比(4)的結果精確了很多:

7b472067f4626245a33b6f0539072c14.png405e725a172a0ce367e98dde826fbb3b.png

6.2.1小結

一維搜索的步長也要選擇適當,否者求出的結果誤差很大。從以上對比可以看出,步長的選取要根據自變量的取值進行相應的調整:函數F1的2fbfe0cfa8b1e411e3134ede43e83e58.gif,變量取3,步長h取0.5時誤差較小;函數F2的fa0b452ac993b7ade0a29e04e7f9b42b.gif,變量取300,步長h取30時誤差較小,步長h取值為變量x取值的10%左右時誤差較小。

6.3比較最速下降法和DFP法:

6.3.1求解函數F1:精度取e8278141bb9b0722a1e9f4182ec7f12e.gif,步長取0.5,變量分別取(-5,-5,-5)、(5,5,5)

(1) 最速下降法

85729ff33f76c139cc1d288681eee6b3.pngc8f65a2bbbc31ed580941c5adb3133c2.png

c8952dcf7a39525bcb77a12b0e2d5bf4.pngf44f5309efbeadfaa089173a52a73b9e.png

(2) DFP

4769dadd7ab651f44dab37a77b87b121.pnga404607b64e20e1251f3841f1cc605b5.png

026c60423b184cfe7168462cbf24d52c.png5117bdadf489a3d22b9a8940d7f74170.png

6.3.2求解函數F2:精度取845dc0461a3d458b474ffb1de21aaf70.gif,步長取50,變量取(500,500,500)

(1)最速下降法

683d2d37456b5d2a1c5c0a7c2f0ee255.pngcc07d338c4cbc080cd3002ee026be26f.png

(2)DFP

37367a7083cf15a5524831cbc62f6016.png0ab88ae8fc4b88a2997986a2958cc433.png

6.3.3小結

由以上兩組對比可看出:

(1) 對於函數F1和F2,DFP算法都比最速下降法迭代次數多;

(2) 對於函數F1和F2,DFP算法都比最速下降法結果精確;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值