计算方法汇总
?
一、內容簡介
?????
?
?
?
本次報告,是在完成整個學期的計算方法學習之后做出的一次一小組為單位的總體匯報,我們匯報的內容主要是建立在以全英文教材《劍橋數值方法教材》學習的基礎上,對教材的四塊主要內容經行編程實現、組內交流、組間匯報、匯報總結等學習討論之后進行的一次總結歸納。此次報告主要分為四大部分,第一部分我們將著重講解一下計算方法課程的授課方式和小組內的學習情況,第二部分我們主要講述一下課程的主要內容和我們對計算方法經行的一下課外的拓展,第三部分我們將展示一下我們組內的成員對計算方法的學習和授課方式的感受,第四部分我們將回顧一學期的學習組長經行一下小組的一個學習總結。此次報告我們不局限于教材上所學的知識,通過多個算法的比較,我們嘗試著探究效率更高、時間空間更加優化的算法。于是,我們經行的廣泛的查詢,雖然時間不是很充裕,在研究方面也是很淺顯,但是我們不會以此次報告為一個終結點,而是組織組內有興趣的人繼續下去,對計算方法這門課程有一個更加深入的了解。
?
?
?
?
二、前言
?
?
計算方法又稱“數值分析”,是為各種數學問題的數值解答研究提供最有效的算法。主要內容為函數逼近論,數值微分、數值積分,誤差分析等。常用方法有迭代法、差分法、插值法、有限元素法、線性方程組等。現代的計算方法還要求適應電子計算機的特點。
本課程是信息與計算科學、數學與應用數學本科專業必修的一門專業基礎課,我們需在掌握數學分析、高等代數和常微分方程的基礎知識之上,學習本課程。 “計算方法”是專門研究各種數學問題的近似解的一門課程,通過這門課程的教學,使學生掌握用數值分析方法解決實際問題以及算法原理和理論分析,提高我們應用數學知識解決實際問題的能力。
對于這門課程的學習,我們采取的是“大班授課,小組合作”的教學方式,即在承認課堂教學為基本教學組織形式的前提下,教師以學生學習小組為重要的教學組織手段,通過指導小組成員展開合作,形成“組內成員合作,組間成員競爭”的學習模式,發揮群體的積極功能,提高個體的學習動力和能力,達到完成特定的教學任務的目的,更好的幫助小組成員完成學習任務和教學任務。同時在組間實行競爭機制更能有效的調動學生的參與熱情和學習積極性,培養學生的競爭意識。我們使用的是劍橋數值方法教材,在學習計算方法課程的同時,也進一步提高了我們的英語水平,此乃一舉兩得,使用全英文教材使我們直接接觸到當前國際上最先進的剖析和見解,避免了中文翻譯帶來的錯誤和問題復雜化。
本小組一共有11位成員,在組長的英明領導下,一共成功進行了四次精彩的實習報告,每一次實習過程中,大家伙都積極參與,勇于表現,各盡其責,基本上人人都會寫出一份自己的程序并上機演示,積極與小組成員討論、改進、升華,最后由組長進行總結,篩選出最有特色、最具健壯性、最好的程序作為本小組進行報告的內容,并安排各小組成員的后續工作,如做PPT、寫報告、定發言人等,確保每位小組成員都有事可做,發揮自己的特長,實現自己的價值。一切的一切都是為了能讓該次實習報告做到最好,體現出本組強大的實力以及各成員強烈的積極性和責任心,發揮出團隊最大的力量。
感謝曾三友老師能給我們這樣一次機會體驗小組合作所帶來的收獲和喜悅,不僅培養我們的合作意識、團隊精神、理性思考、同時也提升我們的境界拓寬我們的胸懷,尺有所短寸有所長,要多發現和挖掘各自的優勢和長處,求知的過程要提倡個人資源互補、優勢共享才能少走彎路,攜手共贏。同時也非常感謝組內所有成員,正是因為大家伙的齊心協力,眾志成城,不分彼此,團結合作,互利共贏,共同成長,才取得了這樣不錯的成績,謝謝大家。
由于小組水平所限,不當之處在所難免,歡迎老師還有各位同學批評指正,在下代表本組成員感激不盡。
?
?
?
?
?
三、目錄
一、內容簡介—————————————————— 02
二、前言———————————————————— 03
三、目錄———————————————————— 04
三、主要內容—————————————————— 05
??? 1、計算方法概要——————————————— 05
?? ?2、方程求根??? ——————————————— 06
3、方程組求解? ——————————————— 12
??? 4、方程積分??? ——————————————— 23
5、方程微分??? ——————————————— 39
五、結課感言—————————————————— 46
小組總結????? ——————————————— 46
小組成員感言? ——————————————— 47
六、小組分工—————————————————— 52
七、總結———————————————————— 54
?
?
?
?
?
?
?
?
?
?
?
?
?
四、主要內容
計算方法概要
介紹一下什么是計算方法
??? 現代科學發展依賴于理論研究、科學實驗與科學計算三種主要手段,它們相輔相成,可以互相補充又都不可缺少。由于計算機技術的發展及其在各技術科學領域的應用推廣與深化,新的計算性學科分支紛紛興起,如計算力學、計算物理、計算化學、計算經濟學等等,不論其背景與含義如何,要用計算機進行科學計算都必須建立相應的數學模型,并研究其適合于計算機編程的計算方法。“數值計算方法”是計算數學的一個主要部分。伴隨著計算機技術的飛速發展和計算數學方法與理論的日益成熟,科學計算已成為第三種科學研究的方法和手段。數值計算方法是研究怎樣利用計算工具來求出數學問題的數值解,并對算法的收斂性、穩定性和誤差進行分析、計算的全過程。
數值計算方法,簡稱計算方法,又稱“數值分析”。是在計算機上使用的解數學問題的方法,數值分析的目的是設計及分析一些計算的方式,可針對一些問題得到近似但夠精確的結果,為各種數學問題的數值解答研究提供最有效的算法。數值計算方法是微分方程,常微分方程,線性方程組的求解,主要內容為函數逼近論,數值微分,數值積分,求解線性方程組, 計算矩陣特征值和特征向量,常微分方程數值解,誤差分析等,常用方法有迭代法、差分法、插值法、有限元素法等,計算對象是微積分,線性代數,常微分方程中的數學問題。
在使用計算方法解決實際問題的過程中,往往需要把連續型離散化處理,同時離散形式的解可以近似原來的連續模型的解。例如:求一個函數的積分是一個連續模型的問題,也就是求一曲線以下的面積,若將其離散化變成數值積分,就變成將上述面積用許多較簡單的形狀(如矩形、梯形、拋物線)近似,因此只要求出這些形狀的面積然后累加即可。離散化是程序設計中一個很常用的技巧,它可以有效的降低時間復雜度。在學習數值積分時,Trapezium rule、Mid-point rule、Simpson’s rule、Gauss quadrature等方法都體現了離散化的思想,降低了解決實際問題過程中的難度。
計算方法和計算機的結合
利用計算機解決科學計算問題的全過程為:實際問題??? 構造數學模型??? 設計數值計算方法???? 程序設計??? 上機求出結果???? 回到實際問題。由流程圖可以發現計算數學中的數值計算方法是解決“計算”問題的橋梁和工具,計算機與計算方法緊密聯系,相輔相成,互相影響。因此在數值分析過程中,我們需要:面向計算機,要根據計算機特點提供實際可行的算法,即算法只能由計算機可執行的加減乘除四則運算和各種邏輯運算組成.
計算能力是計算工具和計算方法的效率的乘積,計算方法是研究用計算機求解數學問題的數值計算方法及其軟件實現,提高計算方法的效率與提高計算機硬件的效率同樣重要。計算方法與計算機發展緊密相關,現代計算數學是計算科學的核心,是各類計算性學科(計算力學、計算物理、計算化學等)的共同基礎。自從計算機誕生以來,經典計算方法經歷的一個重新評價、篩選、改造和創新過程,許多能充分發揮計算機潛力,有更大解題能力的新方法和新概念不斷涌現,構成了現代意義下的計算方法。可見計算方法與計算機互相影響、共同發展
計算方法在實際應用中的重要性
? 航天航空、地質勘探、汽車制造、橋梁設計、天氣預報和漢字字樣設計中都有計算方法的蹤影。并且在社會生活的各個領域中,如預產期、標準體重、養老金、個人所得稅等的計算都用到了計算方法。
以下是一些會利用數值分析處理的問題:數值天氣預報中會用到許多先進的數值分析法。計算太空船的軌跡需要求出常微分方程的數值解。汽車公司會利用電腦模擬汽車撞擊來提升汽車受到撞擊時的安全性。電腦的模擬會需要求出偏微分方程的數值解。對沖基金會利用各種數值分析的工具來計算股票的市值及其變異程度。航空公司會利用復雜的最佳化算法決定票價、飛機、人員分配及用油量。此領域也稱為作業研究。保險公司會利用數值軟件進行精算分析。
方程求根
1、實際引用
???? 方程的應用無處不在,飛機為什么能夠飛上天?用到了伯努利方程;生產關系中的動態平衡方程;行程的價格路程估算問題;工程的比例模型計算;會計中的利潤率的計算等都用到了方程,都需要方程求解。掌握基本的方程求根的方法是很必要的,方程求根的方法包括:二分法、迭代法、牛頓法。
2、主要內容
(1)、二分法
算法描述
對方程 在[a,b]內求根。
將所給區間二分,在分點 判斷是否 ;若是,則有根 。
否則,繼續判斷是否 ,若是,則令 ,否則令 。
否則令 。重復此過程直至求出方程 在[a,b]中的近似根為止。
代碼實現
#define zero 0.0001
double f(double x)
{return 2*sin(PI*x) + cos(PI*x);}
int main()
{?? double a,b;
??? double x1,x2,x3;
??? printf("二分法的實現\n");
??? printf("例子式:2*sin(π*x)+cos(π*x)=0\n");
??? printf("請輸入根所在區間【】:");
??? scanf("%lf %lf",&a,&b);
??? printf("下界\t\t上界\t\t中間值\n");
??? x1=a;
??? x2=b;
??? x3 = (x1+x2)/2;
??? while(fabs(x2-x1)>=zero){
??????? printf("%lf\t%lf\t%lf\n",x1,x2,x3);
??????? if(f(x1)*f(x3)>0 )x1=x3;//x2=x2|| f(x1)*f(b)<0
??????? else if(f(x1)*f(x3)<0)x2=x3;//|| f(x1)*f(a)<0
??????? else printf("\t\t%.6lf\n",x1);
??????? x3 = (x1+x2)/2;}
??? printf("結果:%.6lf\n",x3);
return 0;}
運行結果
開始界面顯示為:
?
這是需要輸入一個區間范圍,然后在這個范圍內查找方程的根,假如輸入1~2的范圍,程序運行后的界面為:
?
?
(2)、迭代法
算法描述
將方程 等價變換為 形式,并建立相應的迭代公式 。遞推迭代式 ,當k趨于無窮大時,xk的極限存在,且 (xk)連續。
代碼實現
#include<stdio.h>
#include<math.h>
#define zero 1e-5
double f(double x)
{
??? return exp(-x);
}
int main()
{
??? double x1,x2;
??? printf("迭代法的實現\n");
??? printf("例式:x = e(-x)\n");
??? printf("請輸x0的值:");
??? scanf("%lf",&x1);
??? x2=100;
??? while(fabs(x1-x2)>=zero)
??? {
??????????????????????????? x2=x1;
??????? printf("%.7lf\n",x1);
??????? x1 = f(x1);
??? }
??? return 0;
}
運行結果
該程序所求方程為:e-x-x=0,可轉化為x=e-x,并在x0處進行迭代
?
假設輸入x0=1,則在x=1處進行迭代求x1,以此可求出x2,x3,x4···,當|xk+1-xk|<=0.00001時迭代結束,輸出結果為:
?
最后求得方程的解為0.5671477
(3)、牛頓法
算法描述
用牛頓迭代法求f(x)=0在x0附近的一個實根的方法是:
(1) 選一個接近于x的真實根的近似根x1;
(2) 通過x1求出f(x1)。在幾何上就是作x=x1,交f(x)于f(x1);
(3) 過f(x1)作 f(x)的切線,交x軸于x2。可以用公式求出x2。由于f'(x1)=f(x1)/(x2-x1),故x2=x1-f(x1)/f'(x1)
(4) 通過x2求出f(x2);
(5) 再過f(x2)作f(x)的切線交x軸于x2;
(6) 再通過x3求出f(x3),…一直求下去,直到接近真正的根。當兩次求出的根之差|xn+1-xn|≤ε就認為 xn+1足夠接近于真實根。
牛頓迭代公式是:xn+1=xn-f(xn)/f'(xn)
代碼實現
#define zero 1e-5
double f(double x)
{
??? return x-(x-exp(-x))/(1+x);
}
int main()
{
??? double a;
??? double x1,x2;
??? printf("牛頓法的實現\n");
??? printf("例式:x = e(-x)\n");
??? printf("請輸入x0的值:");
??? scanf("%lf",&a);
??? x2=a*2;
??? x1=a;
????????????? printf("%.7lf\n",x1);
??? while(fabs(x1-x2)>=zero)
??? {??
??????????????????????????? x2=x1;
??????? x1= f(x1);??????????????
??????? printf("%.7lf\n",x1);
??? }
??? return 0;
}
運行結果
初始界面顯示為:
?
該程序所求方程為:e-x-x=0,可轉化為x=e-x,在x0處開始迭代。
假設x0輸入為1,則顯示結果為:
?
3、算法比較
| 方法 | 優點 | 缺點 |
| 二分法 | 應用廣泛,可常用于求精度不高的近似根 | 循環次數較多,計算量大 |
| 迭代法 | 計算量較小,誤差小 | 可能不收斂 |
| 牛頓法 | 計算量最少,誤差小 | 對重根收斂較慢,要求函數的一階導數存在,可能不收斂 |
?
從以上的比較可以看出一下幾點結論:
1、? 二分法和迭代法、牛頓法均能解出方程的根。
2、? 一般地看來,牛頓迭代法的效率較普通迭代法的要高,兩點加速迭代法能加速一般迭代法。
3、? 迭代法和牛頓法對初值是敏感的,若初值選擇的不合適可能導致迭代的效率很低,甚至是發散的。例如,對于函數 形成的迭代,當選取初值 時,因為 是沒有意義的,這樣就導致了迭代的停止或發散。
4、小組討論及分工情況
在第一次的小組討論中,基本上每個組員都能認真的聽取其他組員對程序的講解,并在不懂的地方主動提出疑問使自己對程序的理解更深刻,覺得有些多余或者不夠完善的地方提出改進的建議來幫助同學提高對算法的更多認識。在討論過程中,每位組員都或多或少的有些收獲。
在討論之后的完成報告過程中,小組內有明確、合理的分工,讓在報告某個不擅長的地方的同學和一個比較擅長的同學合作完成分配的任務,并爭取每一位同學參與。最終報告的完成情況是:以肖大軍的程序為基礎,吸收了韓學武計算誤差的方法,和陳俊樺、劉宇同學提出的計算收斂度的思想。在向勝男、方正等同學提出要將三個算法放在一起更好的比較幾個算法的效率。最后由彭亞瓊、楊耀鵬、張鐘文、梅旭三位同學負責修改程序,王艷琴和肖大軍制作展示PPT,韓學武寫word文檔。
方程組求解
1、實際應用
在我們的實際生活和生成當中會出現大量的方程組,在這些方程組需要求解,如果是要用人工的去求解的時候無疑是一個龐大的工作,而且很能避免錯誤的出現,這樣會浪費大量的人力物力和時間。于是我們今天在前輩們關于方程組的求解總結出來的高斯消去法和直接三角分解法(LU分解)的基礎之上借助編程過程中的循環來讓計算機對方程組經行求解。這樣可以節省大量的時間同時避免了錯誤的出現。下面將是我們本著這個目的去實現高斯消去法和直接三角分解法(LU分解)的過程。雖然有很多的難題還沒有解決,但是這是我們小組共同努力的成果。
2、主要內容
1、高斯列主元消去法求解方程組
(1)、算法描述
Gauss消去法的基本思想是一次用前面的方程消去后面的未知數,從而將方程組化為等價形式:
?
這個過程就是消元,然后再回代就好了。具體過程如下:
對于 ,若 依次計算
?
然后將其回代得到:
?
以上是高斯消去法。
但是高斯消去法在消元的過程中有可能會出現 的情況,這時消元就無法進行了,即使主元數 但是很小時,其做除數,也會導致其他元素數量級的嚴重增長和舍入誤差的擴散。因此,為了減少誤差,每次消元選取系數矩陣的某列中絕對值最大的元素作為主元素。然后換行使之變到主元位置上,再進行銷元計算。即高斯列主元消去法。
?
(2)、代碼實現
#include<stdio.h>
#include<string.h>
#include<math.h>
#define e 0.00000001
const int M=1000;
const int N=1000;
double a[N][M];
double b[M];
double pt(int n,int m)//矩陣的輸出
{
??? for(int i=0;i<n;i++)
??? {
??????? for(int j=0;j<m;j++)
??????? printf("%lf? ",a[i][j]);
??????? printf("\n");
??? }
}
int jihuan(double a[N][M],int n,int m,int i)
{
??? int mi=i;//最大行首
??? //printf("%lf\n",a[mi][mi]);
??? int x;
??? for(int j=i+1;j<n;j++)
??????? if(fabs(a[j][i])>fabs(a[mi][i]))mi=j;//列不動
??????? //printf("##%d\n",mi);
??? //printf("%.6f\n",a[mi][i]);
??? if(mi!=i)
??? for(int j=0;j<m;j++)//換行
??? {
??????? x=a[mi][j];
??????? a[mi][j]=a[i][j];
??????? a[i][j]=x;
??? }
??? //printf("##\n");
??? //pt(n,m);
??? //printf("##\n");
??? return 0;
}
int main()
{
??? int n,m,zhi;
??? double t;
??? printf("請輸入增廣矩陣N,M\n");
??? while(scanf("%d %d",&n,&m)!=EOF)
??? {
??????? for(int i=0;i<n;i++)
??????? for(int j=0;j<m;j++)
??????? scanf("%lf",&a[i][j]);
??????? //pt(n,m);
??????? for(int i=0;i<n-1;i++)
??? {
??????? jihuan(a,n,m,i);//找到不為0的因子,交換行首最大
??????? for(int j=i+1;j<n;j++)
?????? {
?
????????? if(fabs(a[j][i])>e)
????????? {
????????????? t=a[j][i]/a[i][i];//對a[i][i]處理
????????????? for(int k=i;k<m;k++)
????????????? {
????????????????? a[j][k]=a[j][k]-a[i][k]*t;
?
?????????????? }
?????????? }
??????? }
??????? pt(n,m);printf("\n");
??? }
??????? int j;
??????? for(j=0;j<m;j++)
??????????? if(fabs(a[n-1][j])>e)break;//判斷最后行是否全為0
???????? //printf("%lf %lf",a[n-1][m-2],a[n-1][m-1]);
??????? if(fabs(a[n-1][m-2])<e&&fabs(a[n-1][m-1])>e){printf("方程無解\n");continue;}
??????? //printf("%d %d",j,m);
??????? if(j==m)
??????? {
??????????? for(int i=n-1;i>-1;i--)//其他行
??????????? if(fabs(a[i][m-2])<e)n--;
??????? }
??????? if(n<m-1)//判斷矩陣的秩
??????? {
?????????? printf("方程有無窮多解\n");
?????????? printf("化簡后的矩陣為:\n");
?????????? pt(n,m);
?????????? printf("請輸入拓展矩陣N,M\n");
?????????? continue;
??????? }
??????? else if(n>m-1)
??????? {
??????????? printf("方程無解\n");
??????????? printf("化簡后的矩陣為:\n");
??????????? pt(n,m);
??????????? printf("請輸入拓展矩陣N,M\n");
??????????? continue;
??????? }
???????? for(int i=n-1;i>0;i--)
???????? for(int j=i-1;j>-1;j--)
??????? {
??????????? t=a[j][i]/a[i][i];
??????????? //printf("%.2f\n",t);
??????????? a[j][i]=a[j][i]-a[i][i]*t;//對a[i][i]處理
??????????? a[j][m-1]-=a[i][m-1]*t;
???????? }
???????? pt(n,m);
???????? printf("\n");
???????? printf("方程的解為:");
???????? for(int i=0;i<n;i++)
???????? printf("%.3lf ",a[i][m-1]/a[i][i]);
??????? printf("\n請輸入拓展矩陣N,M\n");
???? }
??? return 0;
}
(3)、運行結果
測試數據1:3 4
1 2 3 6
2 2 3 7
1 4 4 9
答案:1 1 1
?
測試數據2:3 4
0 0 1 3
3 0 0 2
0 2 0 1
答案:0.667?? 0.5?? 3
?
2、直接三角分解法(LU分解)求解方程組
(1)、算法描述
先將矩陣A直接分解為 則求解方程組的問題就等價于求解兩個三角形方程組。
直接利用矩陣乘法,得到矩陣的三角分解計算公式為:
?
由上面的式子得到矩陣A的LU分解后,求解Ux=y的計算公式為
?
以上為LU分解法。
?
(2)、代碼實現
#include<iostream>
#include<string.h>
using namespace std;
double m[20][20],lu[20][20];//系數,LU
double root[20],x[20],y[20];
int n;
void LU()//化解
{
??? int i,j,k,t;
??? double num;
??? memset(lu,0,sizeof(lu));
??? for(i=0;i<n;i++)//U的第一行,L的第一列處理
??? {
??????? lu[0][i]=m[0][i];
??????? if(i>0)
??????? lu[i][0]=m[i][0]/lu[0][0];
??? }
??? for(i=1;i<n;i++)
??? {
??????? for(j=i;j<n;j++)//U的第i行
??????? {
??????????? num=0;
??????????? for(t=0;t<i;t++)
??????????? {
??????????????? //if(i-1==t) {num+=lu[t][j];continue;}
???????????????? num+=lu[i][t]*lu[t][j];
??????????? }
??????????? //if(i==1) cout<<num<<endl;
??????????? lu[i][j]=m[i][j]-num;
?
??????? }
??????? for(j=i+1;j<n;j++)//L的第i列
??????? {
??????????? num=0;
??????????? for(k=0;k<i;k++)
??????????? num+=lu[j][k]*lu[k][i];
??????????? lu[j][i]=(m[j][i]-num)/lu[i][i];
??????? }
??? }
??? cout<<endl;
??? cout<<"分解后的LU矩陣為:"<<endl;
??? for(i=0;i<n;i++)
??? {
??????? for(j=0;j<n;j++)
??????? cout<<lu[i][j]<<" ";
??????? cout<<endl;
??? }
??? cout<<endl;
}
double iteration(int i)
//求方程組中第i個未知數的解(遞推)
{
??? double sum;
????????????? if(i==0)
??????????????????????????? return root[0];
????????????? else
????????????? {
??????????????????????????? double sum=root[i];
??????????????????????????? for(int j=i-1;j>=0;j--)
??????????????????????????? {
????????????????????????????????????????? sum-=lu[i][j]*iteration(j);
????????????????????????????????????????? //cout<<lu[i][j]<<" ";
??????????????????????????? }
??????????????????????????? return sum;
????????????? }
}
double iteration_root(int i)
//求方程組中第i個未知數的解
{
??? double sum;
????????????? if(i==n-1)
??????????????????????????? return y[n-1]/lu[i][i];
????????????? else
????????????? {
??????????????????????????? double sum=y[i];
??????????????????????????? for(int j=i+1;j<n;j++)
??????? {
??????????? sum=(sum-lu[i][j]*iteration_root(j));
??????? }
??????? sum=sum/lu[i][i];
??????????????????????????? return sum;
????????????? }
}
?
int main()
{
??? int i,j,k,t;
??? double s;
??? memset(m,0,sizeof(m));
??? memset(root,0,sizeof(root));
??? memset(x,0,sizeof(x));
??? memset(y,0,sizeof(y));
??? cout<<"請輸入系數矩陣的階數"<<endl;
??? cin>>n;
??? cout<<"請輸入系數矩陣"<<endl;
??? for(i=0;i<n;i++)
??? for(j=0;j<n;j++)
??? cin>>m[i][j];
??? cout<<"請輸入結果數組"<<endl;
??? for(i=0;i<n;i++)
??? cin>>root[i];
??? for(i=0;i<n;i++)//如果系數矩陣對角線上存在為0的元素,則對矩陣進行旋轉
??? {
??????? s=0;
?????? if(m[i][i]==0)
?????? {
?????????? for(j=0;j<n;j++)
??????? {
????????? if(m[j][i]>s)
????????? {
???????????? s=m[j][i];
??????????? ?t=j;
????????? }
??????? }
??????? for(k=0;k<n;k++)
??????? {
?????????? s=m[t][k];
?????????? m[t][k]=m[i][k];
?????????? m[i][k]=s;
??????? }
??????? s=root[t];
??????? root[t]=root[i];
??????? root[i]=s;
?????? }
??? }
???? LU();
??? for(j=0;j<n;j++)
??? {
??????? y[j]=iteration(j);
??????? cout<<"Y"<<j<<"="<<y[j]<<endl;
??? }
??? cout<<endl;
??? for(k=n-1;k>=0;k--)
??? x[k]=iteration_root(k);
??? cout<<"方程解為:"<<endl;
??? for(k=0;k<n;k++)
??? cout<<"X"<<k<<"="<<x[k]<<endl;
??? cout<<endl;
}
?
(3)、運行結果
實例一:
實例二:
、
實例三:
?
?
3、小組討論及分工情況
? ?有了第一次方程求根時做小組匯報的經驗,這次我們小組在進行小組匯報方面做了一些改變,以得到更好的效果。
首先,鑒于組內各成員的編程能力各不相同,有的同學基礎較弱,編寫的程序或沒有寫完,或運行起來會有錯誤、所以,我們將小組成員分成兩個同學一個小組, 又編程能力強的同學帶著編程能力稍弱的同學完成程序的編寫,這樣能確保每個同學都能學到一些編程的方法和技巧,也有助于彼此之間的共同提高。
其次,我們這次也做了組員之間任務的交換完成,也就是上一次的分工之后,我們這次決定相互的交換一下工作,然后讓一些編程能力相對比較弱的同學參與到了討論后的代碼修改當中。這次的分工是:由彭亞瓊、劉宇、方正、陳俊樺、韓學武五位同學負責修改程序,王艷琴和向勝男負責細化許多上臺匯報的工作,張鐘文和楊耀鵬寫word文檔,肖大軍和梅旭負責制作PPT。
?
方程積分
1、實際應用
積分在我們日常的生活中有很廣泛地應用,特別是在計算很多復雜的問題的時候,積分顯示出無可替代的作用,為了滿足大量的需求,這樣如何用程序快速的求出積分就成了一個需要解決的問題。我們通過這次的計算方法的學習,建立在積分分割小塊求面積,然后把面積加起來得到積分的近似值的原則上,將分別對trapezium rule、Mid-point rule、Simpson's rule、Gruss Qusdrature、Gruss Qusdrature-three point這五種積分方式經行效率經行比較,從而得到最好的積分方式。
2、主要的算法
1.???? 梯形(trapezia)公式
1、算法描述
如果用一個梯形來近似代替每個子區間的面積,梯形的四個頂點分別位于 , , 與 。梯形的面積為
????????????????????????????????
對于整個[a,b]區間,積分值由所有窄帶的和給出
?
?
y
?
?
???????????????????????????????? F(x)
???????????????????? h
???????????????????????????????????????????????????????????????????????????????????????????
??????????????????????????????????????????? (上底+下底)*h/2=梯形面積
?
?
????????????? a????? xi xi+1 b??????????????????????? x
2、代碼實現
#define Pi 3.1415926535897931
int Trapezium(double x1,double x2)//梯形法
{
??? int i,j;
??? double s=0;//記和
??? double x;
??? double error1,error2=1;
??? double Error_Ratio;//收斂性
??? int intervals[20]= {1,2,4,8,16,32,64,128,256,512,1024,
??? 2048,4096,8192,16384,32768,65536,131072,262144,524288};//細分
??? s=s+function(x1)+function(x2);
??? cout<<setiosflags(ios::left)<<setw(6)<<"No."<<"???????????? "<<
??? setw(7)<<"No.f(x)"<<"?????? "<<setw(15)<<"Trapezium Rule"
??? <<"???????? "<<setw(10)<<"Error Ratio"<<endl;
??? for(i=0; i<20; i++)
??? {
??????? s=function(x1)+function(x2);
??????? x=fabs(x2-x1)/intervals[i];
??????? if(x1<x2)
??????? {
??????????? for(j=0; j<intervals[i]-1; j++)
??????????????? s+=2*function(x1+(j+1)*x);
??????? }
??????? else
??????? {
??????????? for(j=0; j<intervals[i]-1; j++)
??????????????? s+=2*function(x2+(j+1)*x);
??????? }
??????? s=x*s/2;
??????? error1=s-2;
??????? Error_Ratio=error1/error2;
??????? error2=error1;
??????? if(i!=0)
? ??????{
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<setw(10)<<Error_Ratio<<endl;
??????? }
??????? else
??????? {
?????????? ?cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<endl;
??????? }
??? }
??? return 0;
}
?
3、運行結果
2.???? 中值發公式
1、算法描述
如果用一個矩形來近似代替每個子區間的面積,矩形的高應該用其中點,一間距為寬可以計算出矩形面積
然后同理梯形的計算方法可以得出積分。
2、代碼實現
#define Pi 3.1415926535897931
//中值法
int Mid_Point(double x1,double x2)
{
??? int i,j;
??? double s=0,x;
??? double error1,error2=1;
??? double Error_Ratio;
??? int intervals[20]= {1,2,4,8,16,32,64,128,256,512,1024,
??? 2048,4096,8192,16384,32768,65536,131072,262144,524288};
??? cout<<setiosflags(ios::left)<<setw(6)<<"No."<<"???????????? "
??? <<setw(7)<<"No.f(x)"<<"?????? "<<setw(15)<<"Midpoint Rule"
??? <<"???????? "<<setw(10)<<"Error Ratio"<<endl;
??? for(i=0; i<20; i++)
??? {
??????? s=0;
??????? x=fabs(x2-x1)/intervals[i];
??????? if(x1<x2)
??????? {
??????????? for(j=0; j<intervals[i]; j++)
??????????????? s+=function(x1+(j+0.5)*x);
??????? }
??????? else
??????? {
??????????? for(j=0; j<intervals[i]; j++)
??? ????????????s+=function(x2+(j+0.5)*x);
??????? }
??????? s=x*s;
??????? error1=s-2;
??????? Error_Ratio=error1/error2;
??????? error2=error1;
??????? if(i!=0)
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"??????? ?????"<<setw(7)<<intervals[i]<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<setw(10)<<Error_Ratio<<endl;
??????? }
??????? else
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<endl;
??????? }
??? }
??? returen 0;
}
3、運行結果
?
3. Simpson公式
?? 1、算法描述
?當積分的上下限相對于展開的中心點對稱時,積分泰勒展開式中含有f(x)的奇數階導數的項都將等于零。利用這一性質,我們可以在相鄰的兩個子區間內對面積作泰勒級數展開,可得
?
積分的精確度可以達到1。利用中心差分,可將f(x)的二階導數近似表為
?
將此結果代入前述中心查分表式,則子區間[xi-1,xi+1]內的積分近似為
?
對于整個[a,b]區間,結果為
?
?
?
假設區間的數目N為偶數,則奇數格點的貢獻是偶數格點貢獻的2倍。這種權重上的差異來自我們為修正基本方法所得的一級結果所引入的f(x)二階導數的貢獻。而兩端點 和 的權重則僅為偶數點的一半。Simpson法則的另一優點在于其自然引出了一種算法,即通過迭代使積分達到所需要的精確度。
誤差估計---原則上,我們可以通過估計所省略的高階項大小得出數值計算中的誤差。其前提是知道高階導數,這樣做并不容易。比較相繼的兩次迭代結果是較為簡便的一種方法。例如,如果兩次計算值I[a,b]之差小于預設的允許值 ,則我們認為計算已經達到了所需的精確度。對于Simpson法則,該算法可通過如下方法實施。假設我們在x=a和x=b之間對函數f(x)進行積分,且要求達到精確度 。各個節點上的函數值對積分的貢獻可分為三個部分,即端點區,奇數點與偶數點的貢獻,
?
?
進行迭代計算,應從N= 開始,其中 應為某個較小而合理的區間數目,例如取 =6。這是迭代計算的第一步。在下一輪迭代中,將區間的數目翻倍,而令步長h減半,即令N= =2 。以這種方式改變子區間數目的好處在于,對于一個新的N,來自兩個端點的貢獻(存儲為 )是不變的,而偶數點與上一次迭代計算過的偶數點完全相同。也就是說,在新的迭代中的 的值就是上一次循環的 與 之和。所需計算的僅僅是函數在(新的)奇數點上的值。從而我們得到結果
?
其中h=(b-a)/N2。利用上面等式進行變步長的循環計算即。如果計算值與前一循環所得結果之差小于ε,則可認為計算結果已收斂;否則即再次令子區間數目加倍,使N=N3=2N2。然后依此類推,直到計算結果收斂或者達到最大迭代次數
?
2、代碼實現
?
#define Pi 3.1415926535897931
int Simpson(double x1,double x2)
{
??? int i,j;
??? double s=0,x;
??? double error1,error2=1;
??? double Error_Ratio;
??? int intervals[20]= {1,2,4,8,16,32,64,128,256,512};
??? cout<<setiosflags(ios::left)<<setw(6)<<"No."<<"???????????? "
??? <<setw(7)<<"No.f(x)"<<"?????? "<<setw(15)<<"Simpson Rule"
??? <<"???????? "<<setw(10)<<"Error Ratio"<<endl;
??? for(i=0; i<10; i++)
??? {
??????? s=0;
??????? //n個區間 分為2n等份
??????? x=fabs(x2-x1)/(2*intervals[i]);
??????? s=s+function(x1)+function(x2);
??????? if(x1<x2)
??????? {
??????????? for(j=1; j<2*intervals[i]; j++)
??????????? {
??????????????? if(j%2==0)
??????????????? {
??????????????????? s+=2*function(x1+j*x);
??????????????? }
?????????????? ?else
??????????????? {
??????????????????? s+=4*function(x1+j*x);
??????????????? }
??????????? }
??????? }
??????? else
??????? {
??????????? for(j=1; j<2*intervals[i]; j++)
??????????? {
??????????????? if(j%2==0)
??????????????? {
??????????????????? s+=2*function(x2+j*x);
??????????????? }
??????????????? else
??????????????? {
??????????????????? s+=4*function(x2+j*x);
??????????????? }
??????????? }
??????? }
??????? s=s*x/3;
??????? error1=s-2;
??????? Error_Ratio=error1/error2;
??????? error2=error1;
??????? if(i!=0)
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]*2+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<setw(10)<<Error_Ratio<<endl;
??????? }
??????? else
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]*2+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<endl;
??????? }
??? }
??? return 0;
?
?
3、運行結果
4. Gruss Qusdrature及Gruss Qusdrature-three point公式
1、算法原理
在高斯求積公式(1-1)中,若取權函數p(x)=1,積分區間[-1,1]得
稱之為高斯-勒讓德求積公式.
對任意求積區間[a,b],通過變換
?
可化為區間[-1,1],這時
?
取a=-1,b=1,則得公式
(2-3)
求積公式的高斯點就是勒讓德多項式的零點.
利用勒讓德多項式的一個性質
(2-3)
按(2-2)式,可推得余項為
?
若取
?
的零點x0=0為節點,從而一點高斯-勒讓德求積公式(中矩形求積公式)為
?
其余項為
?
若取
?
的兩個零點 為節點,則
?
從而二點高斯-勒讓德求積公式為
?
其余項
?
同理,三點高斯-勒讓德求積公式為
?
其余項
?
一般地,高斯-勒讓德求積公式的節點可以通過勒讓德多項式的零點確定,而系數通過(2-3)式確定.
2、代碼實現
int Simpson(double x1,double x2)
{
??? int i,j;
??? double s=0,x;
??? double error1,error2=1;
??? double Error_Ratio;
??? int intervals[20]= {1,2,4,8,16,32,64,128,256,512};
??? cout<<setiosflags(ios::left)<<setw(6)<<"No."<<"???????????? "
??? <<setw(7)<<"No.f(x)"<<"?????? "<<setw(15)<<"Simpson Rule"
?? ?<<"???????? "<<setw(10)<<"Error Ratio"<<endl;
??? for(i=0; i<10; i++)
??? {
??????? s=0;
??????? //n個區間 分為2n等份
??????? x=fabs(x2-x1)/(2*intervals[i]);
??????? s=s+function(x1)+function(x2);
??????? if(x1<x2)
??????? {
??????????? for(j=1; j<2*intervals[i]; j++)
??????????? {
??????????????? if(j%2==0)
??????????????? {
??????????????????? s+=2*function(x1+j*x);
??????????????? }
??????????????? else
??????????????? {
??????????????????? s+=4*function(x1+j*x);
??????????????? }
??????????? }
??????? }
???? ???else
??????? {
??????????? for(j=1; j<2*intervals[i]; j++)
??????????? {
??????????????? if(j%2==0)
??????????????? {
??????????????????? s+=2*function(x2+j*x);
??????????????? }
??????????????? else
??????????????? {
??????????????????? s+=4*function(x2+j*x);
??????????????? }
??????????? }
??????? }
??????? s=s*x/3;
??????? error1=s-2;
??????? Error_Ratio=error1/error2;
??????? error2=error1;
??????? if(i!=0)
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???? ????????"<<setw(7)<<intervals[i]*2+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<setw(10)<<Error_Ratio<<endl;
??????? }
??????? else
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]*2+1<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<endl;
??????? }
??? }
??? return 0;
}
Gauss_three.h
int Gauss_three(double x1,double x2)
{
??? int i,j;
??? double s=0,x;
??? double error1,error2=1;
??? double Error_Ratio;
??? int intervals[9]= {1,2,4,8,16,32,64,128,256};
??? cout<<setiosflags(ios::left)<<setw(6)<<"No."<<"???????????? "
??? <<setw(7)<<"No.f(x)"<<"?????? "<<setw(15)<<"Midpoint Rule"
??? <<"???????? "<<setw(10)<<"Error Ratio"<<endl;
??? for(i=0; i<9; i++)
??? {
??????? s=0;
??????? x=fabs(x1-x2)/intervals[i];
??????? x=x/2;
??????? for(j=0; j<intervals[i]; j++)
??????????? s=s+x/9*(8*function(2*j*x+x)+5*function(2*j*x+x-sqrt(0.6)*x)
???????????????????? +5*function(2*j*x+x+sqrt(0.6)*x));
??????? error1=s-2;
?? ?????Error_Ratio=error1/error2;
??????? error2=error1;
??????? if(i!=0)
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]*3<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<setw(10)<<Error_Ratio<<endl;
??????? }
??????? else
??????? {
??????????? cout<<setiosflags(ios::left)<<setw(6)<<intervals[i]
??????????? <<"???????????? "<<setw(7)<<intervals[i]*3<<"?????? "
??????????? <<setw(15)<<error1<<"???????? "<<endl;
??????? }
? ??}
??? return 0;
}
3、運行情況
Gruss Qusdrature
GrussQusdrature-threepoint
?
?
3、? 算法效率的比較
?
?
?
| ???????? 計分方法 | ???????? 運行效率 |
| trapezium rule | ??????? O(2) |
| Mid-point rule | ??????????? O(3) |
| Simpson's rule | ??????? O(2) |
| Gruss Qusdrature | ??????? O(4) |
| GrussQusdrature-three point | ??????? O(5) |
?
4、 當時小組討論情況
在第三次的報告中,大家實行兩人一組,相互的交流,然后在討論的時候相互的展示程序。大家百花齊放。之后我們對匯報經行討論。我們組提出了也盡量做到時間和空間精確讀的最優化,大家在課下不僅僅是對課本上的思想在程序經行了實現,而且在實現之后大家相互的交流之后,對算法的時間空間上面進行了優化,在這其中大家試著去做到如何精確,做了許多超出課本上要就的測試,得出為什么越大誤差會很大,并且探求出是函數的原因。大家除了課本從算法的優化和對積分的認識上面有了很大的提高。大家積極的參與到后期的報告活動中,很好的完成了后期的匯報工作。
?
?
方程微分
1、實際應用
?? 科學技術中常常要求解常微分方程的定解問題。這里我們著重考察的一階方程的初值問題
? ??????????????????????????? ?????????????????
我們知道,只要函數 適當光滑,譬如關于 滿足Lipschitz條件
?????????????? 。???? ?????????????????(1.3)
理論上就可以保證初值問題(1.1),(1.2)的解 存在并且唯一。實際生產與科研中,除少數簡單情況能獲得初值問題的初等解外,絕大多數情況下是求不出初等解的。
實用的方法實在計算機上進行數值求解,就是尋求 在一系列離散節點
?
上的近似值 。相鄰兩個結點的間距 稱為步長。如果不特別說明,我們總是假定 為定數,這時節點為?????? 。
初值問題(1.1),(1.2)的數值解法有個基本特點,它們都采用取“步進式”,即求解過程順著節點的次序一步一步地向前推進,所以只要給出用已知信息 計算 的遞推公式。
首先,要對方程(1.1)離散化,建立求數值解的遞推公式。一類是計算 時只用到前一點的值 ,稱為單步法。另一類是用到 前面 點的值 ,稱為步法。其次,要研究公式的局部截斷誤差和階,數值解 與精確解 的誤差估計及收斂性,還有遞推公式的計算穩定性等問題。
??? 這里我們用了三種數值方法來求解常微分方程組,它們分別是歐拉法、后退歐拉法、Crank-Nicholson方法。
?
2.主要內容
(1)Euler method
A.算法描述
? 在 平面上,我們把微分方程(1.1)的解 稱作它的積分曲線。積分曲線上一點 的切線斜率等于函數 的值,如果按函數 在 平面上建立一個方向場,那么,積分曲線上每一點的切線方向均與方向場在該點的方向相一致。
基于上述幾何解釋,我們從初始點 出發,先依方向場在該點的方向推進到 上一點 ,然后再從 依方向場的方向推進到 上一點 ,循此前進推出一條折線 (圖9.1)。
一般地,設已做出該折線的頂點 ,過 依方向場的方向再推進到 ,顯然兩個頂點 , 的坐標有關系
?
即
???????????????????????? ?????????????????????(2.1)
這就是著名的歐拉(Euler)公式。若初值 已知,則依公式(2.1)可逐步算出
????????????????????????
? ?B.代碼實現
????????? 測試例子: ???????
????????? 易解得其原函數是
?初始化:t=0.0,y=1.0,dx=0.1;
?
主要通過迭代來完成
?? for(i=1; i<=10; i++)
??? {
??????? t=(i-1)*dx;
??????? y=y+dx*fun(t,y);
??????? Y=funr(t);
??????? Error[i]=Y-y;
??????? if(i==1) printf("%d\t??????? %.10f\t??? %.10f\t??? \n",i,y,Error[i]);
?????? ?if(i>1) printf("%d\t??????? %.10f\t??? %.10f\t%.10f \n",i,y,Error[i],Error[i]/Error[i-1]);
}
C.運行結果
???? 運行環境:VC++6.0
?
?
(2)Backward Euler
A.算法描述
假設 ,即頂點 落在積分曲線 上,那么,按歐拉方法做出的折線 便是 過點 的切線,從圖形上看,這樣定出的頂點 明顯地偏離了原來的積分曲線,可見歐拉方法是相當粗糙的。
為了分析計算公式的精度,通常可用泰勒展開將 在 處展開,則有
???? ?????(2.2)
在 的前提下, ,于是可得到歐拉法(2.1)的公式誤差
?????????????? ?????????????????(2.3)
稱為此方法的局部截斷誤差。
如果對方程(1.1)從 到 積分,得
. (2.4)
右端積分用左矩形公式 近似,再以 代替 , 代替 也得到(2.1),局部截斷誤差也是(2.3).
如果在(2.4)中右端積分用右矩形公式 近似,則得另一個公式
, (2.5)
稱為后退的歐拉法.
B.代碼實現
for(i=1; i<=10; i++)
??? {
??????? t=i*dx;
??????? y=y+dx*fun(t,y);
??????? Y=funr(t);
??????? Error[i]=Y-y;
??????? if(i==1)? printf("%d\t??????? %.10f\t??? %.10f\t??? \n",i,y,Error[i]);
? ??????if(i>1) printf("%d\t??????? %.10f\t??? %.10f\t%.10f \n",i,y,Error[i],Error[i]/Error[i-1]);
??? ?}
C.運行結果
???? 運行環境:VC++6.0
?
(3)Crank-Nicholson
???? A.算法描述
??? 為得到比歐拉法精度高的計算公式,在等式(1.4)右端積分中若用梯形求積公式近似,并用 代替 , 代替 ,則得
??????????????? ????????? (2.7)
稱為梯形方法.
梯形方法是隱式單步法,可用迭代法求解.同后退的歐拉方法一樣,仍用歐拉方法提供迭代初值,則梯形法的迭代公式為
(2.8)
為了分析迭代過程的收斂性,將(2.7)式與(2.8)相減,得
?
于是有
,
式中 為 對 滿足Lipschitz常數,如果選取 充分小,使得
,
則當 時有 ,這說明迭代過程(2.8)是收斂的.
B.代碼實現
? for(i=1; i<=10; i++)
??? {
??????? t=i*dx;
??????? tem=y;
??????? y=y+dx*fun(t,y);
??????? y=tem+(dx*fun(t,y)+dx*fun((i-1)*dx,tem))/2.0;
??????? Y=funr(t);
??????? Error[i]=Y-y;
??????? if(i==1)?? printf("%d\t??????? %.10f\t??? %.10f\t??? \n",i,y,Error[i]);
??????? if(i>1) printf("%d\t??????? %.10f\t??? %.10f\t%.10f \n",i,y,Error[i],Error[i]/Error[i-1]);
}
?
C.運行結果
?
這里,我們還有介紹一種改進的歐拉方法:
顯示歐拉公式計算工作量小,但精度低。Crank-Nicholson方法雖提高了精度,但為隱式公式,需用迭代法求解,計算工作量大。綜合兩者便可改進Euler公式。 先用Euler公式求出一個初步的近似值 ,稱為預測值,它的精度不高,再用Crank-Nicholson公式對它校正一次,即迭代一次,求得 ,稱為校正值。即得到改進的Euler公式:
?
可以證明該公式的精度是二階,這是一種顯示方式
相應具體代碼如下:
??? for(i=1; i<=10; i++)
??? {
??????? t1=(i-1)*dx;
??????? t2=i*dx;
??????? tem=y+dx*fun(t1,y);
??????? y=y+(dx*fun(t1,y)+dx*fun(t2,tem))/2.0;
??????? Y=funr(t2);
??????? Error[i]=Y-y;
??????? if(i==1)???? printf("%d\t??????? %.10f\t??? %.10f\t??? \n",i,y,Error[i]);
??????? if(i>1) printf("%d\t??????? %.10f\t??? %.10f\t%.10f \n",i,y,Error[i],Error[i]/Error[i-1]);
?}
以下是運行結果:
?
可以從運行結果看出,結合改進后的歐拉法后誤差相對變小,精確度和穩定性相對高于前面的顯示歐拉法。
?
3、算法效率的比較
各種算法的優劣比較:
| ??????? 方法 | ??????? 優點 | ??????? 缺點 |
| ??? Euler Method | ??????? 簡單 | ?????? 精度低 |
| ? Backward Euler | ????? 穩定性好 | ? 精度低,計算量大 |
| ??? Crank-Nicholson | ????? 精度提高 | ?????? 計算量大 |
?
各種算法局部截斷誤差和階數的比較:
?????????????????????????????????????????????????????????????????? (h代表步長)
| ??????? 方法 | ?????? 截斷誤差 | ?????? 階數 |
| ??? Euler Method | ???? ? | ?????? 一階 |
| ? Backward Euler | ??? | ?????? 一階 |
| ??? Crank-Nicholson | ???? ? | ?????? 二階 |
?
經探討,我們得出提高計算精度的方法
①增加展開項數。
? 增加 函數的泰勒展開式的階數,即逐次取高次項,這樣就可以減少截斷誤差。其誤差系列為
②縮小步長
? 由于差分間隔減小,即h值變得很小,可使計算精度提高。在理論上步長值越小越好,而且趨近于0最好。但是,dx越小會使計算次數增加,浪費計算時間,而且還會使舍入誤差增大。
?
4、小組內討論情況
???? ①大家對算法經行了細致的研究
???? 經過上三次的編寫程序之后我們對各自的編程的特點和基本思路有了一個清晰的了解,大家在交流的時候也是明顯的速度加快了許多,同時對微分的認識也是加強了很多。對于這次的編程我們組提出了也盡量做到時間和空間也精確讀的最優化。于是大家在課下不僅僅是對課本上的思想在程序經行了實現,而且大家試著去做到如何精確,做了許多超出課本上要就的測試,得出為什么越大誤算從而更加精確的確定其微分的值。大家除了課本從算法的優化和對積分的認識上面有了很大的提高。
???? ②大家積極的參與到后期的報告活動中
??? 這次中,大家表現出前所未有的熱情,爭先恐后的去做報告PPT等任務,力求做的最好。在即上三次的分工之后,我們這次決定再次相互的交換一下工作。我們最終的程序或許沒有解決我們最初討論出的問題,但是我想大家參與了就是一種最大的收獲。這次的分工是:陳俊樺、韓學武、肖大軍和梅旭由四位同學負責修改程序,王艷琴和向勝男經行程序的測試和算法的描述工作,彭亞瓊、劉宇、方正寫word文檔,肖大軍和梅旭負責制作PPT ,張鐘文和楊耀鵬寫臺上的細化工作。
?
五、結課感言
小組總結
經過一學期的學習,從小組的角度看,小組有了一個不錯的成長。小組阿紫組織大家的學習討論的時候,本著老師要求的基本原則,經行了多次的改革。首先介紹一下組內的成員。我們小組內的成員相對其他組來說沒有編程能力特別出眾的人員,所以我們小組在第一次的實習中經行了一次小小的嘗試,結果很顯然,寫出程序來的人并不多,有的甚至連教材上面講的基本原理都不清楚,所以在第一次討論之后,我們組內經行了一次關于改革的討論,將大家分為兩人一組,這樣可以加強大家之間的交流,同時也能讓大家都參與到其中,第一次的報告其實完成的還是很倉促的。但是第二次的時候就是有了一個新的面貌,兩人一組經行匯報討論,這樣大家就建立在討論之前兩人已經進行了交流,這樣進度經快了很多,完成之后我們現場對一些精度等存在問題的代碼現場經行了更改,這樣讓大家更清楚了在寫程序的時候需要注意什么。然后我們開始對組間匯報有了一個明確的分工。在組間匯報完之后,我們并且對每個組的匯報經行了總結,對第三次的匯報提出要求,希望大家不僅僅以實現算法,盡量的讓代碼從時間空間可讀性等各個方面有一定的建樹。等到第三次實習的時候,大家對原理和代碼都很熟悉,討論很快就結束了,我們這次著重的經行了一下對每個人寫代碼的特點的展示,比如如何考慮和實現時空的最優化,如何讓代碼健壯性更好,有的人更是展示了面向對象的實現方式。大家在相互交流的同時相互的學習,使自己在編程的思想上面有了一定的提高。這次大家很積極的要求去做各個任務。在這個基礎上面我們經行三次匯報結束之后,就各個小組之間存在問題經行了探討。于是在第四次匯報的時候我們不僅僅是對教材上面的微分的內容經行了實現,還對一些大家忽略的內容比如各個類型的精確度問題等經行了探究,讓我們對實現中各個實現過程更加的胸有成竹。
可能我們組做的不是做好的,但是從一定程度上說我們覺得我們已經得到自己想要得到的,不僅僅是在計算方法上面更是在大家對編程的自信心和技巧上面有了一個很大的提高。有句話說的好:我們不和其他人比較,我們每次超越自己一點劇足夠了。的確在這個學期的學習中,我們小組雖然沒有那么輝煌的成就,但是我們對每一個組員都是熱心的幫助,大家一起進步,讓很多以前沒有動手編過程序的人開始意識到編程沒有自己想象的那么難。
在課程即將結束的時候,有組員主動的提出要去完成某些任務,當這次任務已經那排好了的時候,他要求下次讓他來。這和其他組的本著能者多勞的原則大大的不同,在我們組這樣的人不僅僅一個,而是大家一起。雖然有些事情說出來沒什么驕傲的,但是我依然覺得自始至終在老師不點名的情況下,我們組內的成員沒有一個人翹過一節課,更是后來似乎愛上了這種模式。這源自于大家對小組的付出和在小組內的存在感。我想在大學的學習中,本次的小組學習是大家經歷過的醉成功學習之一。
為什么大家積極的去做任務,因為大家對小組愛的深沉。
小組成員感言
組長 韓學武
??? 作為組長在這學期的計算方法學習上面有很大的收獲很大,在四次的實習中,積極的完成每次的程序編寫工作,然后積極和大家討論,并且積極的組織大家經行小組簡單扼匯報準備工作,每次的匯報主要分擔了寫報告的工作。除此之外還積極的對小組的管理和安排經行改革極大的調動大家的積極性。通過此次計算方法的學習,我最大的感受就是團隊精神,俗話說“三人行必有我師”在多次的交流之后,在編程思想,PPT制作,匯報方式等等方面學到了很多。在這種積極活躍的授課方式之下,感覺到對計算方法和程序編寫有了更深的認識。
向勝男
起初,我對老師用英文版教材授課的方式很不習慣。由于英語水平有限,課本上內容基本看不懂,單靠聽老師的講解只能半知半解。后來老師又要求對每章節的知識用程序實現,而且進行討論并作匯報,這讓我開始對這門課程感到些許的茫然。但是,為了真正弄懂各種算法的原理,我課后還是積極查閱資料,嘗試著編寫出正確的程序。有一次程序運行結果不對,自己花了大量時間還是不知道問題出在哪里,后來在小組討論環節經和同學分析將問題解決。雖然那次程序寫得粗糙,但還是很有成就感,并且漸漸對老師的這種授課方式提起興趣來。
四次程序匯報后,這門課也就相應結束了。在這過程中,我感受到了團隊合作的重要性。每次小組匯報,和大家一起交流算法,提出并分析問題,接著準備匯報材料,在有限的時間內大家一起忙碌各自分配的任務,喜歡這樣一個愉快的過程。同時,發現自己的動手實踐能力也提高了,學會如何調試修改程序,完善自己的代碼,以及美化輸出界面等,而且對知識原理了解得更加透徹了。當然,拿起英文教材也沒那么恐懼了,認識了不少單詞呢。如果我們平時沒有這樣的練習,最后知識傳統地筆試考試后就結課是完全達不到這種效果的。
?
肖大軍
?? 誠然的說以前從來沒有老師以這種方式授過課。我能感受的到,我不僅僅學習到了課本上的知識,更提高了團隊合作,有效溝通,當眾演說等其他方面的綜合素質。
首先,上課的教材采用英文版本就讓我們耳目一新,誠然以我個人的英語水平還不能完全理解教材。經過在課堂上老師的重點剖析,能理解計算方法的基本算法思想,并能獨立的編寫每一個程序。英語教材的使用也讓我再次意識到英語水平的不足,以及英語學習的重要性和迫切性。
然后老師采取分組的方式進行交流,的確很契合大多數場合集體交流探討的需要,讓我們意識到團隊的重要性,對今后我們的工作實踐有了較好的啟蒙基礎,在小組內積極討論還鍛煉了我們的團隊協作能力,增進了大家的情感交流,學習了不同同學好的算法思路。
采取小組回報的方式,給我們提供了一個上臺發言的平臺,讓我們嘗試著在更多人面前講話,做PPT展示,克服膽怯的心里,鍛煉了交際能力,靈活的應變能力,對今后的學習工作都有啟蒙意義。
總的來說,在計算方法這門課上,我學到的東西著實很多,在上課時,積極圍繞著老師的講解思考問題,有時老師一些發人肺腑的話,也讓人受益匪淺;課下我積極編程實現算法,提高了動手能力,也進一步的理解了算法的核心思想;在小組內討論時,積極幫同學解決困惑,積極思考同學提出的新的算法思路,這些都讓我受益匪淺;經過全組同學的共同努力,在小組匯報時,我抱著鍛煉自己的心態積極參加小組匯報!
?
彭亞瓊
說起計算方法,先談談計算方法的授課老師-曾老師吧,第一次上曾老師的課,給我的感覺就是老師的態度非常認真,為了讓多數同學能聽懂,很基礎的定理、公式都在黑板上一一推導,還時不時的找同學提問,以確定同學是否真正聽懂。此外,在英語不怎么好的情況下,曾老師堅持用英文教材,目的在于督促大家學習更多的英語,促進英語能力的提高。而我的收獲也是非常大的,首先是英語專業詞匯的學習,在講解每一章內容時,我都會用手機查詢不懂的詞匯,并且掌握;再者就是掌握了一系列解決實際問題的方法,主要學習對象是微分方程,常微分方程,線性方程組,學習了迭代法、二分法、插值法的理論知識,并在計算機上用所學內容實現了對相關問題的求解,掌握了微積分,線性代數,常微分方程中的數學問題,并學習了誤差、收斂度的分析與判斷。此外掌握了一種重要的數學思想-離散化:離散化是程序設計中一個很常用的技巧,它可以有效的降低時間復雜度。在學習數值積分時,Trapezium rule、Mid-point rule、Simpson’s rule、Gauss quadrature等方法都體現了離散化的思想,降低了解決實際問題過程中的難度;最后就是提升了我的團隊合作能力,這也是老師一直強調的東西,要有集體榮辱觀,這樣才能發揮你個人的最大潛質,為小組貢獻自己的力量。并且學習態度也有了改善,在學習一門新的學科時,不能憑自己的喜好決定你的努力程度,你要對自己負責,學東西時一定要持有認真的態度,不能隨心所欲。本門課程學習過程中收獲頗豐,希望自己秉著學習的態度一直走下去。
楊耀鵬
其實一直以來感覺自己在數學方面還是比較感興趣的,但是從學完線性代數和高數后自己也就很少去碰數學方面的書了,直到這個學期的這門計算方法讓我重新又找回了學習數學的感覺。經過這一個學期的學習,總體感覺還行,基本上都能領悟。個別的知識點可能比較抽象,但是好多的算法我們都經過了上機實踐,所以掌握起來會更透徹一點。學習了這門課,感覺實用性比較大。像拉格朗日和牛頓插值法等等算法。因為我們在現實生活中需要通過已有的數據來發掘事物本身的內在規律,或者模擬出相應的數學模型來解決。所以這就需要我們用到這學期學習的相關知識來完成。這門課程也是連接數學與計算機之間的橋梁,之前學習的數學積分的知識現在也知道怎么用程序來實現了。還有就是對線性方程組和非線性方程組的求解方法的掌握。插值的應用自己還想說的就是。自己準備和同學一起做關于圖像處理的方面的東西,所以當時我就覺得這門課程作用不一般。學完了這門課程也希望自己活學活用,發揮這門課應有的作用。
方正
? 經過了這個學期對計算方法的學習,總體感覺還行,跟著老師的節奏,積極參加小組活動,課后仔細研究老師推薦的劍橋數值方法教材,基本上都能領悟,除了個別知識點可能比較抽象外,但是好多的算法我們都經過了上機實踐,所以掌握起來會更透徹一點。學習了這門課程后,我感覺實用性很大,因為在我們現實生活中我們經常需要通過已有數據來發掘事物本身的內在規律,或者模擬出相應的數學模型來解決,這就需要我們用到這學期學到的相關知識來完成了。這門課程也是連接數學與計算機之間的橋梁。其實學習這門課最大的收獲是老師讓我們懂得了團隊合作的意義,不僅培養我們的合作意識、團隊精神、理性思考、同時也提升我們的境界拓寬我們的胸懷,尺有所短寸有所長,要多發現和挖掘各自的優勢和長處,求知的過程要提倡個人資源互補、優勢共享才能少走彎路,攜手共贏。我很喜歡也很欣賞曾三友老師的這種富有創新意義的教學模式,讓我受益匪淺,得到了很大的提高。謝謝!
梅旭
在計算方法的課程學習中,曾老師的教學方法明顯和一般老師的不同,不僅僅是讓學生學習理論的知識,還將理論與實踐緊密的結合起來,以此提高學生的動手能力。星期二課堂上的討論更是讓學生對理論知識有了更深的理解,而星期四的匯報也讓每個人有機會學習其他人的程序和匯報形式。不過這門課程對英語水平有較高的要求,也許是英文教材寫得更好或者是有意讓學生了解數學術語的英文書寫、提高英語閱讀水平,我還是覺得用中文教材更方便學生學習。
王艷琴
課程設計是培養學生綜合運用所學知識,發現,提出,分析和解決實際問題,鍛煉實踐能力的重要環節,是對學生實際工作能力的具體訓練和考察過程.隨著科學技術發展的日新日異,程序軟件已經成為當今計算機應用中空前活躍的領域, 在生活領域中的應用可以說得是無處不在。因此作為二十一世紀的大學來說掌握簡單的軟件的開發技術是十分重要的。????? 回顧起此次數值分析的課程設計,至今我仍感慨頗多,的確,從選題到定稿,從理論到實踐,可以說得是苦多于甜,但是可以學到很多很多的的東西,同時不僅可以鞏固了以前所學過的知識,而且學到了很多在書本上所沒有學到過的知識。通過這次課程設計使我懂得了理論與實際相結合是很重要的,只有理論知識是遠遠不夠的,只有把所學的理論知識與實踐相結合起來,從理論中得出結論,才能真正為社會服務,從而提高自己的實際動手能力和獨立思考的能力。在設計的過程中遇到問題,可以說得是困難重重,難免會遇到過各種各樣的問題,同時在設計的過程中發現了自己的不足之處,對以前所學過的知識理解得不夠深刻,掌握得不夠牢固,通過這次課程設計之后,一定把以前所學過的知識重新溫故。? 我得到了很多同學的幫助。我想沒有他們我可能都要放棄了,因為我本人對數值分析的算法本來就不是很熟悉,學的東西也不能很好的靈活應用,理論聯系不了實際。
通過這段時間的學習,我認為要學好C++程序這門課程,不僅要認真閱讀課本知識,更重要的是要通過上機實踐才能增強和鞏固我的知識。特別是作為大學生,更要注重實踐這一環節,只有這樣我們才能成為合格的計算機人材。? 整個過程不斷的調試,在調用子程序的時候遇到了部分問題,最后幸好都解決了。通過這次課程設計也穩固了一些已經學習的數值分析的算法,同時了解了一些以前沒有接觸的數值分析的算法。總之,這次的課程設計受益匪淺。
張鐘文
通過對計算方法的學習,讓我明白了兩個道理。一、做一件事要做好充分的準備,那樣便可以事半功倍。在正式操作前,對理論知識的學習很重要,經過聽老師講課、課后自己看書,我對這門課的理論知識有了一定了解。二、學習中要勇于創新,不能墨守陳規。在編程時,我發現有時候一個題目在用常規方法完成后,我們可以通過一些改進,從而可以讓程序變得更加簡明易懂,這就需要我們的創新精神。
在上機實踐中,最具有挑戰性的是編程,它需要扎實的C語言功底和較強的邏輯思維能力及一定的編程技巧。正好讓我對已經學習過的C語言這門課程進行復習與鞏固,真是一舉兩得。
??? 經過這幾天學習的實踐,我已經對數值計算方法這門課程有了一定的了解,我相信有了這樣實用的數學工具,在今后的學習生活中一定會給我帶來狠多的幫助,我也會更加努力,爭取更大的進步!!!
??? 此外,在本次上機訓練的學習中體驗到了團隊的重要性,大家分工合作,會把事情簡單而又有效的完成。
陳俊樺
計算方法是信息科學與計算科學緊密相聯的一門課程,與計算機科學有著相輔相成的作用。一來計算方法的理論可以為計算機編程提供算法理論;另一方面,通過編程實現,也可以對計算方法的算法效率和實現效果進行衡量和比較。作為一名計算機專業的學生,僅僅知道計算方法的理論知識顯然還是不夠的,還要知道如何將算法編程實現。
? 不同于之前的計算方法課程,這次的課程老師更加注重了對動手編程能力的考查,而不是對理論知識的考核。對于我們專業的同學來說,這樣的考查形式更有意義,也更符合我們鍛煉和提高編程能力的要求。通過這樣一門實踐性較強的課程的學習,自己還是有所收獲的。
? 四次編程實踐真正的鍛煉了我思考問題和動手編程的能力。比如,在用LU分解法求解線性方程組的時候,會有三個矩陣需要存儲:系數矩陣,系數矩陣的下三角矩陣和系數矩陣的上三角矩陣。如果為每個矩陣都單獨開辟存儲空間,無疑將會占用太多的資源,所以可以用為系數矩陣開辟的空間來輪流存儲這三個矩陣,這是在課堂上我所學到的一個如何更好的解決問題的一個方法。自己動手編程的重要在于通過自己去編寫代碼,才會發現問題,然后想出解決問題的辦法,使自己的編程能力得到提高。
這次以小組形式進行編程實踐對我們團隊合作意識的培養液起到了很大的作用。一個人想到的問題和解決方法是有限的,這也是為什么團隊合作精神對于程序編寫人員來說如此重要的原因。在一個小組里面,和同學們一起針對給出的算法進行討論,各抒己見,彼此之間分享自己的想法,最終每個小組成員都能吸收到別人的好的方法,同時也可以讓自己的好的方法為他人所用。這樣的一個環境讓我受益匪淺,知道了如何更好地和他人交流,通過團隊合作來完成程序的設計。
? 總之,以動手實踐編程為考查方式的計算方法課程的學習,對于計算機專業的我們,還是有比較大的幫助的。在平時訓練量少的情況下,這門課程的編程實踐也成為了比較難得的鍛煉的機會。理論知識固然重要,但是更要將理論知識運用到實踐中,那樣才能學以致用,達到我們學習的更進一步的目標。
劉宇
我是信息工程學院的學生,是為了學習算法設計而選擇的這門課。
在這門課上,我們主要學會了泰勒公式在計算機數據在算法設計中的應用。我們進行了求函數值(二分法、Newton-Raphson、迭代法),線性方程求解(高斯消元法、LU算法),求積分(梯形法、
Mid-point rule、Simpson's rule、Guass quadrature),求解常微分方程(Euler method、backward Euler、Crank-Nicholson、Multistep methods)等方法的實驗。
利用泰勒公式進行計算方法的學習好處是用函數值替代導數,簡化程序設計的算法,縮短計算時間,此方法在工程領域的應用異常廣泛。
而這門課程鍛煉的不僅僅是我們的編程能力和數學能力,因為我們每次都要進行PPT的講解,我們還鍛煉了算法論文的寫作能力和講解能力。
通過這門課,我學到了很多東西,不枉費我選擇了這門課程。
?
?
六、小組分工
第一次實習:
| 成員 | 報告中的任務 | 成員 | 報告中的任務 |
| 韓學武 | 整理文檔 | ? | ? |
| 方正 | 比較程序優劣 | 彭亞妹 | 制作PPT |
| 肖大軍 | 講解PPT | 梅旭 | 修改程序 |
| 劉宇 | 對算法效率測試 | 陳俊樺 | 對算法效率測試 |
| 楊耀鵬 | 修改程序 | 張鐘文 | 修改程序 |
| 向勝男 | 整理文檔 | 王艷琴 | 制作PPT |
第二次實習
| 成員 | 報告中的任務 | 成員 | 報告中的任務 |
| 韓學武 | 修改程序 | ? | ? |
| 方正 | 修改程序 | 彭亞妹 | 修改程序 |
| 肖大軍 | 匯報 | 梅旭 | 制作PPT |
| 劉宇 | 修改程序 | 陳俊樺 | 修改程序 |
| 楊耀鵬 | 寫文檔 | 張鐘文 | 寫文檔 |
| 向勝男 | 制作PPT | 王艷琴 | 細化臺上匯報 |
?
第三次實習
| 成員 | 報告中的任務 | 成員 | 報告中的任務 |
| 韓學武 | 寫文檔 | ? | ? |
| 方正 | 了解關于課外的積分方法 | 彭亞妹 | 細化臺上細節 |
| 肖大軍 | 上臺展示 | 梅旭 | 了解關于課外的積分方法 |
| 劉宇 | 制作PPT | 陳俊樺 | 制作PPT |
| 楊耀鵬 | 修改程序 | 張鐘文 | 修改程序 |
| 向勝男 | 寫文檔 | 王艷琴 | 分析其他組的代碼特點 |
?
第四次實習
| 成員 | 報告中的任務 | 成員 | 報告中的任務 |
| 韓學武 | 修改程序 | ? | ? |
| 方正 | 寫word文檔 | 彭亞妹 | 寫word文檔 |
| 肖大軍 | 制作PPT | 梅旭 | 修改程序 |
| 劉宇 | 修改程序 | 陳俊樺 | 修改代碼 |
| 楊耀鵬 | 細化臺上工作 | 張鐘文 | 制作PPT |
| 向勝男 | 算法描述 | 王艷琴 | 程序測試 |
?
總報告
| 成員 | 報告中任務 | 頁數 | 成員 | 報告中任務 | 頁數 |
| 韓學武 | 撰寫主要內容、目錄、小組感想、總結、最后整理工作 | 1~2、4、46~47、51~54 | ? | ? | ? |
| 方正 | 撰寫前言 | 3 | 彭亞妹 | 撰寫計算方法概要 | 5~6 |
| 肖大軍 | 撰寫解方程部分 | 6~12 | 梅旭 | 撰寫解方程部分 | 6~12 |
| 劉宇 | 撰寫求解方程組部分 | 12~23 | 陳俊樺 | 撰寫求解方程組部分 | 12~23 |
| 楊耀鵬 | 撰寫求解積分部分 | 23~39 | 張鐘文 | 撰寫求解積分部分 | 23~39 |
| 向勝男 | 撰寫求解微分部分 | 39~46 | 王艷琴 | 撰寫求解微分部分 | 39~46 |
?
注:我們每次實習都會寫好報告和PPT所以最后報告各個實習內容的撰寫相對比較容易
七、總結
通過這次與眾不同的計算方法課程的學習,我們在此間都收獲了很多。從我們小組的角度將從以下幾點談論對這個學期計算方法學習做一個總結。
?1、首先從學習收獲的角度。從組內人們的交流過程中我們可以得到幾點。首先,大家對計算有了一個新的理解。以前大家學習高數的時候整天研究做題,但是對高數中的積分微分等方法的原理沒有一個基礎的理解。但是這次,我們組的成員能深刻的理解到計算的基本原理,這樣對知識的掌握有一個新的高度。其次,除了計算原理理解之外,大家在計算方法的學習和編程實現中也漸漸的明白了一個理論的公式計算(如同高數中復雜的公式,高難度的運算)如何轉化成程序去實現。在這個過程中,大家明白了計算機運行,或者說是設計一個算法的基礎是什么,簡單的說是借用計算機告訴可重復的運算來彌補其中其離散的缺點。這樣雖然不能帶到醉精確的數值但是可以得到一個你需要的數值。在這個過程中我們從教材上,從課堂上去體會是怎么把一個問題去離散化,如何去用迭代等方式去逼近一個問題等等。通過學習我們基本上認識到了怎么將一個現實的問題去用編程思想去考慮。這不僅僅體現在我們隊算法的理解上面,更是我們對編程的一次新的理解。
2、其次從授課方式角度。曾老師改變以前的授課和考核方式,以小組的方式經行考核,這樣對我們來說也是一個挑戰。但是從最終大家的結果來看收獲頗豐。第一、讓大家對教材的知識有了一個全新的認識。采用階段性的小組匯報,這樣讓大家有時間經行討論,在大家寫程序的時候對教材的知識有了一遍了解,在給大家講解的時候有了一個更深的了解,然后到最后的報告總結,當大家能用自己的話把課本上的很多東西寫出來的時候,或許大家不僅僅是看了教材上的內容,還會參考很多課外的資料,我想這個時候他們的理解會是非常深刻的。
第二、培養了大家的團隊合作能力,在這學期的計算方法的學習中,我們組從寫程序到最后的報告總結始終貫徹著團隊的精神,在寫程序初期,我們組織兩人一組,相互的補充相互的學習,使得周二的討論效率更高,在討論好大家之后,大家的分工明確在完成自己的工作得到同時主動幫助其他人完成任務。于此同時大家相互的交換工作相互的知道讓每個人有了很快的成長。大家在團隊中清楚了自己的角色,如何把一個比較大的工程分解到每個人身上,再怎么整合起來成為一個需要的產品。這不僅僅在這次的學習中很重要,也漸漸的明白了團隊的工作。第三、大家熱情高漲,收獲效率更上一層樓,像其他的組一樣,開始的時候我們組也是存在部分 同學基礎比較差編程能力相對來說比較弱,我們在按照老師的授課方式的基礎上,在小組內實行兩人一組等一系列的活動安排,調動大家的熱情,漸漸的大家開始積極的展示自己的代碼,對討論的后的安排工作大家開始搶著做,一度出現了預約下一次任務的場景。雖然大家做任務的水平參差不齊,但是還是本著大家自愿保留大家成果的原則經行每一次的小組匯報。這樣可能每次報告不是最好的,但是極大的調動了大家的積極性,這樣大家的收獲肯定是最高的。
轉載于:https://www.cnblogs.com/XDJjy/archive/2013/06/05/3119467.html
總結
- 上一篇: 公司旅游--金华武义二日游
- 下一篇: android开机优化-framewor